The more smartphones and tablets are sold the bigger the need for a mobile version of a modern website. PrimeFaces Mobile helps us developers here and allows us to quickly create mobile websites that display well on an iPhone, Android, Palm, Blackberry, Windows Mobile and others.
In the following tutorial we’re going to create a web application that is using Java Server Faces 2.1, PrimeFaces 3.1 and PrimeFaces Mobile 1.0 and runs on a simple web container like Tomcat or Jetty.
Prerequisites
If you want to build the following examples you’ll need at least the following development environment ..
JSF Web Project, Adding PrimeFaces
First we need a web application project ..
-
Create a new Maven project using the webapp archetype
Creating a new Maven Web Application Project -
Add the PrimeFaces and Java Maven repositories and dependencies for Java Server Faces, PrimeFaces and PrimeFaces Mobile to your pom.xml – my final project descriptor looks like this
<?xml version="1.0"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hascode.tutorial</groupId> <artifactId>primefaces-mobile-tutorial</artifactId> <packaging>war</packaging> <version>0.0.1</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jsf.version>2.1.6</jsf.version> </properties> <repositories> <repository> <id>prime-repo</id> <name>PrimeFaces Maven Repository</name> <url>http://repository.primefaces.org</url> <layout>default</layout> </repository> <repository> <id>maven2-repository.dev.java.net</id> <name>Java.net Repository for Maven</name> <url>http://download.java.net/maven/2</url> </repository> </repositories> <build> <finalName>primefaces-mobile-tutorial</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> <configuration> <source>1.6</source> <target>1.6</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.primefaces</groupId> <artifactId>primefaces</artifactId> <version>3.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-api</artifactId> <version>${jsf.version}</version> </dependency> <dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-impl</artifactId> <version>${jsf.version}</version> </dependency> <dependency> <groupId>org.primefaces</groupId> <artifactId>mobile</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
-
Since we’re going to run our web application in a simple servlet container and not a Java EE application server we need to add the JSF dispatcher to our web context. Add the following web.xml in src/main/webapp/WEB-INF
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>hasCode.com PrimeFaces Mobile Tutorial</display-name> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <context-param> <param-name>com.sun.faces.allowTextChildren</param-name> <param-value>true</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> </servlet> <servlet> <servlet-name>Resource Servlet</servlet-name> <servlet-class>org.primefaces.resource.ResourceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Resource Servlet</servlet-name> <url-pattern>/primefaces_resource/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>/demo.xhtml</welcome-file> </welcome-file-list> </web-app>
-
Finally switch to the mobile theme application wide by adding the following faces-config.xml in src/main/webapp/WEB-INF
<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd"> <name>hascode-demo</name> <application> <default-render-kit-id>PRIMEFACES_MOBILE</default-render-kit-id> </application> </faces-config>
-
If you want to temporarily enable the mobile version you are free to use the request parameter javax.faces.RenderKitId=PRIMEFACES_MOBILE or write a custom view handler by overriding the calculateRenderKitId API – I haven’t tried this one yet
A simple multi view page
Our first web site is a simple page that contains multiple views ..
-
Create a new file named demo.xhtml in src/main/webapp
<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui" xmlns:pm="http://primefaces.org/mobile" contentType="text/html"> <pm:page title="hasCode.com PrimeFaces Mobile Tutorial - Simple Navigation"> <pm:view id="viewChapter1"> <pm:header title="First Chapter"/> <pm:content> <h:form> <p:commandButton value="Go to second chapter" action="pm:viewChapter2"/> </h:form> This is the first chapter </pm:content> </pm:view> <pm:view id="viewChapter2"> <pm:header title="Second Chapter"/> <pm:content> <h:form> <p:commandButton value="Go to first chapter" action="pm:viewChapter1"/> </h:form> This is the second chapter </pm:content> </pm:view> </pm:page> </f:view>
-
The command buttons hold references to the views and allow you to switch between the views
-
Now it’s time to run the sample, simply run the following command in your IDE our console:
mvn tomcat:run
-
That is what the sample app looks like on my HTC Desire Android smartphone / webkit browser
Figure 1. A simple multiview page on a Android smartphone
Using AJAX
In the following example, we’re going to add some AJAX to our mobile app. A managed bean is queried for the current time when the button is clicked …
-
Create a new file in src/main/webapp named ajax.xhtml
<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui" xmlns:pm="http://primefaces.org/mobile" contentType="text/html"> <pm:page title="hasCode.com PrimeFaces Mobile Tutorial - AJAX"> <pm:view id="main"> <pm:header title="AJAX Sample"/> <pm:content> <h:form> <p:commandButton value="Click" update="result"/> <h:outputText id="result" value="#{demoBean.output}"/> </h:form> </pm:content> </pm:view> </pm:page> </f:view>
-
Add a directory src/main/java if it does not exist yet and add the managed bean DemoBean
package com.hascode.tutorial; import java.util.Date; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; @ManagedBean @RequestScoped public class DemoBean { public String getOutput() { return "It is " + new Date().toString(); } }
-
Run the example, but this time use mvn tomcat:run-war – the result looks like this
Figure 2. Using AJAX and a ManagedBean
Mobile Components
PrimeFaces Mobile not only optimizes some of the existing UI components but also adds some sexy new ones .. the following page shows some of them ..
-
Create a new file named components.xhtml in src/main/webapp
<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui" xmlns:pm="http://primefaces.org/mobile" contentType="text/html"> <pm:page title="hasCode.com PrimeFaces Mobile Tutorial - Mobile Components"> <pm:view id="components"> <pm:header title="Mobile Components"/> <pm:content> <h:form> <h:outputText value="Button Group"/> <pm:buttonGroup> <p:commandButton value="Accept"/> <p:commandButton value="Deny"/> </pm:buttonGroup> <p:separator/> <h:outputText value="Input Range"/> <pm:inputRange value="23"/> <p:separator/> <h:outputText value="Nav Bar"/> <pm:content> <pm:navBar> <p:button value="Home" icon="home" href="#components" styleClass="ui-btn-active"/> <p:button value="Settings" icon="gear" href="#components"/> <p:button value="About" icon="info" href="#components"/> </pm:navBar> </pm:content> <p:separator/> <h:outputText value="Switch"/> <pm:switch value="#{true}" onLabel="Accept" offLabel="deny"/> </h:form> </pm:content> </pm:view> </pm:page> </f:view>
-
Run mvn tomcat:run and enjoy the result – mine looks like this one
Figure 3. PrimeFaces Mobile Components in Action
Using a Header-Footer-Layout
PrimeFaces Mobile gives us special components to declare header and footer regions for our mobile pages.
A header supports facets to define the left and right section of the header region.
-
I have defined such a layout in a file named segments.xhtml
<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui" xmlns:pm="http://primefaces.org/mobile" contentType="text/html"> <pm:page title="hasCode.com PrimeFaces Mobile Tutorial - Mobile Components"> <pm:view id="segments"> <pm:header title="The header"> <f:facet name="left"> <p:button value="Back" icon="back" href="#segments"/> </f:facet> <f:facet name="right"> <p:button value="Config" icon="gear" href="#config"/> </f:facet> </pm:header> <pm:content> <h:outputText value="This is our content.."/> <p:calendar mode="inline"/> </pm:content> <pm:footer> <pm:buttonGroup orientation="horizontal"> <p:button value="Like" href="#segments"/> <p:button value="Share" href="#segments"/> </pm:buttonGroup> </pm:footer> </pm:view> </pm:page> </f:view>
-
The layout looks like this on my mobile device
Figure 4. PrimeFaces Mobile Header-Footer Layout
Tutorial Sources
I have put the source from this tutorial on my GitHub repository – download it there or check it out using Git:
git clone https://github.com/hascode/primefaces-mobile-tutorial.git
Troubleshooting
-
javax.el.PropertyNotFoundException: if you are testing your app with the tomcat maven plugin – try running mvn tomcat:run-war instead of mvn tomcat:run