Using PrimeFaces (Sep 2014)#

I started with RichFaces, and failed to cope with it, so I switched to PrimeFaces. Additionally PrimeFaces has an excellent documentation available as PDF download and also great showcases.

1. Do NOT include prototype.js in the head
2. Do NOT include any version of jQuery in the head, PrimeFaces will inject it's own one

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:p="http://primefaces.org/ui"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core">
	
<h:head>
	<h:outputScript name="overlib.js" library="javascripts" />
	<h:outputScript name="func.js" library="javascripts" />

	<!-- Due to PrimeFaces do not include ANY jQuery libs, it will be injected automatically from the lib -->
	<h:outputStylesheet name="style.css" library="stylesheets" />
</h:head>
<h:body id="body">
    ...
</h:body>
</html>

Remark 1: Sometimes people use the "xmlns.jcp.org" domain for the jsf namespaces (html,facelets,core), but this doesn't matter from my experience.
Alternate namespaces:

 ...
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:h="http://xmlns.jcp.org/jsf/facelets"
    xmlns:h="http://xmlns.jcp.org/jsf/core"

Remark 2: Some sites state that you have to use <h:head> instead of head to enable injection. In my tests it worked also with pure <head>.

Intergrating JSF into Struts/JSP (Sep,2014)#

Struts and JSF have diffenrent lifecycles, so you need to handle them separately.
This can be done within the web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>Homepage</display-name>

	<!-- JSF settings -->
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>/faces/*</url-pattern>
	</servlet-mapping>

	<context-param>
		<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
		<param-value>server</param-value>
	</context-param>

	<!-- PrimeFaces config -->
	<context-param>
		<param-name>javax.faces.CONFIG_FILES</param-name>
		<param-value>/WEB-INF/faces-config.xml</param-value>
	</context-param>

	<context-param>
		<param-name>primefaces.THEME</param-name>
		<param-value>aristo</param-value>
	</context-param>

	<!-- struts settings -->
	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<filter>
		<filter-name>sitemesh</filter-name>
		<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>sitemesh</filter-name>
		<url-pattern>/*</url-pattern>
		<dispatcher>FORWARD</dispatcher>
	</filter-mapping>


	<!-- default file settings -->
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>

</web-app>

DataTable and sorting#

<p:dataTable id="dataTab" value="#{vineController.vineList}" var="list">
    <p:column headerText="Name" sortBy="#{list.name}">
	<h:outputText value="#{list.name}" />
    </p:column>
</p:dataTable>

If you have a getter method for the list, this list MUST not be assembled in that getter, because PrimeFaces acts on that list. So if you have business logic in the getter the sorting takes not place. That means that the getter must only return the list, nothing else.

So you need to fill the list somewhere else. One option is to do it in a @PostConstruct, but this is executed only, if the bean is created (once).

This would mean to get the list and copy it to the local variable. You need to copy it to release it from the unmodifiable context of the bean result and to enable PrimeFaces to get hold of the order.

@PostConstruct
public void init() {
    vineListDatabase = vineEJB.getAll();
    vineList.clear();
    for (Vine vine: vineListDatabase) {
    	vineList.add(vine);
    	log.info("getVineList:" + vine);
    }			
}

Note 1: Parameters STATE_SAVING_METHOD and PARTIAL_STATE_SAVING in web.xml DO NOT influence sorting (whatever value you take):

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>server</param-value>
</context-param> 
<context-param>
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
    <param-value>false</param-value>
</context-param>

Note 2: The sortBy attribute with entity field only is deprecated since version 5.
I should look like above ( sortBy="#{list.name}" ) !

Primefaces with Tomee (JSF + JPA) as of June 2015#

same as above:

  • do not include prototype.js, ajax won't work due to
Console:
TypeError: $(...) is null in jquery-plugins.js.jsf:333:8981
  • do not include your own jquery.js, primefaces-5.2.jar includes following js libs:
    • /javax.faces.resource/jquery/jquery.js.jsf?ln=primefaces&v=5.2: jQuery v1.11.0, 2014-01-23T21:02Z
    • /javax.faces.resource/jquery/jquery-plugins.js.jsf?ln=primefaces&v=5.2: jQuery UI - v1.11.0 - 2014-07-22
    • primefaces.js

DataTable and Sorting#

If you instantiate the list outside of the controller, primefaces cannot change it and you get following errors
private List<Profile> profileList; //  = new ArrayList<Profile>()
public List<Profile> getProfileList() {
    profileList = profileEJB.getAll();
    return profileList; 
}
> java.lang.UnsupportedOperationException: Result lists are read-only.
> java.lang.IllegalStateException: CDATA tags may not nest
So you can make a copy of it. Then you get no error, but nothing happens.
public List<Profile> getProfileList() {
    profileList = new ArrayList<Profile>(profileEJB.getAll());
    return profileList; 
}
This is because you recreate the list each time you get it and do not give primefaces the change to work on it (sort it). So retrieve it initially only:
public List<Profile> getProfileList() {
	if (profileList == null)
		profileList = new ArrayList<Profile>(profileEJB.getAll());
	return profileList;
}

Styles #

You can anylse the css settings with Firebug etc., create you own one and add you css file this way:
<h:body>
    <f:facet name="last">
        <h:outputStylesheet library="default" name="css/your-custom.css" />
    </f:facet>
...

Themes#

Download at http://primefaces.org/themes

To apply a theme from the Theme Gallery, download the theme jar, add it your classpath and configure PrimeFaces to use it.

Set it manually in web.xml

<context-param>  
    <param-name>primefaces.THEME</param-name>  
    <param-value>bootstrap</param-value>  
</context-param>