Comparison of AJAX JSF Libraries Functionality and Interoperability

103
MASARYK UNIVERSITY FACULTY OF I NFORMATICS Comparison of AJAX JSF Libraries Functionality and Interoperability DIPLOMA THESIS Bc. Pavol Pito ˇ nák Brno, June 2011

Transcript of Comparison of AJAX JSF Libraries Functionality and Interoperability

Page 1: Comparison of AJAX JSF Libraries Functionality and Interoperability

MASARYK UNIVERSITY

FACULTY OF INFORMATICS

}w���������� ������������� !"#$%&'()+,-./012345<yA|Comparison of AJAX JSF LibrariesFunctionality and Interoperability

DIPLOMA THESIS

Bc. Pavol Pitonák

Brno, June 2011

Page 2: Comparison of AJAX JSF Libraries Functionality and Interoperability

Declaration

Hereby I declare, that this paper is my original authorial work, which I have worked out bymy own. All sources, references and literature used or excerpted during elaboration of thiswork are properly cited and listed in complete reference to the due source.

Bc. Pavol Pitonák

Advisor: Mgr. Marek Grác

ii

Page 3: Comparison of AJAX JSF Libraries Functionality and Interoperability

Acknowledgement

I would like to thank my supervisor, Mgr. Marek Grác, my consultant, Ing. Jirí Pechanec,and RichFaces team, especially Lukáš Fryc, for their guidance and support throughout mywork on this thesis.

Many thanks also go to my family, girlfriend, and close friends who supported me whileworking on this thesis.

iii

Page 4: Comparison of AJAX JSF Libraries Functionality and Interoperability

Abstract

This thesis compares functionality of four popular JavaServer Faces component libraries—RichFaces, ICEfaces, OpenFaces, and PrimeFaces. This thesis demonstrates differences be-tween them, highlights their unique features, and research their interoperability. A demoapplication that would demonstrate interoperability of these libraries is created as a part ofthe thesis.

iv

Page 5: Comparison of AJAX JSF Libraries Functionality and Interoperability

Keywords

Java Server Faces, JSF, RichFaces, ICEfaces, PrimeFaces, interoperability, web framework,Rich Internet Applications

v

Page 6: Comparison of AJAX JSF Libraries Functionality and Interoperability

Contents

1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 The JavaServer Faces Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.1 History of JavaServer Faces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.2 Key Terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.3 JSF Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.4 The Request Processing Lifecycle . . . . . . . . . . . . . . . . . . . . . . . . . . 82.5 The Navigation Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.6 Managed Beans and Scopes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.7 The Facelets View Declaration Language . . . . . . . . . . . . . . . . . . . . . 122.8 Composite Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.9 Resource Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.10 Component Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3 Ajax and Core Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183.1 Ajax in JSF 2 and in Component Libraries . . . . . . . . . . . . . . . . . . . . . 183.2 Region . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203.3 Command Button and Command Link . . . . . . . . . . . . . . . . . . . . . . . 213.4 JavaScript Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213.5 Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.6 Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233.7 Poll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.8 Push . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

4 Input Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294.1 Calendar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294.2 Inplace Inputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314.3 Autocomplete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314.4 Slider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344.5 Spinner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354.6 File Upload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

5 Output Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405.1 Progress Bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405.2 Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

6 Panels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466.1 Panels in RichFaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466.2 Panels in PrimeFaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486.3 Panels in OpenFaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516.4 Panels in ICEfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

7 Iteration Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567.1 RichFaces Repeat, List and Data Grid . . . . . . . . . . . . . . . . . . . . . . . . 577.2 RichFaces Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

vi

Page 7: Comparison of AJAX JSF Libraries Functionality and Interoperability

7.3 RichFaces Extended Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . 607.4 RichFaces Data Scroller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 617.5 OpenFaces ForEach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637.6 OpenFaces Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637.7 PrimeFaces Data Grid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697.8 PrimeFaces Data List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707.9 PrimeFaces Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717.10 ICEfaces Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

8 Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758.1 Charts in PrimeFaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758.2 Charts in OpenFaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 778.3 Charts in ICEfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

9 Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 829.1 Faces Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 829.2 Bean Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 829.3 Client Side Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839.4 Cross-field Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849.5 Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 859.6 Captcha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

10 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91A Sample Use of RichFaces Sub Table . . . . . . . . . . . . . . . . . . . . . . . . . . . 93B Sample Use of Sorting in RichFaces Table . . . . . . . . . . . . . . . . . . . . . . . 94C Metamer Screenshot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95D Contents of Attached CD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

vii

Page 8: Comparison of AJAX JSF Libraries Functionality and Interoperability

1 Introduction

Rich Internet Applications (RIA) became extremely popular in last couple of years. A RichInternet Application is a web application that has many of the characteristics of a desktopapplication, typically delivered either by way of a site-specific browser, via a browser plu-gin, independent sandboxes, or virtual machines.[1] The three most common platforms areAdobe Flash, Microsoft Silverlight and Java. Although all these platforms are mature, stableand widespread, their biggest disadvantage is that they all depend on plugins installed inuser’s web browser.

On the other hand, new web standards such as HTML 5 are being developed in order to pro-vide advanced features need by RIAs out-of-the-box. HTML 5 will contain new elements forhandling multimedia (video and audio), a canvas element and improved integration of SVGcontent. Next, there are planned new semantic elements for page header, articles and sec-tions. Several new APIs are about to be introduced for offline storage database (also knownas Web Storage), drag-and-drop, geolocation, indexed database, an API for handling fileuploads and file manipulation, and many more. Although latest versions of most popu-lar browsers, namely Google Chrome, Mozilla Firefox, Apple Safari and Microsoft InternetExplorer support many HTML 5 features, it is expected to become a standard in 2014.[2]Therefore, most of modern web frameworks uses a mixture of HTML 4 and some propri-etary technologies such as Adobe Flash or Microsoft Silverlight.

In the Java world, there are several web frameworks and standards for creating rich internetapplications. In March 1998, the Java Servlet API was introduced. Prior to servlets, Java wasnot widely used as a server-side technology for web applications. Unlike other proprietaryweb server APIs, the Java Servlet API provided an object-oriented design approach and wasable to run on any platform where Java was supported. Since the Java Servlet API provideda low-level handling of HTTP requests, it was tedious and error-prone to generate HTML,e.g.:

1 out.println("<img id=\"cat\" src=\"cat.png\"/>");

Notice how the quote symbols (”) have to be escaped.

Because of above-mentioned problems of the Java Servlet API, a new technology calledJavaServer Pages (JSP) was introduced. JSP was built on top of servlets and provided a sim-pler solution to generating large amounts of dynamic HTML. JSP were using a mix of twobasic content forms, scriptlets and markup. Markup is typically HTML with some specialJSP tags, while scriptlets are blocks of Java code. When a page is requested, it is translatedinto servlet code that is then compiled and immediately executed. Subsequent requests tothe same page simply invoke generated servlet for the page. Simple page might look likethis:

1 <%@ page errorPage="myerror.jsp" %>

1

Page 9: Comparison of AJAX JSF Libraries Functionality and Interoperability

1. INTRODUCTION

2 <%@ page import="com.foo.bar" %>3 <html>4 <body>5 <%! int serverInstanceVariable = 1;%>6 <% int localStackBasedVariable = 1; %>7 <table>8 <tr>9 <td>

10 <%= toStringOrBlank( "expanded inline data " + 1 ) %>11 </td>12 </tr>13 </table>14 ...

The Java Platform, Enterprise Edition (J2EE, later renamed to JEE) contained both ServletAPI and JavaServer Pages right from the first version.

Although JSP was an improvement, it was not a complete solution. Developers used to usea lot of Java code in JSPs making them hard to maintain. Thus, some separation of applica-tion logic and view was needed. What was needed was an implementation of model-view-controller design pattern. The model-view-controller (MVC) was first described in 1979 byTrygve Reenskaug.[3] The MVC pattern separates the modeling of the domain, the presen-tation, and the actions based on user input into three separate classes: [4]

• model—manages the behavior and data of the application domain, responds to re-quests for information about its state (usually from the view), and responds to instruc-tions to change state (usually from the controller);

• view—manages the display of information; and

• controller—interprets the mouse and keyboard inputs from the user, informing themodel and/or the view to change as appropriate.

Because of above mentioned issues with JSP and the need of MVC, several web frame-works were created. They could be divided into two major groups by a paradigm they use–request based (e.g. Struts or Stripes) and component based (e.g. Wicket, Tapestry, GoogleWeb Toolkit and JavaServer Faces). A request based framework basically gets user’s request,then determines what the application should do and gives the response back to the user. Onthe other hand, in a component based framework there is no clear sense of the flow fromfront to back. The developer has to think not in actions but in components. JavaServer Faces(JSF) is based on components but is somehow similar to request based frameworks.

Struts became one of the most dominant Java web frameworks and was donated to theApache Foundation in May 2000. Formerly located under the Apache Jakarta Project andknown as Jakarta Struts, it became a top level Apache project in 2005. According to EdwardBurns, [5] the Java Community Process (JCP) saw the benefits that Struts offered by explicitlyfollowing the MVC approach. However, Struts lacked a robust way to handle the view tier.

2

Page 10: Comparison of AJAX JSF Libraries Functionality and Interoperability

1. INTRODUCTION

To address this need, several leading software vendors, including Sun, Oracle, IBM, andBEA, met through the JCP in 2001 and voted to proceed with a comprehensive and detailedspecification for building Java web applications.

JavaServer Faces became part of the Java EE in version 5 (May 2006). Since it contained onlyfew basic components, soon several component libraries with advanced features were cre-ated. These libraries brought Ajax1 support and various visual components such as calendar,spinner, slider or advanced tables. Despite the fact that they all were built on top of a stan-dard, they did not work together well, if at all. JEE 6 (December 2009) introduced JSF 2.0which added many missing features. Since many developers wanted to use componentsfrom several JSF libraries, JSF 2.0 were designed with interoperability in mind. However,the JSF specification does not prescribe implementation details. The main goal of this thesisis to compare functionality of three JSF open source component libraries (ICEfaces, Prime-Faces, and OpenFaces) with RichFaces and find out how they inter-operate. Author of thisthesis works at Red Hat in RichFaces team. This work will help RichFaces team to under-stand strengths and weaknesses of RichFaces components.

The work is divided into several chapters. The second chapter describes the history ofJavaServer Faces and new features of JSF 2. There are also above-mentioned componentlibraries introduced. The following chapters describe functionality and interoperability ofvarious groups of components—Ajax, input, output, panels, charts and other components.The last chapter describes validation of forms on the pages. It describes three different mech-anisms for validation.

1. AJAX is an acronym for Asynchronous JavaScript and XML. In this work it will be referred to as “Ajax”because this name is usual in JSF community.

3

Page 11: Comparison of AJAX JSF Libraries Functionality and Interoperability

2 The JavaServer Faces Framework

2.1 History of JavaServer Faces

JavaServer Faces is a standard component-oriented user interface (UI) framework for theJava EE platform. JSF offers an ecosystem of portable UI component libraries and exten-sions. JSF was created through the Java Community Process (JCP) by a group of technologyleaders.

The first version of JSF (1.0) was introduced in the first half of March 2004 as Java Specifi-cation Request (JSR) 1271 along with J2EE 1.4. After that, a revised version (1.1) was releasein late May 2004. JSF 1.1 was only a bug-fixing release, it did not contain any specificationchanges nor HTML renderkit changes. The specification was led by Edward Burns (Oracle)and Craig R. McClanahan (Sun Microsystems). The objective of the specification was to es-tablish a standard API for creating Java web application GUIs which would eliminate theburden of creating and maintaining GUI infrastructure for developers. The specification didnot have any dependency on specific operating system nor CPUs. The API was created withinternationalization and localization in mind.

Two years later, JSF 1.2 was introduced as JSR-2522. The specification was released in May2006 and after that, three reviewed versions were released (last in July 2008), all targeted theJ2EE 5.0 Platform. The specification was led by Edward Burns and Roger Kitain (both fromOracle). JSF 1.2 was not a JSR for new features. According to specification page, the primarygoal of the JSR was handling the Faces side of the JSP/Faces alignment issues addressedin the parallel JSR-245 (JavaServer Pages 2.1). The specification contained also several sec-ondary goals:

• enhancements to provide an interim solution to the content-interweaving problem de-scribed in article Improving JSF by Dumping JSP 3;

• provide XML Schema for the config files, instead of using DTD;

• enhancements to allow faces applications to handle multi-frame, or multi-window UIdesigns;

• enhancements to the f tag library for improved TCK coverage, <f:view> lifetimeevents, and other small features; enhancements to the decorator support for API ob-jects;

• security enhancements for client side state saving;

1. JSR-127, http://jcp.org/en/jsr/detail?id=1272. JSR-252, http://jcp.org/en/jsr/detail?id=2523. Improving JSF by Dumping JSP, http://www.onjava.com/pub/a/onjava/2004/06/09/jsf.html

4

Page 12: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

• solve the "duplicate button press" problem;

• re-organize the spec into normative, and non-normative sections, to make implemen-tation easier;

• portlet related bug-fixes; and

• bug fixes that require minimal spec changes.

In July 2009 JavaServer Faces 2.0 specification was released.4 The specification was led,as JSF 1.2, by Edward Burns and Roger Kitain. Similarly to previous specifications, expertgroup consisted of several individuals and companies, such as Oracle, Sun Microsystems,Red Hat, Exadel, IBM, Apache Software Foundation and many other. Unlike JSF 1.2, 2.0 wasa feature specification targeting the Java EE 6 Platform. According to specification page,the JSR was about to bring the best ideas in web application development to the Java EEplatform. Specification should maximize the productivity of web application developmentand minimize the complexity of maintenance of the web application during its productionlifetime. Another goal of the specification was to bring an easy to use API for Ajax. The tech-nical details will be explained in following sections. This work will focus mainly on JSF 2.0and upcoming versions.

JSF applications need a JSF implementation to run. There are two major implementationsof JSF: a reference implementation (also known as Mojarra) and Apache’s implementationcalled MyFaces. All JEE 6 compliant application servers contain a JSF implementation, e.g.GlassFish V3 contains Mojarra and JBoss AS 6 contains both Mojarra and MyFaces.

2.2 Key Terms

This section contains a list of key terms used in JSF as explained by Kito Mann in his bookJavaServer Faces in Action [6, p. 39-40].

UI component is a stateful object, maintained on the server, that provides specific functional-ity for interacting with an end user. UI components are JavaBeans with properties, methods,and events. They are organized into a view, which is a tree of components usually displayedas a page.

Renderer is responsible for displaying a UI component and translating a user’s input into thecomponent’s value. Renderers can be designed to work with one or more UI components,and a UI component can be associated with many different renderers.

Validator is responsible for ensuring that the value entered by a user is acceptable. One ormore validators can be associated with a single UI component.

4. JSR-314, http://jcp.org/en/jsr/detail?id=314

5

Page 13: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

Backing beans (managed beans) are specialized JavaBeans that collect values from UI com-ponents and implement event listener methods. They can also hold references to UI compo-nents.

Converter converts a component’s value to and from a string for display. A UI componentcan be associated with a single converter.

JSF uses the JavaBeans event/listener model (also used by Swing). UI components (andother objects) generate events, and listeners can be registered to handle those events.

Message is some information that is displayed back to the user. Just about any part of theapplication (backing beans, validators, converters, and so on) can generate information orerror messages that can be displayed back to the user.

Navigation is the ability to move from one page to the next. JSF has a powerful navigationsystem that is integrated with specialized event listeners.

2.3 JSF Application

A JavaServer Faces application is like any other Java web application. A typical JSF applica-tion includes the following parts: [7, section 4]

• a set of web pages in which components are laid out;

• a set of tags to add components to the web page;

• a set of backing beans, which are JavaBeans5 component that define properties andfunctions for components on a page;

• a web deployment descriptor (web.xml file);

• optionally, one or more application configuration files, such as a faces–config.xml file,which can be used to define page navigation rules and configure beans and other cus-tom objects, such as custom components;

• optionally, a set of custom objects, which can include custom components, validators,converters, or listeners, created by the application developer; and

• a set of custom tags for representing custom objects on the page.

A simple web.xml descriptor might look like in the following code snippet where two URLpatterns are mapped to Faces servlet. When running JSF 2.0 on a Servlet 3.0 container, theweb.xml is optional. If no web.xml is found, the Faces Controller servlet is automaticallymapped to the most popular URL patterns: /faces/*, *.jsf, and *.faces.[5, p. 9]

5. JavaBeans, http://download.oracle.com/javase/tutorial/javabeans/index.html

6

Page 14: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

1 <?xml version="1.0" encoding="UTF-8"?>2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/

xml/ns/javaee/web-app_2_5.xsd">5 <display-name>Foo Application</display-name>6 <context-param>7 <param-name>javax.faces.DEFAULT_SUFFIX</param-name>8 <param-value>.xhtml</param-value>9 </context-param>

10 <servlet>11 <servlet-name>Faces Servlet</servlet-name>12 <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>13 <load-on-startup>1</load-on-startup>14 </servlet>15 <servlet-mapping>16 <servlet-name>Faces Servlet</servlet-name>17 <url-pattern>/faces/*</url-pattern>18 </servlet-mapping>19 <servlet-mapping>20 <servlet-name>Faces Servlet</servlet-name>21 <url-pattern>*.jsf</url-pattern>22 </servlet-mapping>23 <welcome-file-list>24 <welcome-file>faces/index.xhtml</welcome-file>25 </welcome-file-list>26 </web-app>

Example of faces-config.xml:1 <?xml version="1.0" encoding="UTF-8"?>2 <faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"3 xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org

/2001/XMLSchema-instance"4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/

xml/ns/javaee/web-facesconfig_2_0.xsd">5 <application>6 <locale-config>7 <default-locale>en</default-locale>8 <supported-locale>en</supported-locale>9 </locale-config>

10 <message-bundle>com.pitonak.foo.messages</message-bundle>11 </application>12 </faces-config>F

Both web.xml and faces-config.xml are located in WEB-INF directory. Once a JSF applicationis properly configured, XHTML pages can be constructed (notice the mixture of HTML andJSF tags). Here is example index.xhtml:

1 <html xmlns="http://www.w3.org/1999/xhtml"2 xmlns:h="http://java.sun.com/jsf/html">3 <h:head/>4 <h:body>

7

Page 15: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

5 <h:form>6 name: <h:inputText value="#{fooBean.name}"/> <br/>7 Hello <h:outputText value="#{fooBean.name}"/>! <br/>8 <h:commandButton value="Greet"/>9 </h:form>

10 </h:body>11 </h:head>

A very minimalist managed bean might look as follows:

1 package com.pitonak.foo;2 import javax.faces.bean.ManagedBean;3 import javax.faces.bean.SessionScoped;4

5 @ManagedBean6 @SessionScoped7 public class FooBean {8 private String name;9

10 public String getName() {11 return name;12 }13

14 public void setName(String name) {15 this.name = name;16 }17 }

2.4 The Request Processing Lifecycle

In the example presented in last section, a managed bean FooBean is named fooBean. Itsgetter and setter methods are called using the Unified Expression Language. [7, section 6].JSF creates and manages a server-side component tree in memory that directly correspondsto the components included in a page. [5, p. 10]

Figure 2.1: JSF component tree

8

Page 16: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

Common tasks, such as handling incoming requests, decoding parameters, modifying andsaving state, and rendering web pages to the browser are all performed during a web ap-plication lifecycle. By default, JavaServer Faces automatically handles most of the lifecycleactions for a developer. However, it also exposes the various stages of the request lifecycle,so that developer can modify or perform different actions if his application requirementswarrant it. [7, section 4]

The lifecycle of a JavaServer Faces application starts and ends with the following activity:the client makes a request for the web page, and the server responds with the page. Thewhole request processing lifecycle is more complicated. JavaServer Faces goes through sev-eral phases when it processes a single incoming request: [6, p. 59]

• Restore View—finds or creates a tree of components for the selected view; some com-ponents, like HtmlCommandButton, will generate action events (or other types ofevents) in this phase;

• Apply Request Values—updates the value of the components to equal ones sent in therequest, optionally using converters; adds conversion errors if there is an error andalso generates events from request parameters;

• Process Validations—asks each component to validate itself (which may include usingexternal validators); validation error messages may be reported;

• Update Model Values—updates all the values of backing beans or model objects asso-ciated with components; conversion error messages may be reported;

• Invoke Application—calls any registered action listeners; the default action listenerwill also execute action methods referenced by command components and choose thenext view to be displayed; and

• Render Response—displays the selected view using the current display technology(like JSP).

For the initial request, only the view is built which means that only phases Restore View,Invoke Application and Render Response are invoked. For subsequent (postback) requests,some or all other phases are invoked. In chapter 3 some advanced techniques for limitingthe request processing lifecycle will be explained.

When the application from previous section is built and deployed to an application server,the application is in an uninitiated state. When a client makes an initial request for in-dex.xhtml web page, the Facelets application is compiled (see section The Facelets ViewDeclaration Language). The compiled Facelets application is executed and a new compo-nent tree is constructed for the application and is placed in a FacesContext. The compo-nent tree is populated with the component and the backing bean property associated with it.Then a new view is built and rendered to the requesting client as a response. The componenttree is destroyed automatically. On subsequent requests, the component tree is rebuilt and

9

Page 17: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

Figure 2.2: Initial request vs. usual postback request

the saved state is applied to it.

2.5 The Navigation Model

Navigation happens in a web application when a user tries to switch from one page toanother page. There are several ways how to navigate on the web application:

1. submitting a form and invoking an action method;

2. clicking a hyperlink; or

3. directly entering the target URL of a page into a browser.

Whatever be the case, the next page to be displayed or the response for the current pagehas to be handled by the web application. The navigation outcome is result of an actionmethod.

In JSF 1.x all navigation cases had to be configured in faces-config.xml. For example, whennavigating from page1 to page2 in response to a “success” outcome on a command compo-

10

Page 18: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

nent in page1 required the following XML boilerplate code: [8]1 <navigation-rule>2 <from-view-id>/page1.xhtml</from-view-id>3 <navigation-case>4 <from-outcome>success</from-outcome>5 <to-view-id>/page2.xhtml</to-view-id>6 </navigation-case>7 </navigation-rule>

The URL of the resulting page will be concatenation of context root, context path, Facesservlet mapping, and view ID, e.g. for the sample above the URL of the page might behttp://localhost:8080/myapp/faces/page2.xhtml.

JSF 2.0 introduced a simplification called implicit navigation that reduces the size of faces-config.xml. If no matching navigation case is found, the navigation handler checks to seewhether the outcome of action corresponds to a view ID. It is possible to use absolute pathto the page (/page2.xhtml), relative path to the page (page2.xhtml) or even the ID of theview (page2). The sample action method called from page1 resulting in navigation to page2might look like this:

1 public String fooAction() {2 // some business logic3 return "page2";4 }

Another enhancement to the navigation subsystem is conditional navigation. It is possibleto use expression language in pre-conditions that must be met in order for the navigationcase to be accepted:

1 <navigation-rule>2 <from-view-id>/page1.xhtml</from-view-id>3 <navigation-case>4 <from-outcome>success</from-outcome>5 <to-view-id>/page2.xhtml</to-view-id>6 <if>#{bean.fooCondition}</if>7 </navigation-case>8 </navigation-rule>

One of drawbacks of JSF navigation is that it uses strings for outcomes. Apache MyFaces Ex-tensions project (CODI), inspired by Tapestry, brings type-safe navigation to the JSF 2 (usingContexts and Dependency Injection, JSR-299). Another implementation is Seam Faces. It isprobable that type-safe navigation will be addressed in future version of JSF specification.There has to be a new class defined for each view and the action method returns a Classobject instead of string:

1 public Class fooAction() {2 // some business logic3 return Page2.class;4 }

11

Page 19: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

2.6 Managed Beans and Scopes

Model objects in JSF are called managed beans. Section 2.3 showed how to define and usea simple managed bean. Managed beans are accessed from XHTML pages using UnifiedExpression Language (EL). 6 Any time user references a bean, Managed Bean Creation facil-ity creates the bean, initializes it, and stores it in the proper application scope if it does notalready exist. If the bean already exists, it is returned. [6, p. 110]

In JSF 1.x, it was necessary to configure managed beans in the faces-config.xml:1 <managed-bean>2 <managed-bean-name>fooBean</managed-bean-name>3 <managed-bean-class>com.pitonak.foo.FooBean</managed-bean-class>4 <managed-bean-scope>session</managed-bean-scope>5 </managed-bean>

In JSF 2 it is possible to configure managed beans directly in code using annotations, forexample see section 2.3.

In JSF 2 it is possible to use the following scopes:

• request—variables are available only during the current request;

• flash—variables survive a single view transition, including surviving redirects;

• view—variables are preserved until the user finishes interaction with the current view;

• session—variables are available for during of user’s HTTP session;

• application—variables are available for the entire life of the application; and

• custom—a scope defined by the user using EL expression instead of a keyword.

Even though new scopes were added to JSF 2 (flash and view), it is still missing some com-monly used scopes such as conversation known from JBoss Seam Framework. In Java EE 6 anew standard was created - Contexts and Dependency Injection (CDI, JSR-299). CDI definesfour built-in scopes: request, session, application, and conversation.7 It is recommended touse CDI for creating JSF 2 applications.

2.7 The Facelets View Declaration Language

When JSF was created, JSP was about to be reused as it was already a standard in the webcommunity. The idea was to simplify the adoption of JSF by using a familiar tag language.

6. Expression Language, http://java.sun.com/products/jsp/reference/techart/unifiedEL.html7. CDI scopes, http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/scopescontexts.html

12

Page 20: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

Unfortunately, JSP and JSF do not naturally complement each other. JSP is not suitable forcreating component trees. Its elements are processed in a page from top to bottom withthe basic objective of creating a response to a request. On the other hand, JSF has a morecomplex life cycle, and thus mixing JSP and JSF tags in pages causes problems. Consider thefollowing example:

1 <h:panelGroup>2 <h:outputText value="first"/>3 second4 </h:panelGroup>

In the example above, JSF tags (h:panelGroups and h:outputText) are mixed with JSPfragments (free text). This causes that the output of the example will be reversed: [9, p. 67-68]

1 second2 first

This is one of reasons why several view definition languages, such as Apache Shale’s Clay,JSFTemplating or Facelets, were created. Bruno Aranda and Zubin Wadia describe Faceletsas a templating language developed from the ground up with JavaServer Faces in mind.[10, foreword] Facelets is founded on the idea of compositions. This means that a compo-nent tree can be defined in multiple Facelet pages. A simple template can look like this(template.xhtml):

1 <html xmlns="http://www.w3.org/1999/xhtml" ...>2 <head>3 <title><ui:insert name="title">Default title</ui:insert></title>4 <ui:insert name="head"/>5 </head>6 <body>7 <ui:insert name="body">8 <p>Body of the page.</p>9 </ui:insert>

10 </body>11 </html>

Page using the defined template will then look like this (index.xhtml):

1 <html xmlns="http://www.w3.org/1999/xhtml" ...>2 <body>3 <ui:composition template="/template.xhtml">4 <ui:define name="title">Main page</ui:define>5 <ui:define name="body">6 some content7 </ui:define>8 </ui:composition>9 </body>

10 </html>

13

Page 21: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

JSF 2.0 recognizes the need for a standard alternative to JSP. JSF 2 introduced a genericfoundation for integrating view declaration languages into the JSF runtime environment—the view declaration language API. This API allows framework authors to define theirown view declaration languages and integrate these with JSF in a standard way. Moreover,Facelets became part of JSF 2.0 as default declaration language implementation. This 2.0 ver-sion of Facelets ought be very familiar to anyone who has been using Facelets 1.x. Most ofthe 1.x APIs are present, though there has been some tweaking/repackaging as part of thestandardization process. [8]

2.8 Composite Components

Creating a custom component in JSF is quite complicated process. In the worst case, a com-ponent class has to be created, with a lot of attributes with special getters and setters thatinteracts with StateHelper, renderer-specific class that contains similar attributes for pa-rameters related to HTML and defines JSF behavior events for them. A renderer class thatgenerates HTML code using spaghetti of startElement /writeAttribute/writeText/endElement calls has to be created as well. Everything has to be described in the faces-config.xml and Facelets taglib.xml has to be created. [11] RichFaces uses special ComponentDevelopment Kit (CDK) that simplifies development of custom components and lets devel-opers to concentrate on component functionality only.

Even though RichFaces CDK is a powerful tool, it is too complicated for simple components.JSF 2 greatly simplifies custom component development with the introduction of the “com-posite component” feature. [8]. A simple “Hello world” component could be implementedwith a single file with no Java code required (hello.xhtml):

1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">3 <html xmlns="http://www.w3.org/1999/xhtml"4 xmlns:h="http://java.sun.com/jsf/html"5 xmlns:composite="http://java.sun.com/jsf/composite">6 <h:body>7

8 <composite:interface>9 <composite:attribute name="who"/>

10 </composite:interface>11

12 <composite:implementation>13 <h:outputText value="Hello, #{cc.attrs.who}!"/>14 </composite:implementation>15

16 </h:body>17 </html>

This is how the component would be used on a page:

14

Page 22: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

1 <html xmlns="http://www.w3.org/1999/xhtml"2 xmlns:h="http://java.sun.com/jsf/html"3 xmlns:greet="http://java.sun.com/jsf/composite/greet">4 <h:head/>5 <h:body>6 <greet:hello who="World"/>7 </h:body>8 </html>

2.9 Resource Handling

Before JSF 2 each component library loaded resources (images, JavaScript files, style sheets,etc.) in its own way. JSF 2 provides a standard solution to resource loading with the intro-duction of the resource handler API. The ResourceHandler is responsible for serving upresources from well-known locations on the class path. Resource requests are routed throughthe FacesServlet, which passes these request onto the ResourceHandler for process-ing. This solution allows components and their resource dependencies to be bundled in thesame jar file with no need for a bonus servlet, servlet filter or phase listener to serve up theseartifacts. In order to support resource relocation, JSF 2 introduces two new tags: <h:head>and <h:body>. These components render the HTML head/body markup and also providea target for relocatable resources. [8]

2.10 Component Libraries

JSF provides a basic set of components for creating web pages such as inputs, outputs, ta-bles, etc. However, modern web applications require more advanced components, such asinplace inputs, tables with sortable columns, pagination in tables, various menus and pan-els, progress bars, charts and more. This is a reason why many components libraries werecreated. This thesis will describe four open source libraries—RichFaces, PrimeFaces, Open-Faces, and ICEfaces.

RichFaces

RichFaces is a JSF component framework containing tens of advanced visual and non-visualcomponents. JSF 2’s <f:ajax> tag was inspired by RichFaces <a4j:support> tag whichwill be described in detail in section 3.1. RichFaces is a project created by Alexander Smirnov.In 2005, Smirnov was hired by Exadel and continued to develop the framework (then calledAjax4jsf). In 2007 Red Hat and Exadel signed a partnership agreement. RichFaces were opensourced under the GNU Lesser General Public License, version 2.1 and became a JBoss.orgproject.

15

Page 23: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

The main features of RichFaces include advanced Ajax components, many visual compo-nent, strong skinning support, client side validation and a component development kit(CDK). In the sample application developed for this thesis (will be described later), version4.1.0-SNAPSHOT of RichFaces is used. Unlike RichFaces 3, client-side code in RichFaces 4is implemented in jQuery only. RichFaces 4 support this environments:

• Java Development Kit (JDK) 1.5 or higher;

• an application server compliant with JEE6, such as JBoss Application Server 6 or Glass-fish 3;

• servlet containers Tomcat 6 or 7;

• Google App Engine;

• JSF 2 implementation such as Mojarra 2.0.4 or Apache MyFaces 2.0.4; and

• web browser such as Google Chrome 11, Firefox 3.6, or Internet Explorer 8.

PrimeFaces

PrimeFaces is a lightweight open source (Apache License v2) component suite for JSF 2 fea-turing more than 100 of JSF components. Additional PrimeFaces Mobile module features aUI kit for developing mobile web applications. However, development of mobile web ap-plications is out of the scope of this work and therefore this part of PrimeFaces will notbe described. PrimeFaces is maintained by Prime Technology, a Turkish software develop-ment company specialized in agile consulting, JSF, Java EE and outsourcing. Project is ledby Çagatay Çivici. The sample application uses PrimeFaces 2.2.1 which support similar en-vironments as RichFaces.

OpenFaces

OpenFaces is an open-source library of Ajax-powered JSF components, an Ajax frameworkand a client-side validation framework. OpenFaces is based on the set of JSF componentsformerly known as QuipuKit. It contains fully revised codebase of QuipuKit and intro-duces many new components and features. OpenFaces is distributed under a dual licensemodel. Users can choose between using the library under GNU Lesser General Public Li-cense v2.1 or purchasing a commercial license. OpenFaces is contributed and administeredby TeamDev Ltd, and Ukrainian company providing Java development services. The sam-ple application uses OpenFaces 3.0 which supports very similar environments as Rich-Faces.

16

Page 24: Comparison of AJAX JSF Libraries Functionality and Interoperability

2. THE JAVASERVER FACES FRAMEWORK

ICEfaces

ICEfaces 2 is an open source (Mozilla Public License) rich Internet application developmentframework based on the JavaServer Faces 2 standard. Like its predecessor, ICEfaces 1.8,ICEfaces 2 extends JSF to simplify development and enhance the standard JSF feature set—simultaneously improving developer efficiency and expanding the spectrum of RIA capabil-ities that can be included in any JSF-based web application. Adhering closely to the standardJSF 2 extension points allows ICEfaces to work transparently with the stock JSF framework,simplifying integration and fostering 3rd party compatibility with other JSF 2-compliantlibraries.

The two most significant features of ICEfaces 2 are automatic Ajax with Direct-to-DOM ren-dering and Ajax Push (see chapter 3). ICEfaces 2 contains three sets of components:

1. ICEfaces Components—original components from ICEfaces 1.8 using a compatibilitylayer that enables them to work with JSF 2;

2. ICEfaces Advanced Components—using all the features of the JSF 2 standard and arebased on a new Advanced Component Environment; and

3. ICEfaces Enterprise Components—derived from ICEfaces 1.8 composite componentsbut ported to Facelets, these components are available only in ICEfaces 2 EnterpriseEdition.

Since this thesis deals only with freely available open source components, the ICEfacesEnterprise Components will not be compared. The sample application uses ICEfaces 2.0.2which runs on JBoss AS 6, Glassfish 3.1 and all modern web browsers. Moreover, it runs inLiferay Portal 5.2.3. [12]

There are many other open source JSF component libraries. In 2006 Oracle donated its Ora-cle ADF Faces to the Apache Software Foundation which became MyFaces Trinidad. Otherexamples are MyFaces Tobago (donated by Atanion GmbH) and MyFaces Tomahawk. Thereare also many proprietary technologies built on JSF, such as IBM’s XPages. Though, all thesetechnologies are out of the scope of this work.

17

Page 25: Comparison of AJAX JSF Libraries Functionality and Interoperability

3 Ajax and Core Components

3.1 Ajax in JSF 2 and in Component Libraries

One of major additions to the JSF 2 is standard Ajax support. In JSF 1.2 every compo-nent framework implemented Ajax in it own style. On the client side, JSF 2 exposes a newJavaScript API that issues an Ajax request back to the current view. Once the request entersthe Faces lifecycle, the state of the Ajax request is captured via the PartialViewContext.This object provides access to information such as which components are targeted for pro-cessing/rendering. The PartialViewContext’s processPartial() method uses thisinformation to perform partial subtree processing/rendering. When the rendered responseis sent back to the client, the callback previously provided by jsf.ajax.request() isinvoked. This callback automatically updates the client-side DOM to reflect the newly ren-dered markup. [8]

The jsf.ajax.request() JavaScript API is targeted for use by frameworks as well asby the JSF implementation itself. JSF 2 also includes a declarative approach using the new<f:ajax> tag. The tag was inspired by tag <a4j:support> tag from RichFaces 3:

1 <h:form>2 <h:inputText id="input" value="#{bean.text}" >3 <a4j:support event="keyup" process="input" reRender="output"/>4 </h:inputText>5 <h:outputText id="output" value="#{bean.text}" />6 </h:form>

1 <h:form>2 <h:inputText id="input" value="#{bean.text}" >3 <f:ajax event="keyup" execute="input" render="output"/>4 </h:inputText>5 <h:outputText id="output" value="#{bean.text}" />6 </h:form>

The first sample demonstrates the use of RichFaces 3 <a4j:support> tag. When a userstarts typing into input, pressed keys are sent by Ajax to the server, bean is updated andthen output is rerendered. Attribute execute says the server which data should be processand attribute reRender says the client which parts of the page should be rerendered. Thesecond sample does exactly the same but it uses JSF 2 to send Ajax request. Since it wasinspired by RichFaces 3, the usage is almost the same.

RichFaces 4 comes with its own tag, <a4j:ajax>, which is based on f:ajax but upgradesthe tag with more features and advanced functionality. It originates in <a4j:support> butwas greatly refactored in order to be similar to <f:ajax>. The previous example writtenusing RichFaces 4 would look very similarly:

1 <h:form>

18

Page 26: Comparison of AJAX JSF Libraries Functionality and Interoperability

3. AJAX AND CORE COMPONENTS

2 <h:inputText id="input" value="#{bean.text}" >3 <a4j:ajax event="keyup" execute="input" render="output"/>4 </h:inputText>5 <h:outputText id="output" value="#{bean.text}" />6 </h:form>

Max Katz describes non-standard features of <a4j:ajax>. [13] First of all, EL expressionsin render and execute attributes are evaluated differently and <a4j:ajax> accepts aspecial keyword @region which instructs the application to execute/render only <a4j:region>. Secondly, it adds new event handlers:

• onbegin—JavaScript to execute before Ajax request;

• onbeforedomupdate—JavaScript to execute after response comes back but before anyDOM update; and

• oncomplete—JavaScript to execute after response comes back but before any DOMupdate.

Last but not least important attribute is bypassUpdate which, if set to true, skips UpdateModel and Invoke Application phases which is useful for form validation.

PrimeFaces contain <p:ajax> tag that is very similar to RichFaces’ <a4j:ajax>. How-ever, there are some little differences. First, <p:ajax> has attribute process instead ofstandard execute and attribute update instead of standard render. PrimeFaces’ Ajax taghas additional event handlers similar to those in <a4j:ajax>—onstart, oncomplete,and onsuccess.

OpenFaces contain their own tag for Ajax, too. Similarly to RichFaces and PrimeFaces, it con-tains additional event handlers onajaxstart and onajaxend. Moreover, it has attributedelay that reduces the number of Ajax requests by skipping the frequently-happeningevents. This attribute specifies the delay in milliseconds that should elapse after an eventthat activates this component to start an actual request for reloading components (and in-voking an appropriate action if specified). If there will be another event during this delay,this event will postpone the request according to the specified delay instead of performingan additional request. As a result there will be only one request for all events that come morefrequently than specified in this attribute. Exactly the same behavior can be implemented inRichFaces by using queues (see section 3.5). Another interesting feature of <o:ajax> is itsattribute for which allows attaching Ajax component to an arbitrary component or HTMLtag instead of attaching to the parent component. The sample above might look in Open-Faces as follows:

1 <h:form>2 <h:inputText id="input" value="#{bean.text}" />3 <o:ajax for=":input" event="keyup" execute="input" render="output"/>4 <h:outputText id="output" value="#{bean.text}" />5 </h:form>

19

Page 27: Comparison of AJAX JSF Libraries Functionality and Interoperability

3. AJAX AND CORE COMPONENTS

ICEfaces use a very different approach to Ajax called automatic Ajax. ICEfaces AutomaticAjax feature guarantees minimal page updates under any condition, and does not requirethe page developer to consider how, when or why page updates occur. The key to AutomaticAjax is the use of Direct-to-DOM (D2D) rendering in the ICEfaces framework. D2D does justwhat it says, and writes the output of the JSF rendering phase into a server-side DOM thatrepresents exactly what the client DOM needs be. Using a cached version of the DOM, theframework calculates precisely the set of DOM updates required to affect the changes in thepage at the completion of any JSF lifecycle. [14, section Automatic Ajax]

Although the D2D handles the page updating aspect, it is still necessary to initiate the wholeprocess through some UI event. ICEfaces provides the Single Submit features, which causesa component to submit itself automatically when the user interacts with it.

1 <h:form>2 <icecore:singleSubmit/>3 <h:inputText id="myinput" value="#{bean.input}"/>4 output: <h:outputText id="output" value="#{bean.input}"/>5 </h:form>

On one hand, the automatic Ajax feature optimizes the development time but on the otherhand, there is some overhead as it is necessary to render the entire page to produce the DOMfor comparison. This can be optimized by using <f:ajax> tag with redefined attributerender.

1 <h:form>2 <icecore:singleSubmit/>3 <h:inputText id="myinput" value="#{bean.input}">4 <f:ajax execute="@this" render="output"/>5 </h:inputText>6 output: <h:outputText id="output" value="#{bean.input}"/>7 </h:form>

More information about both automatic Ajax and Direct-to-DOM rendering can be found inICEfaces documentation. [14, section Direct-to-DOM]

3.2 Region

RichFaces contain an <a4j:region> component which specifies a part of the JSF compo-nent tree to be processed on the server. The region causes all the a4j and rich Ajax controlsto execute: decoding, validating, and updating the model. The region causes these compo-nents to execute even if not explicitly declared. As such, processing areas can more eas-ily be marked using a declarative approach. Regions can be nested, in which case onlythe parent region of the component initiating the request will be processed. [15, sectiona4j:region]

20

Page 28: Comparison of AJAX JSF Libraries Functionality and Interoperability

3. AJAX AND CORE COMPONENTS

There is no region component in other component libraries. However, because of ICEfaces’automatic Ajax and Direct-to-DOM rendering, it is not needed when using ICEfaces.

3.3 Command Button and Command Link

RichFaces <a4j:commandButton> and <a4j:commandLink> components are similar tothe JavaServer Faces <h:commandButton> and <h:commandLink> components, but ad-ditionally include Ajax support. All extra attributes from <a4j:ajax>, e.g. onbegin orbypassUpdates, are also available in command button and command link.

Similarly to RichFaces, PrimeFaces command button and command link are very similarto standard JSF button and link but add advanced features that are available also in thecomponent <p:ajax>. What is unique comparing to RichFaces, <p:commandButton> and<p:commandLink> have attribute ajax which specifies submit mode—when set to true(default), submit would be made with Ajax.

OpenFaces link extends standard JSF link, too, and add some features from <o:ajax>.OpenFaces’ button is more advanced because it supports child elements inside and so itis possible to create graphical images with text:

1 <o:commandButton action="#{fooBean.bar}" ...>2 <h:graphicImage url="..."/>3 <h:outputText value="..."/>4 </o:commandButton>

ICEfaces contain command button and command link component that are very similar tothose in RichFaces.

Figure 3.1: Command button in RichFaces, PrimeFaces, OpenFaces, and ICEfaces

3.4 JavaScript Function

If a user need to fire an Ajax request from his JavaScript function, it is possible to directlycall jsf.ajax.request(), RichFaces.ajax() or similar functions from PrimeFacesand OpenFaces. However, this approach is error prone and therefore RichFaces contains thecomponent <a4j:jsFunction> which performs Ajax requests directly from JavaScriptcode and retrieves server-side data. The server-side data is returned in JavaScript Object

21

Page 29: Comparison of AJAX JSF Libraries Functionality and Interoperability

3. AJAX AND CORE COMPONENTS

Notation (JSON) format prior to the execution of any JavaScript code defined using theoncomplete attribute.

1 <a4j:jsFunction name="updateName" render="showname">2 <a4j:param name="name" assignTo="#{functionBean.text}"/>3 </a4j:jsFunction>4

5 <span onmouseover="updateName(’Kate’)" onmouseout="updateName(’’)">6 Kate7 </span>8 <h:outputText id="showname" value="#{functionBean.text}" />

OpenFaces’ component <o:ajax> has attribute standalone which behaves similarly to<a4j:jsFunction>. In is used in this way:

1 <h:form id="form">2 <h:inputText id="textField"3 onkeypress="O$(’form:updateImage’).run()" .../>4 <o:ajax id="updateImage" standalone="true" render="dynamicImage"5 execute="textField colorField fontSizeField" requestDelay="500"/>6 <o:dynamicImage id="dynamicImage" .../>7 </h:form>

There is not any similar component in PrimeFaces nor ICEfaces.

3.5 Queue

JSF 2 has very basic queue functionality—requests are queued and fired one at a time. Thismeans that only one request is processed on the server at a time. Since it is a very simplequeue, RichFaces implemented a much more sophisticated queue. The component <a4j:queue> provides additional options for a finer control of request processing. It worksin the same basic way as the standard JSF queue. It can be enabled and disabled throughthe enabled attribute. Attribute requestDelay adds a delay between each request in thequeue. Delaying requests avoids unnecessary processing for actions that would otherwisecause multiple requests, such as typing. Similar requests in the queue are combined whilewaiting for the request delay. The user ought be aware of the fact that the component doesnot handle standard JSF requests or requests from component libraries other than Rich-Faces. [15, section a4j:queue]

RichFaces contains behavior <a4j:attachQueue>which is used together with component<a4j:queue> to further customize queuing for particular components and behaviors. The<a4j:attachQueue> behavior can override the scope-wide queue settings for an individ-ual component, or attach specific requests to a queue.

1 <a4j:queue requestDelay="2000"/>2

3 <h:form>

22

Page 30: Comparison of AJAX JSF Libraries Functionality and Interoperability

3. AJAX AND CORE COMPONENTS

4 <h:inputText>5 <a4j:ajax event="keyup" />6 </h:inputText>7 <a4j:commandButton value="submit">8 <a4j:attachQueue requestDelay="0" />9 </a4j:commandButton>

10 </h:form>

PrimeFaces do not have any queue component. In OpenFaces, it is possible to set attributedelay of <o:ajax> which has similar functionality.

3.6 Status

Users of a web page usually want to know the status of latest action they triggered. This isthe place where status component is useful. RichFaces contain a highly customizable com-ponent <a4j:status> which can be in three states:

• progress—during the execution of an Ajax request;

• complete—after an Ajax request completed successfully; or

• error—after and Ajax request completed with an error.

It is possible to define start text, stop text and error text. User can choose whether compo-nent’s attributes or facets will be used.

1 <a4j:status id="status1" startText="Work in progress..."2 stopText="Complete" errorText="Error">3

4 <a4j:status id="status2">5 <f:facet name="start">6 <h:graphicImage value="/images/ai.gif" alt="ai"/>7 </f:facet>8 <f:facet name="stop">...</f:facet>9 <f:facet name="error">...</f:facet>

10 </a4j:status>

The <a4j:status> component monitors the status of the region relevant to where it isplaced. If it is unnamed and placed outside any forms, it monitors the status at the viewlevel. If unnamed and placed inside a form, it monitors the status at the form level. [15,section a4j:status]

PrimeFaces contains a similar component called <p:ajaxStatus>. Unlike RichFaces’ sta-tus, it is not possible to define start text, stop text, etc. using attributes. On the other hand,it has more facets so it is possible to customize the component a bit better. Its list of facetsinclude prestart, start, complete, error, and success. Similarly to <a4j:status>,it is possible to define whichever markup the user needs in facets.

23

Page 31: Comparison of AJAX JSF Libraries Functionality and Interoperability

3. AJAX AND CORE COMPONENTS

In OpenFaces, the status of current request is handled in different way. When any Ajaxrequest is in progress, the “Loading...” message with and animated image appear in theupper-right corner of the screen. This message is displayed by default. It is possible to con-figure this message for the whole application or for the particular page. The user can changethe Ajax progress message for the whole application by specifying the org.openfaces.ajaxMessageHTML parameter in web.xml. This parameter should be specified as portionof HTML that will be shown in the upper-right corner on an Ajax request. [16, section AjaxSettings Component]

1 <context-param>2 <param-name>org.openfaces.ajaxMessageHTML</param-name>3 <param-value><![CDATA[4 <div style="background: white; font: Tahoma 15pt normal; border: 1px solid

black;">5 <img src="/resources/images/progress.gif"/>6 Ajax request is currently in progress!7 </div>8 ]]></param-value>9 </context-param>

When the user needs to change the status only for a particular page, the progressMessagefacet of the <o:ajaxSettings> tag which accepts tag <o:defaultProgressMessage>should be used. It provides many options for customization, such as text, image URL, align-ment, transparency and many more. It is also possible to define mode which tells OpenFaceswhether to display message for all Ajax requests or only for those fired by OpenFaces com-ponents. Sample configuration would look like this:

1 <o:ajaxSettings>2 <f:facet name="progressMessage">3 <o:defaultProgressMessage text="..." imageUrl="..."4 mode="..." transparency="..." >5 </f:facet>6 </o:ajaxSettings>

RichFaces and OpenFaces interoperate in this field very nice. When an OpenFaces compo-nent fires an Ajax request, RichFaces’ status component shows the progress and vice versa.PrimeFaces status, unlike RichFaces and OpenFaces, can handle only requests from Prime-Faces components. RichFaces and OpenFaces cannot handle PrimeFaces requests, too.

The <a4j:status> components cannot be present on the page when using ICEfaces. Oth-erwise, the Ajax request is fired and the page is updated but the <a4j:status> nevershows the end of request. This causes that all subsequent requests are blocked.

There is the <ice:outputConnectionStatus> component that shows the progress ofan Ajax request. However, it does not work for standard JSF requests, only those made byICEfaces automatic Ajax. If no attributes are set, an image is displayed in each state.

1 <link rel="stylesheet" type="text/css"2 href="./xmlhttp/css/xp/xp.css"/>

24

Page 32: Comparison of AJAX JSF Libraries Functionality and Interoperability

3. AJAX AND CORE COMPONENTS

3 <ice:outputConnectionStatus/>

Figure 3.2: ICEfaces status in all states in two themes

3.7 Poll

Poll is a component that has the ability to send periodical Ajax requests and execute actionlistener on a JSF managed bean. RichFaces poll has all standard Ajax attributes, such asonbegin, render, execute, etc., but the most important attribute is interval which ispoll-specific. It specifies the time in milliseconds between requests.

There is a very similar component in PrimeFaces. It also defines attributes usual for Prime-Faces components firing Ajax requests. The most noticeable difference from RichFaces pollis that attribute interval accepts an integer expressing the number of seconds, not millisec-onds.

There is no component with similar functionality in OpenFaces. ICEfaces contain poll com-ponent only in Enterprise Edition.

3.8 Push

The push component performs real-time updates on the client side from events raised atthe server side, e.g. displaying new messages in a chat application. Push behavior can besimulated using poll technique but it in most cases produces too much network traffic.

Comet is a web application model in which a long-held HTTP request allows a web serverto push data to a browser, without the browser explicitly requesting it. [17, p. 1]. Thereare several techniques how to achieve this, including long polling and HTTP streaming.When using long polling, browser’s requests are suspended and only resumed when serverdecides to push data. After the response is retrieved, browser connects and begins to waitingfor data again. An application using streaming Comet opens a single persistent connectionfrom the client browser to the server for all Comet events. These events are incrementallyhandled and interpreted on the client side every time the server sends a new event, withneither side closing the connection. [18]

25

Page 33: Comparison of AJAX JSF Libraries Functionality and Interoperability

3. AJAX AND CORE COMPONENTS

More modern approach to dealing with push in web applications is using WebSockets. Web-Sockets is a technology providing bi-directional, full-duplex communication channels, overa single Transmission Control Protocol (TCP) socket. It is designed to be implemented inweb browsers and web servers, but it can be used by any client or server application. TheWebSocket specification—developed as part of the HTML5 initiative—introduced the Web-Socket JavaScript interface. The WebSocket API is being standardized by the W3C, and theWebSocket protocol is being standardized by the IETF. Because ordinary TCP connections toports other than 80 are frequently blocked by administrators outside of home environments,it can be used as a way to overcome these restrictions and provide similar functionality withsome additional protocol overhead while multiplexing several WebSocket services over asingle TCP port. The WebSocket standard simplifies much of the complexity around bi-directional web communication and reduces network traffic significantly.

Both RichFaces and PrimeFaces use the Atmosphere framework which implements bothComet and WebSockets and runs on any Java based web server including Tomcat, JBossAS, Glassfish and many more. For the client side, WebSocket was to be implemented inFirefox 4, Google Chrome 4, Opera 11, and Safari 5, as well as the mobile version of Safari iniOS 4.2. However, although present, support was disabled by default in Firefox 4 [19] andOpera 11 [20] because of concerns over security vulnerabilities. [21] Although the problemin WebSockets was already solved, it is expected that web browsers will implement the newversion of protocol in next major releases. This would mean that all major browsers shouldhave WebSockets enabled again in summer 2011.

RichFaces push component performs real-time updates on the client side from events raisedat the server side. The events are pushed out to the client through the Java Message Service(JMS). Instead of implementing its own messaging mechanism, RichFaces reuses the welldefined and tested standard solution. This results in very easy integration of <a4j:push>with existing enterprise applications. On the other hand, for smaller applications not us-ing Java EE compliant application server, it brings some overhead. When the <a4j:push>component is triggered by a server event, it can in turn cause Ajax updates and changes.The <a4j:push> component uses the Comet model for pushing data to the client.

On the server side, RichFaces push first needs to initialize topics context, get and instanceof TopicsContext and then send the message (the sample assumes that the JMS topic isconfigured in application server):

1 public void initializePush() {2 TopicsContext topicsContext = TopicsContext.lookup();3 Topic topic = topicsContext.getOrCreateTopic(4 new TopicKey("fooTopic", "fooSubtopic"));5 topic.setMessageDataSerializer(6 DefaultMessageDataSerializer.instance());7 }8

9 public void send() {10 try {

26

Page 34: Comparison of AJAX JSF Libraries Functionality and Interoperability

3. AJAX AND CORE COMPONENTS

11 TopicsContext.lookup().publish(12 new TopicKey("fooTopic", "fooSubtopic"), message);13 } catch (MessageException messageException) {14 ...15 }16 }

On client, <a4j:push> tag would be used like this:

1 <a4j:push address="fooSubtopic@fooTopic"2 onerror="alert(’Error: ’ + event.rf.data)"3 ondataavailable="handlePush(event.rf.data)"/>

Ajax Push in ICEfaces 2.0 leverages an asynchronous notification mechanism called ICE-push. ICEpush unleashes the power of Ajax Push in a wide range of Java and JavaScripttechnologies, including JSP, JSF, Spring MVC, GWT, Wicket, jQuery, and Prototype. ICE-push uses long polling to provide asynchronous notification over standard HTTP, usingonly standard browser capabilities.

The sequence of events involved in ICEfaces Ajax Push is following: [14, section Ajax PushOverview]

1. some state change in the application triggers an Ajax Push event;

2. ICEpush notification is delivered to the browser client over a dedicated ICEpush con-nection;

3. notification at client browser causes a JSF Ajax request with an empty execute phase;and

4. render phase captures new state of client, and Direct-to-DOM Rendering delivers in-cremental page updates to client.

ICEpush relies on Servlet 3.0 standard Asynchronous Request Processing APIs. If they arenot present in the deployment environment, normal thread blocking connections are used.For clustered and high-availability deployments of Ajax Push-enabled applications the En-terprise Push Server (EPS) is required. It manages asynchronous blocking connections acrossthe cluster and performs seamless fail over for mission-critical, high-availability deploy-ments. EPS is available in ICEfaces Enterprise Edition.

To use the ICEfaces push in application, client session has to be added to a push group:

1 PushRenderer.addCurrentSession("fooGroup");

Then, an Ajax Push notification ought be sent to any other client sessions in the push group“fooGroup”. To do so, method PushRenderer.render() has to be called.

1 public String myAction() {2 // some business logic3 PushRenderer.render("fooGroup");

27

Page 35: Comparison of AJAX JSF Libraries Functionality and Interoperability

3. AJAX AND CORE COMPONENTS

4 return null;5 }

ICEfaces push in version 2.0.2 does not work properly because of an issue with asynchro-nous request processing (see ICEfaces Jira PUSH-1281). The issue is scheduled to be fixed inICEfaces 2.1.

PrimeFaces Push is powered by Atmosphere, however it is only compatible with version0.5.x, not the newer one which is used by RichFaces push. To use <p:push>, the CometServlet and its mapping has to be defined in web.xml:

1 <servlet>2 <servlet-name>Comet Servlet</servlet-name>3 <servlet-class>org.primefaces.comet.PrimeFacesCometServlet</servlet-class>4 <async-supported>true</async-supported>5 </servlet>6 <servlet-mapping>7 <servlet-name>Comet Servlet</servlet-name>8 <url-pattern>/primefaces_comet/*</url-pattern>9 </servlet-mapping>

On the server side, the following method is the main element of PrimeFaces Push.1 CometContext.push(String channel, Object data)

On the client side, the component <p:push> is used. This component has two main para-meters—channel and onpublish. The channel attribute represents an unique name ofcommunication channel and onpublish attribute points to a JavaScript handler method.Published object is serialized as JSON, passed to publish handler, and is accessible usingresponse.data.

1 <h:head>2 <script type="text/javascript">3 function handlePublish(response) {4 alert(response.data);5 }6 </script>7 </h:head>8

9 <h:body>10 <h:form>11 <h:inputText value="..."/>12 <p:commandButton value="Send" actionListener="..."/>13 </h:form>14 <p:push channel="chat" onpublish="handlePublish"/>15 </h:body>

There is no push component in OpenFaces.

1. PUSH-128: Servlet 3.0’s ARP support is broken on Tomcat 7, http://jira.icefaces.org/browse/PUSH-128

28

Page 36: Comparison of AJAX JSF Libraries Functionality and Interoperability

4 Input Components

4.1 Calendar

Applications frequently require users to insert a date such as date of birth or the start date ofemployment. The <rich:calendar> component allows the user to enter a date and timethrough an inline or popup calendar. The popup calendar can navigate through months andyears, and its look and feel can be highly customized.

Figure 4.1: RichFaces calendar in popup mode expanded, in inline mode, and with hiddeninput

Simple usage of <rich:calendar> migh look like in the following sample. RichFaces cal-endar works fine with all <f:ajax>, <a4j:ajax>, <p:ajax> and <o:ajax>.

1 <rich:calendar value="#{bean.dateTest}" >2 <a4j:ajax event="change" .../>3 </rich:calendar>

In ICEfaces, there is the <ice:selectInputDate> component which renders either inlineor popup calendar depending on attribute renderAsPopup. Users may enter a date directlyinto the text input or click the popup button beside the input to display the popup calendarview (when in popup mode). When the attached <f:convertDateTime> is configured toshow time, the calendar will include a time editing UI.

1 <ice:selectInputDate id="calendar" value="#{bean.date}">2 <f:convertDateTime pattern="MM/dd/yyyy hh:mm a"3 timeZone="#{bean.timeZone}"/>4 </ice:selectInputDate>

OpenFaces contain two components for inputting dates—calendar and date chooser. Open-Faces calendar component is an inline component and date chooser has an input and popup

29

Page 37: Comparison of AJAX JSF Libraries Functionality and Interoperability

4. INPUT COMPONENTS

which contains <o:calendar>.

Figure 4.2: Expanded OpenFaces date chooser and calendar

In PrimeFaces, there is a <p:calendar> component. Like RichFaces calendar, it supportsboth inline and popup mode with or without icon.

Figure 4.3: PrimeFaces calendar in inline mode, default popup mode and popup mode acti-vated by clicking on button

It has very similar features to RichFaces calendar. However, there is one unique feature—paging. Using attribute pages it is possible to display multiple months at once.

Figure 4.4: PrimeFaces calendar with pages attributes set to 3

All above mentioned calendar components can be easily localized so that users can inputdates in the format to which they are used, names of months are in the language of theirschoice and week begins on Sunday or Monday according to set locale. All calendar compo-nents support only Gregorian calendar. It would not be easy to use e.g. Hebrew or Islamic

30

Page 38: Comparison of AJAX JSF Libraries Functionality and Interoperability

4. INPUT COMPONENTS

calendar in JSF components.

4.2 Inplace Inputs

An inplace input component allows information to be entered inline in blocks of text, im-proving readability of the text. RichFaces inplace input has three functional states: the viewstate, where the component displays its initial setting, such as “click to edit”; the edit state,where the user can input text; and the “changed” state, where the new value for the compo-nent has been confirmed but can be edited again if required. It is possible to set the compo-nent to save its state on blur event and to display controls for confirming or canceling user’sinput. The second similar component provided by RichFaces is <rich:inplaceSelect>.It looks the same in initial state but it renders a select menu instead of text input when inedit state. Basic inplace input and inplace select are very easy to use:

1 <rich:inplaceInput value="#{bean.value}"2 defaultLabel="click here to edit"/>3

4 <rich:inplaceSelect value="#{bean.value2}"5 defaultLabel="click here to edit" >6 <f:selectItems value="#{bean.selectItems}" />7 <f:selectItem itemValue="1" itemLabel="Item 1" />8 <f:selectItem itemValue="2" itemLabel="Item 2" />9 <f:selectItem itemValue="3" itemLabel="Item 3" />

10 <f:selectItem itemValue="4" itemLabel="Item 4" />11 </rich:inplaceSelect>

PrimeFaces contains a more universal component called <p:inplace>. It wraps not onlytext input but it is possible to create an inplace select, inplace checkbox or even inplace im-age. Inplace with inner <h:textInput> produces a component very similar to component<rich:inplaceInput>. However, with default settings, it does not behave the same—thecomponent does not save its state on blur event. On the other hand, it can be in editor modewhen it shows buttons for confirming or canceling the input and then it is possible to fireAjax requests. This advanced inplace would be used like this:

1 <p:inplace editor="true" onEditUpdate="msgs">2 <p:inputText value="#{inplaceBean.text}"3 required="true" label="text"/>4 </p:inplace>

Neither OpenFaces nor ICEfaces have inplace components.

4.3 Autocomplete

Users of modern web applications expect inputs to show suggestions as they type into in-put. The <rich:autocomplete> component is an auto-completing input box with built-in

31

Page 39: Comparison of AJAX JSF Libraries Functionality and Interoperability

4. INPUT COMPONENTS

Figure 4.5: RichFaces and PrimeFaces inplace input in initial state, in edit state and in editstate with controls enabled

Ajax capabilities. It supports client-side suggestions, browser-like selection, and customiza-tion of the look and feel. To use the component, it is necessary to implement a method thatwill return list of suggestions, e.g.:

1 public List<String> autocomplete(String prefix) {2 ArrayList<String> result = new ArrayList<String>();3 if (prefix != null && prefix.length() > 0) {4 Iterator<Capital> iterator = capitals.iterator();5 while (iterator.hasNext()) {6 Capital elem = ((Capital) iterator.next());7 if ((elem.getState() != null && elem.getState().toLowerCase().indexOf(

prefix.toLowerCase()) == 0) || "".equals(prefix)) {8 result.add(elem.getState());9 }

10 }11 } else {12 for (Capital capital : capitals) {13 result.add(capital.getState());14 }15 }16 return result;17 }

This method will be set in autocompletMethod attribute of the <rich:autocomplet>component.

1 <rich:autocomplete autocompleteMethod="#{bean.autocomplete}"2 value="#{bean.value}">

The <rich:autocomplete> can work in several modes which influence if the data shouldbe pre-loaded or if they will be fetched with an Ajax request on every user’s input. By de-fault, the first suggestion item is selected as the user types. This behavior can be deactivatedby setting selectFirst to false. Setting autoFill to true causes the combo-box to fill thetext field box with a matching suggestion as the user types. The attribute tokens can be usedfor user to be able to input multiple values. For example, if the tokens attribute is set to “, ”,

32

Page 40: Comparison of AJAX JSF Libraries Functionality and Interoperability

4. INPUT COMPONENTS

user can use both comma and space for separating inputs. For each input, a new suggestionis process begins.

PrimeFaces autocomplete component is very similar to RichFaces’ one. It can be used inalmost the same way. There is attribute completeMethod instead of RichFaces’ methodautocompleteMethod. This attribute can be bound to the method from RichFaces examplewithout any changes.

1 <p:autoComplete completeMethod="#{bean.complete}"2 value="#{bean.value}">

It is possible to limit the maximum number of suggestions, set minimum query length andeven set query delay in order to ensure that the server will not be flooded with Ajax re-quests.

Instead of waiting for user to send the input manually with some action button or link, it ispossible to send value of <p:autoComplete> instantly with Ajax. However, PrimeFacesdo not support standard JSF way, i.e. to attach an Ajax behavior (<f:ajax>, <p:ajax>,or <a4j:ajax>). To do Ajax request, one has to set attribute selectListener. Option-ally, some parts of the page can be rerendered after selection using onSelectUpdate op-tion.

In OpenFaces, an autocomplete input component is called <o:suggestionField>. It cancontain static options (similarly to <h:selectOneMenu>) or dynamic options. To use thelater, the autocomplete method from above example has to be modified slightly:

1 public List<String> getCapitals() {2 String prefix = Faces.var("searchField", String.class);3 ArrayList<String> result = new ArrayList<String>();4 if (prefix != null && prefix.length() > 0) {5 Iterator<Capital> iterator = capitals.iterator();6 while (iterator.hasNext()) {7 Capital elem = ((Capital) iterator.next());8 if ((elem.getState() != null && elem.getState().toLowerCase().indexOf(

prefix.toLowerCase()) == 0) || "".equals(prefix)) {9 result.add(elem.getState());

10 }11 }12 } else {13 for (Capital capital : capitals) {14 result.add(capital.getState());15 }16 }17 return result;18 }

Component will then be used in the following way:

1 <o:suggestionField id="suggestionField" value="#{oSuggestionFieldBean.value}"2 suggestionMode="custom">

33

Page 41: Comparison of AJAX JSF Libraries Functionality and Interoperability

4. INPUT COMPONENTS

3 <o:dropDownItems value="#{oSuggestionFieldBean.capitals}"/>4 <o:ajax event="change" render="output"/>5 </o:suggestionField>

Autocomplete in ICEfaces is represented by the <ice:selectInputText> component.The usage is very similar to previous components. The filtering method can be reused withvery small change.

1 <ice:selectInputText rows="15" width="300" valueChangeListener="#{bean.updateList}"

2 value="#{bean.selected}">3 <f:selectItems value="#{bean.list}" />4 </ice:selectInputText>

1 public void updateList(ValueChangeEvent event) {2 matchesList = new ArrayList<String>();3 String prefix = (String) event.getNewValue();4 if (prefix != null && prefix.length() > 0) {5 Iterator<Capital> iterator = capitals.iterator();6 while (iterator.hasNext()) {7 Capital elem = ((Capital) iterator.next());8 if ((elem.getState() != null && elem.getState().toLowerCase().indexOf(

prefix.toLowerCase()) == 0) || "".equals(prefix)) {9 matchesList.add(elem.getState());

10 }11 }12 } else {13 for (Capital capital : capitals) {14 matchesList.add(capital.getState());15 }16 }17 }

4.4 Slider

The <rich:inputNumberSlider> component is an input component for numerical val-ues that can optionally include control arrows to step through the values, a tooltip to displaythe value while sliding, and a text field for typing the numerical value which can then bevalidated against the slider’s range. Basic use of the component with no attributes specifiedwill render a slider with a minimum value of 0, a maximum of 100, and a gradient step of 1,together with a text field for typing the desired numerical value.

The <rich:inputNumberSlider> component is highly customizable, e.g. input can behidden, boundary values do not have to be displayed, step, minimal and maximal value canbe customized, and slider can be displayed horizontally or vertically.

PrimeFaces contains a slider component but it is much simpler though. The <p:slider>itself does not contain input but it has to be associated with some text input using attribute

34

Page 42: Comparison of AJAX JSF Libraries Functionality and Interoperability

4. INPUT COMPONENTS

Figure 4.6: Default RichFaces slider with value set to 81

for.

1 <h:inputText id="number" value="#{bean.value}"/>2 <p:slider for="number" style="width: 150px;"/>

Figure 4.7: PrimeFaces slider with default values

Similarly to <p:autoComplete> component, no Ajax behavior can be attached to compo-nent <p:slider>. Instead, the slideEndListener attribute has to be used which is notstandard JSF approach.

There is no slider component in OpenFaces nor ICEfaces standard component suite. How-ever, there is a slider component in ICEfaces Enterprise Edition.

4.5 Spinner

Spinner is a single-line input field with buttons to increase and decrease a numerical value.In RichFaces, this component is called <rich:inputNumberSpinner>. It has practicallythe same API as <rich:inputNumberSlider>. As in RichFaces slider, for basic use onlyattribute value has to be set (either to an EL expression or a literal).

Figure 4.8: RichFaces spinner component

Spinner is a very simple component. However, there are som features that can be cus-tomized. When changing the value using the buttons, raising the value above the maximumwill cause the spinner to restart at the minimum value. Likewise, when lowering below theminimum value the spinner will reset to the maximum value. This behavior can be deac-tivated by setting cycled to false, which will cause the buttons to stop responding when

35

Page 43: Comparison of AJAX JSF Libraries Functionality and Interoperability

4. INPUT COMPONENTS

the reach the maximum or minimum value. The second customizable feature is set with at-tribute enableManualInput. When it is set to false, it is not possible to type into spinner’sinput field.

In PrimeFaces, there is <p:spinner> component. Unlike PrimeFaces slider, this compo-nents behaves like a JSF component. Similarly to RichFaces slider, it is really easy to startusing the component:

1 <p:spinner value="#{bean.value}"/>

Many aspects of the component are customizable. Spinner’s step can be set using attributestepFactor, it is possible to set boundaries (i.e. min a max value), and using the at-tributes prefix and suffix it is possible e.g. to display spinners containing currency sym-bol.

1 <p:spinner value="#{bean.value}" prefix="$">2 <f:convertNumber currencySymbol="$" type="currency"/>3 </p:spinner>

OpenFaces contain a spinner component, too. It has features very similar to PrimeFaces andRichFaces spinner and practically identical API. It is possible to disabled manual input bysetting attribute typingAllowed to false. Buttons can be placed either on the left or on theright of spinner’s input. This can be achieved by using attribute buttonAlignment.

1 <o:spinner id="input" value="#{bean.value}" promptText="click here to edit"2 minValue="0" maxValue="10" step="0.1">3 <o:ajax render="output"/>4 </o:spinner>

However the example above is very simple, it does not work because of an exception re-turned in response for Ajax request:

1 <partial-response>2 <error>3 <error-name>class java.lang.IllegalStateException</error-name>4 <error-message>5 <![CDATA[org.openfaces.component.ajax.AjaxHelper]]>6 </error-message>7 </error>8 <extension ln="openfaces" ajaxResult="null" type="ajaxResult">9 </extension>

10 </partial-response>

This bug is caused by JSF itself. It was reported as JSF issue 1427.1 It is marked as critical andshould be resolved in Mojarra 2.2. There is a workaround for this issue, though. The follow-ing context parameter has to be set in web.xml pointing to the problematic page(s).

1. JSF Jira, http://java.net/jira/browse/JAVASERVERFACES-1427

36

Page 44: Comparison of AJAX JSF Libraries Functionality and Interoperability

4. INPUT COMPONENTS

1 <context-param>2 <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>3 <param-value>/page.xhtml</param-value>4 </context-param>

Then, <o:ajax> has to be replaced with <f:ajax>. After that, Ajax requests should befired and output should be updated as expected.

There is no spinner component is standard ICEfaces component suite. However, there arenumber spinner, date spinner, and text spinner components in ICEfaces Enterprise Edi-tion.

4.6 File Upload

Many web applications require or allow their users to upload files. In RichFaces, there iscomponent <rich:fileUpload> that features multiple uploads, progress bars, restric-tions on file types, and restrictions on sizes of the files to be uploaded.

Basic usage requires the fileUploadListener attribute. Use the attribute to reference alistener function on the server side after each file is uploaded. The listener should processfiles as required, such as storing them in the session, database, or filesystem directory. Thecomponent itself does not store uploaded files, so if the listener is not implemented they arenot stored anywhere. [15, section rich:fileUpload]

1 <rich:fileUpload fileUploadListener="#{bean.listener}" />

Depending on org.richfaces.fileUpload.createTempFiles context parameter ofthe web.xml, files will be uploaded to either a temporary directory (depending on operatingsystem) or to RAM. If the value is true, they will be uploaded to a temporary directory.

To limit the maximum size of the uploaded files, it is necessary to define the context parame-ter org.richfaces.fileUpload.maxRequestSize in the web.xml. Its value is definedin bytes.

Figure 4.9: RichFaces file upload with selected files and during the uploading

37

Page 45: Comparison of AJAX JSF Libraries Functionality and Interoperability

4. INPUT COMPONENTS

PrimeFaces file upload is based on Flash. If the user agent does not support JavaScript orFlash, it fallback to the standard input with type set to file.

First of all, PrimeFaces file upload requires two additional dependencies, namely commons-fileupload version 1.2.1 and commons-io version 1.4 or newer. Then, file upload filter has tobe defined in application’s web.xml. Moreover, this filter has to be listed first.

1 <filter>2 <filter-name>PrimeFaces FileUpload Filter</filter-name>3 <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>4 </filter>5 <filter-mapping>6 <filter-name>PrimeFaces FileUpload Filter</filter-name>7 <servlet-name>Faces Servlet</servlet-name>8 </filter-mapping>

Figure 4.10: PrimeFaces file upload with selected files and during uploading

It is possible to configure <p:fileUpload> for single or multiple uploads. Upload can bestarted by clicking on “Upload” link, however, it is possible to turn on autouploading bysetting attribute auto to true. Like in RichFaces, uploads can be restricted to only specifiedfile types. To use this feature, attribute allowTypes has to contain a list of file extensions toaccept separated with semicolons. Size limit for uploaded files can be specified (in bytes) inattribute sizeLimit, not in context parameter like in RichFaces.

ICEfaces contain component <ace:fileEntry> which has very similar features to Prime-Faces and RichFaces file upload components. It uses a special AJAX technique for allowingICEfaces incremental page updates within HTML 4 compliant browsers. Files and otherform elements are all uploaded and processed together in a single JSF lifecycle.

Attribute absolutePath, or alternatively relativePath, determine the root directoryinto which files will be stored. If absolutePath is specified, then it is interpreted as anabsolute path into the file-system. As well, it takes precedence if relativePath is alsospecified, erroneously. If relativePath is specified, it is interpreted as a path within theapplication deployment directory. Component’s attributes maxTotalSize, maxFileSizeand maxFileCount allow for setting quota constraints on upload operations. They areevaluated and enforced for each individual form submit and upload. In ICEfaces 2.0.2 only

38

Page 46: Comparison of AJAX JSF Libraries Functionality and Interoperability

4. INPUT COMPONENTS

<h:commandButton> can be used to upload files. [14, section FileEntry]

Figure 4.11: Two ICEfaces file entry components before and after uploading files

There is no component for uploading files in OpenFaces.

39

Page 47: Comparison of AJAX JSF Libraries Functionality and Interoperability

5 Output Components

5.1 Progress Bar

The <rich:progressBar> component displays a progress bar to indicate the status of aprocess to the user. It can update either through Ajax or on the client side, and the look andfeel can be fully customized. Basic usage of the component <rich:progressBar> requiresthe value attribute, which points to the property that holds the current progress value. Whenthe value is greater than or equal to the minimum value (0 by default), the progress bar be-comes active, and starts sending Ajax requests if in ajax mode. [15, section rich:progressBar]The basic usage is very simple, only attribute value has to be specified:

1 <rich:progressBar value="#{bean.currentValue}" />

Progress bar’s label can be customized in two ways—either by using attribute label or byusing nested child elements:

1 <rich:progressBar value="#{bean.currentValue}">2 <h:outputText value="#{bean.currentValue} % complete"/>3 </rich:progressBar>

Figure 5.1: RichFaces progress bar with a label

RichFaces progress bar allows users to define two facets, initial and finish.

1 <rich:progressBar value="#{bean.currentValue}">2 <f:facet name="initial">3 <h:outputText value="Process has not started yet"/>4 </f:facet>5 <f:facet name="finish">6 <h:outputText value="Process has completed"/>7 </f:facet>8 </rich:progressBar>

The <rich:progressBar> supports two modes—ajax and client. The progress bar in ajaxmode works in the same way as the <a4j:poll> component. The component repeatedlypolls the server for the current progress value. When in client mode, the progress bar mustbe explicitly updated on the client side through the JavaScript API.

PrimeFaces progress bar is much simpler than RichFaces one but on the other hand it canbe styled better. It also can work in client and ajax mode. To use it in client mode, JavaScriptfunctions handling starting and stopping the progress bar have to be defined.

1 <p:progressBar widgetVar="pb" style="width: 200px"/>2 <p:commandButton value="Start" type="button" onclick="start()"/>

40

Page 48: Comparison of AJAX JSF Libraries Functionality and Interoperability

5. OUTPUT COMPONENTS

3 <p:commandButton value="Stop" type="buton" onclick="stop()"/>4

5 <script type="text/javascript">6 function start() {7 this.progressInterval = setInterval(function() {8 pb.setValue(pb.getValue() + 2);9 }, 2000);

10 }11

12 function stop() {13 clearInterval(this.progressInterval);14 pb.setValue(0);15 }16 </script>

Figure 5.2: PrimeFaces progress bar

There is a progress bar component in ICEfaces, too. The component supports both deter-minate and indeterminate modes. The component is used in very similar way like progressbars in other component libraries.

Figure 5.3: ICEfaces output progress

There is no progress bar component in OpenFaces.

5.2 Tree

Tree is a component used for displaying hierarchical data. The <rich:tree> componentprovides a hierarchical tree control. Each <rich:tree> component typically consists ofseveral <rich:treeNode> child components. The appearance and behavior of the treeand its nodes can be fully customized.

The <rich:tree> component requires only value attribute pointing to the data model.According to RichFaces Component Reference [15, section rich:tree], the data model mustbe either an org.richfaces.model.TreeNode interface, an org.richfaces.model.TreeDataModel interface, or a javax.swing.tree.TreeNode interface. The var at-

41

Page 49: Comparison of AJAX JSF Libraries Functionality and Interoperability

5. OUTPUT COMPONENTS

tribute declares the variable used for iterating through the data model, so that child <rich:treeNode> components can reference each iteration. Ideally, the <rich:tree> compo-nent needs one or more <rich:treeNode> components to work with the data model.However if no <rich:treeNode> components are provided the tree creates default nodesinstead.

Figure 5.4: Simple RichFaces tree, picture from RichFaces Component Reference [15]

Different nodes can have different appearance including font and icons for collapsed andexpanded state (see Figure 5.4). Expanding and collapsing nodes can work in three modes:client, ajax, and server. Similarly, these three modes can be used also for selecting treenodes.

In RichFaces, there are tree adaptors which can be used for populating tree model withnon-hierarchical data, such as list or map. The <rich:treeModelAdaptor> component isadded as a nested child component to a <rich:tree> component, or to another tree adap-tor component. The <rich:treeModelAdaptor> component requires the nodes attributefor basic usage. The nodes attribute defines a collection of elements to iterate through forpopulating the nodes. The <rich:treeModelAdaptor> is not the only adaptor. The com-ponent <rich:treeModelRecursiveAdaptor> iterates through recursive collections inorder to populate a tree with hierarchical nodes, such as for a file system with multiple levelsof directories and files. An example can be found in RichFaces Component Reference. [15,section rich:treeModelRecursiveAdaptor]

PrimeFaces tree is populated with a org.primefaces.model.TreeNode instance whichcorresponds to the root.

1 public TreeNode getModel() {2 TreeNode root = new DefaultTreeNode("Root", null);3 TreeNode node0 = new DefaultTreeNode("Node 0", root);4 ...5 TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);6 ...7 return root;8 }

42

Page 50: Comparison of AJAX JSF Libraries Functionality and Interoperability

5. OUTPUT COMPONENTS

1 <p:tree value="#{treeBean.root}" var="node">2 <p:treeNode>3 <h:outputText value="#{node}"/>4 </p:treeNode>5 </p:tree>

Figure 5.5: PrimeFaces tree

Like <rich:tree>, PrimeFaces tree also support client (called non-dynamic) and Ajax(called dynamic) mode for toggling. PrimeFaces tree supports three modes for nodes se-lection:

• single;

• multiple; and

• checkbox.

When the checkbox mode is selected, a checkbox is rendered next to each node.

ICEfaces also contains a highly customizable tree component. ICEfaces tree may displaynavigation controls for the dynamic expansion and collapse of branch nodes and nodes maysupport an action event when clicked that can be used to respond to user click events.

In order to use ICEfaces tree, it is necessary to define tree model first. Tree model in ICE-faces is represented by class javax.swing.tree.DefaultTreeModel. The followingcode demonstrates creation of a tree model for the <ice:tree> component:

43

Page 51: Comparison of AJAX JSF Libraries Functionality and Interoperability

5. OUTPUT COMPONENTS

Figure 5.6: PrimeFaces tree with selection mode set to checkbox

1 // create root node with its children expanded2 DefaultMutableTreeNode rootTreeNode = new DefaultMutableTreeNode();3 IceUserObject rootObject = new IceUserObject(rootTreeNode);4 rootObject.setText("Root Node");5 rootObject.setExpanded(true);6 rootTreeNode.setUserObject(rootObject);7

8 // model is accessed by by the ice:tree component via a getter method9 DefaultTreeModel model = new DefaultTreeModel(rootTreeNode);

10

11 // add some child nodes12 for (int i = 0; i < 3; i++) {13 DefaultMutableTreeNode branchNode = new DefaultMutableTreeNode();14 IceUserObject branchObject = new IceUserObject(branchNode);15 branchObject.setText("node " + i);16 branchNode.setUserObject(branchObject);17 for (int j = 0; j < 5; j++) {18 DefaultMutableTreeNode subbranchNode = new DefaultMutableTreeNode();19 IceUserObject subbranchObject = new IceUserObject(subbranchNode);20 subbranchObject.setText("node " + i + "." + j);21 subbranchNode.setUserObject(subbranchObject);22 branchNode.add(subbranchNode);23 }24 rootTreeNode.add(branchNode);25 }

After the model is created, the component can be used on a page as follows which willrender as a tree in Figure 5.7.

1 <ice:tree id="tree" value="#{iceTreeBean.model}" var="item"2 hideRootNode="false" hideNavigation="false"3 imageDir="./xmlhttp/css/xp/css-images/" >4

44

Page 52: Comparison of AJAX JSF Libraries Functionality and Interoperability

5. OUTPUT COMPONENTS

5 <ice:treeNode>6 <f:facet name="content">7 <ice:panelGroup style="display: inline">8 <ice:outputText value="#{item.userObject.text}" />9 </ice:panelGroup>

10 </f:facet>11 </ice:treeNode>12

13 </ice:tree>

Figure 5.7: ICEfaces tree

There is no tree component in OpenFaces.

45

Page 53: Comparison of AJAX JSF Libraries Functionality and Interoperability

6 Panels

It is usually necessary to organize elements of pages into smaller parts. JSF and extendinglibraries contain few container components such as simple panels, tab panel, togglable pan-els, wizards, etc.

6.1 Panels in RichFaces

The <rich:panel> is a bordered panel with an optional header. If no attributes are de-fined, a simple bordered panel without any header will be rendered. There are two way fordefining header of panel—using attribute header or using facet header.

1 <rich:panel header="header of panel">2 Lorem ipsum...3 </rich:panel>4

5 <rich:panel>6 <f:facet name="header">7 <h:outputText value="header of panel">8 </f:facet>9 Lorem ipsum...

10 </rich:panel>

Figure 6.1: RichFaces panel with header

In addition to simple panel, RichFaces contain also several advanced panels, namely col-lapsible panel, toggle panel, tab panel, and accordion. All listed RichFaces panels have at-tribute switchType which influence the way how the panels are toggled. There are threeoptions:

• server—performs standard HTTP request;

• ajax—performs Ajax request; and

46

Page 54: Comparison of AJAX JSF Libraries Functionality and Interoperability

6. PANELS

• client—toggles panel on the client without firing any request.

The <rich:accordion> is a series of panels stacked on top of each other, each collapsedsuch that only the header of the panel is showing. All togglable panels are easy to use andall share the same API. The <rich:accordion> component is used together with <rich:accordionItem>, <rich:tabPanel> with <rich:tab>, and <rich:togglePanel>with <rich:togglePanelItem> component.

1 <rich:accordion id="accordion" switchType="ajax">2 <rich:accordionItem id="item1" name="item1" header="Item 1">3 content of item 14 </rich:accordionItem>5 <rich:accordionItem id="item2" name="item2" header="Item 2">6 content of item 27 </rich:accordionItem>8 ...9 </rich:accordion>

Figure 6.2: RichFaces accordion with five accordion items and fourth item disabled

The <rich:collapsiblePanel> looks like simple <rich:panel> but it can be toggled.All RichFaces panels are highly customizable, e.g. it is possible to set icons on the left andon the right in all states.

The <rich:popupPanel> component provides a window that appears in front of the restof the application. The <rich:popupPanel> component functions either as a modal win-dow which blocks interaction with the rest of the application while active, or as a non-modalwindow. This functionality can be turned on or off by setting attribute modal to true orfalse. It can be movable and resizable. The popup panel is usually opened and closed on theclient using JavaScript API. In order not to use JavaScript directly, one can use the <rich:componentControl> component. The pop-up panel can be automatically sized when it isshown if the autosized attribute is set to true.

1 <h:commandButton id="openPanelButton" value="Call the popup"

47

Page 55: Comparison of AJAX JSF Libraries Functionality and Interoperability

6. PANELS

Figure 6.3: RichFaces collapsible panel in expanded and collapsed state

2 moveable="true">3 <rich:componentControl target="popupPanel" operation="show" />4 </h:commandButton>5 <rich:popupPanel header="Header of the panel">6 content...7 </rich:popupPanel>

Figure 6.4: RichFaces popup panel

6.2 Panels in PrimeFaces

PrimeFaces contain component called <p:panel> which is very similar to RichFaces panel.It also enables user to define header as attribute or as facet. Moreover, PrimeFaces panel

48

Page 56: Comparison of AJAX JSF Libraries Functionality and Interoperability

6. PANELS

component allows the user to define also footer in the same way as header. PrimeFacespanel can be made togglable using attribute toggleable set to true. When it is desiredto get notified on server side when a panel is toggled, it is possible to do so by using AjaxtoggleListener. Unlike RichFaces panel, PrimeFaces panel can be made closable. In or-der to make panel closable, its attribute closeable has to be set to true. Last but not leastimportant feature of the <p:panel> is the ability to define popup menus in its header. Touse this feature, facet options has to contain <p:menu> component.

Figure 6.5: Togglable and closable PrimeFaces panel

There is <p:accordionPanel> component in PrimeFaces. It is used in connection withseveral <p:tab> components. It is possible to define an effect that will be used for switchingtabs.

1 <p:accordionPanel id="accordionPanel" effect="hover">2 <p:tab id="item1" title="Item 1">3 content of item 14 </p:tab>5 <p:tab id="item2" title="Item 2">6 content of item 27 </p:tab>8 ...9 </p:accordionPanel>

49

Page 57: Comparison of AJAX JSF Libraries Functionality and Interoperability

6. PANELS

Figure 6.6: PrimeFaces accordion panel with second tab expanded

There is also a tabbed panel in PrimeFaces called tab view. It is possible to take accordionpanel sample and change top-level tag and the tab panel will be rendered:

1 <p:tabView id="tabPanel" effect="hover">2 <p:tab id="item1" title="Item 1">3 content of item 14 </p:tab>5 <p:tab id="item2" title="Item 2">6 content of item 27 </p:tab>8 ...9 </p:tabView>

Figure 6.7: Simple PrimeFaces tab view

There is a component similar to RichFaces popup panel called dialog. It has almost the samefeature set. The component is controlled by JavaScript. Since PrimeFaces do not have any-thing like <rich:componentControl>, it is needed to define attribute widgetVar. Thisdefines the name of the widget which can be then used in JavaScript. This is commonly usedconcept in PrimeFaces.

1 <a href="#" onclick="dialog.show()">Show</a>2 <a href="#" onclick="dialog.hide()">Hide</a>3

4 <p:dialog header="Panel Header" widgetVar="dialog" closable="true">

50

Page 58: Comparison of AJAX JSF Libraries Functionality and Interoperability

6. PANELS

5 content...6 </p:dialog>

6.3 Panels in OpenFaces

OpenFaces contains several panel components, too. The one similar to RichFaces collapsiblepanel is called folding panel. It is used in a very similar way:

1 <o:foldingPanel caption="Header of panel">2 content...3 </o:foldingPanel>

OpenFaces folding panel can work in three modes similar to those in RichFaces (client,server, and ajaxAlways). Moreover, there is one extra mode called ajaxLazy. In this mode, thecontent of the panel is loaded from the server with Ajax request. Once loaded, it is cachedon the client and shown without additional server requests on further expansions.

Figure 6.8: OpenFaces folding panel in expanded state

By default, the folding panel component expands downwards. However, it is possible toconfigure it to expand in other directions using attribute foldingDirection (possibleoptions are up, down, left, and right).

The layered pane component is similar to the <rich:togglePanel>. It is used togetherwith <o:subPanel> child components. Like in folding panel, this component also canwork in four modes including ajaxLazy.

1 <o:layeredPane id="layeredPane" loadingMode="client">2 <o:subPanel>3 content 14 </o:subPanel>5 <o:subPanel>6 content 27 </o:subPanel>8 ...9 </o:layeredPane>

51

Page 59: Comparison of AJAX JSF Libraries Functionality and Interoperability

6. PANELS

OpenFaces do not contain full-fledged popup panel. Although there is a universal compo-nent <o:popupLayer>, it is rather a general container for other components. It supportsdragging, resizing and even modal mode. However, it does not define any header.

The <o:tabbedPane> component can be used instead of <rich:tabPanel>. It is usedtogether with <o:subPanel> component. It is possible to use tag <o:subPanels> in or-der to generate tabs dynamically in both <o:tabbedPane> and <o:layeredPane>. It ispossible to customize the placement of the tabs. To do so, the attribute tabPlacement hasto be set to one of top, left, bottom, or right. One unique feature of the <o:tabbedPane>is out of the box keyboard support. It is possible to use up, down, left, and right keys tonavigate in a tabbed pane.

1 <o:tabbedPane>2 <o:subPanel caption="First tab">3 <h:outputText value="Some text on the first tab" />4 </o:subPanel>5 <o:subPanel caption="Second tab">6 <h:outputText value="Some text on the second tab"/>7 </o:subPanel>8 </o:tabbedPane>

Figure 6.9: OpenFaces tab panel with fourth tab active

6.4 Panels in ICEfaces

ICEfaces contain a collapsible panel component which is used in the same way as <rich:collapsiblePanel>. Although it is very similar to RichFaces collapsible panel, it sup-ports only Ajax mode.

1 <ice:panelCollapsible id="panel" style="width: 600px;">2

3 <f:facet name="header">4 <ice:panelGroup>5 <ice:outputText value="Lorem Ipsum"/>6 </ice:panelGroup>7 </f:facet>8

9 Lorem ipsum...10

11 </ice:panelCollapsible>

52

Page 60: Comparison of AJAX JSF Libraries Functionality and Interoperability

6. PANELS

Figure 6.10: ICEfaces collapsible panel

ICEfaces contain a basic togglable panel called panel stack. It is similar to RichFaces togglepanel which does not render any additional markup. The component <ice:panelStack>has to contain one or more <ice:panelGroup> child components. The panel stack com-ponent can be used in cases where a form region must contain several embedded panels,only one of which is visible at one time, changing dynamically depending on an applicationstate change or user selection.

1 <ice:selectOneRadio value="#{bean.selectedPanel}">2 <f:selectItem itemValue="panel1"/>3 <f:selectItem itemValue="panel2"/>4 <f:selectItem itemValue="panel3"/>5 </ice:selectOneRadio>6

7 <ice:panelStack id="stack" selectedPanel="#{bean.selectedPanel}">8 <ice:panelGroup id="panel1"> ... </ice:panelGroup>9 <ice:panelGroup id="panel2"> ... </ice:panelGroup>

10 <ice:panelGroup id="panel3"> ... </ice:panelGroup>11 </ice:panelStack>

The <ice:panelTabSet> is a container component which represent a tab panel. It itselfcontains one or more <ice:panelTab> components which are also container components.It is used in a similar way as <rich:tabPanel>.

1 <ice:panelTabSet id="stack" selectedIndex="#{bean.selectedPanel}">2 <ice:panelTab id="tab1" label="Tab 1">...</ice:panelTab>3 <ice:panelTab id="tab2" label="Tab 2">...</ice:panelTab>4 <ice:panelTab id="tab3" label="Tab 3">...</ice:panelTab>5 <ice:panelTab id="tab4" label="Tab 4">...</ice:panelTab>6 </ice:panelTabSet>

There is a popup panel in ICEfaces which can be, like popup panels in other libraries, mov-able, modal or non-modal. Unlike RichFaces popup panel, ICEfaces panel cannot be resiz-able. Although it has attribute resizable, it has not been implemented in version 2.0.2. Theother difference from RichFaces panels is that it does not support client mode.

1 <ice:panelPopup id="popup" visible="#{icePanelPopupBean.visible}"2 draggable="true" modal="true" autoCentre="true">3

4 <f:facet name="header">5 <ice:panelGroup styleClass="popupHeaderWrapper">

53

Page 61: Comparison of AJAX JSF Libraries Functionality and Interoperability

6. PANELS

Figure 6.11: ICEfaces panel tab set with third tab activated

6 <ice:outputText value="Header"/>7 <ice:commandButton id="modalPnlCloseBtn" type="button"8 image="/resources/images/popupclose.gif"9 actionListener="#{icePanelPopupBean.togglePanel}"

10 styleClass="popupHeaderImage"11 title="Close Popup" alt="Close"/>12 </ice:panelGroup>13 </f:facet>14

15 <f:facet name="body"> ... </f:facet>16

17 </ice:panelPopup>

Figure 6.12: ICEfaces popup panel in modal mode

54

Page 62: Comparison of AJAX JSF Libraries Functionality and Interoperability

6. PANELS

ICEfaces contain a panel that is not in RichFaces—a split pane panel. It is a component thatis split into two parts horizontally or vertically and serves as a container for other compo-nents. User can use panel divider to resize panes. Basic usage is very simple. The followingexample will be rendered as the panel in Figure 6.13.

1 <ice:panelDivider>2 <f:facet name="first">3 content of the first pane4 </f:facet>5 <f:facet name="second">6 content of the second pane7 </f:facet>8 </ice:panelDivider>

Figure 6.13: ICEfaces panel divider

55

Page 63: Comparison of AJAX JSF Libraries Functionality and Interoperability

7 Iteration Components

Creators of web applications need very often to display sets of data in form of a list, table orwith some custom markup. JSF 2 contains three components usable for iterating through alist of objects:

• <h:dataTable>—renders an HTML <table> element compliant with the HTML 4.0.1specification; one row in table corresponds to one object in list of objects;

• <h:panelGrid>—renders an HTML <table> element, conforming to the rules in theHTML 401 specification; attribute columns specifies how many columns should berendered before starting a new row; and

• <ui:repeat>—intended as a replacement for the c:forEach tag from the JSTL Coretag library.

The following code will render a table with two columns, the first will contain employee’sname and the second one will contain employee’s phone number:

1 <h:dataTable value="#{bean.employees}" var="employee">2 <h:column>3 <f:facet name="header">Name</f:facet>4 #{employee.name}5 <f:facet name="footer">Name</f:facet>6 </h:column>7 <h:column>8 <f:facet name="header">Phone Number</f:facet>9 #{employee.phoneNumber}

10 <f:facet name="footer">Phone Number</f:facet>11 </h:column>12 </h:dataTable>

Since the standard JSF components are very simple, component libraries came with theirown iteration components which usually contain at least one table with advanced featuressuch as column sorting and filtering, scrolling, row selecting, changing column order usingdrag and drop, and pagination of long data sets. Last but not least they advanced itera-tion components usually support lazy loading of data. 1 Basically, all iteration componentshave the same standard API so it is very easy to change implementation, e.g. in the exampleabove, it is possible to change <h:dataTable> and <h:column> to <rich:dataTable>and <rich:column> respectively and the sample will function without any other modifi-cations.

1. Lazy loading is a design pattern to defer initialization of an object until the point at which it is needed.

56

Page 64: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

7.1 RichFaces Repeat, List and Data Grid

The non-visual <a4j:repeat> component extends the standard UIRepeat component toallow partial updates within iterations while sending Ajax requests. The component acts asa base for all the other RichFaces data iteration components. The component itself does notrender any special markup so it is possible to wrap one’s data in whichever markup. Forinstance, it is easy to create a standard HTML unordered list with <a4j:repeat>:

1 <ul>2 <a4j:repeat value="#{bean.employees}" var="employee">3 <li>#{employee.name}: #{employee.phoneNumber}</li>4 </a4j:repeat>5 </ul>

All RichFaces iteration components allow the use of standard attributes first (which ob-ject from the collection will be the first displayed) and rows (how many objects ought berendered) with which it is possible to limit the size of the source data. Moreover, it is pos-sible to attach a <rich:dataScroller> to every RichFaces iteration component and thusadd pagination to it. This will be explained in detail later in this section.

Although it is easy to create an unordered list with <a4j:repeat>, it can be even moresimplified by using <rich:list>. RichFaces list component renders unordered, orderedor definition list depending on its type attribute.

1 <rich:list value="#{bean.employees}" var="employee" type="onordered">2 #{employee.name}: #{employee.phoneNumber}3 </rich:list>

The <rich:dataGrid> component is used to arrange data objects in a grid. Values in thegrid can be updated dynamically from the data model, and Ajax updates can be limited tospecific rows. The component supports header, footer, and caption facets. The compo-nent <rich:dataGrid> is similar in function to the standard JavaServer Faces component<h:panelGrid>. However, the <rich:dataGrid> component additionally allows itera-tion through the data model rather than just aligning child components in a grid layout. [15,section rich:dataGrid]

57

Page 65: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

Figure 7.1: RichFaces data grid with scroller in its footer and columns attribute set to 3

7.2 RichFaces Data Table

The <rich:dataTable> component is used to render a table, including the table’s caption.It works in conjunction with the <rich:column> and <rich:columnGroup> compo-nents to list the contents of a data model. The basic usage is the same as for <h:dataTable>but RichFaces data table supports some advanced features, namely filtering and sorting ofdata. The table supports four self-explaining facets:

• caption;

• header;

• footer; and

• nodata.

It is possible to specify header and footer not only for table but also for each column.

The <rich:collapsibleSubTable> component acts as a child element to a <rich:dataTable> component. The <rich:collapsibleSubTable> iterates through the childcollections in the currently iterated object to create master-detail tables. Additionally, thedetail part of the table can be collapsed or expanded through different modes. The <rich:collapsibleSubTable> component works with the collapsible subtable toggler com-ponent, which expands and collapses the sub-tables. [15, section rich:collapsibleSubTable]Sample for using collapsible sub tables can be found in Appendix A.

58

Page 66: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

Figure 7.2: RichFaces data table with all facets set with data (left) and without data (right)

Figure 7.3: RichFaces data table containing two subtables, the first one is collapsed

Table filtering in RichFaces is done using column’s attribute filterExpression. This at-tribute has to be set to an EL expression evaluating to boolean. The expression checks ifeach table entry satisfies the filtering condition when the table is rendered. For example, theexpression might be a JSTL function such as contains or equals. Another approach isto use filter attribute which points to an object which implements the org.richfaces.model.Filter<T> interface. The object provides method accept(T t) which takes eachiteration object as a parameter and returns a boolean value, which determines whether theobject satisfies the filter. By defining a custom filter, it is possible to implement complexbusiness logic to filter a table. [15, section Table filtering]

A table’s column can be sortable by using the attribute sortBy. By default, the targetwill be sorted using the compare() method. If using custom-defined rules for sorting, thecomparator attribute ought be used instead. The sorting order is managed by binding thesortOrder attribute to bean properties. If a column is sortable, its header is rendered as aclickable link (see Figure 7.4). Example in Appendix B demonstrates table sorting.

59

Page 67: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

Figure 7.4: RichFaces data table with all columns sortable

Last but not least, RichFaces data table adds few self-explaining JavaScript event handlers:onrowclick, onrowdblclick, onrowkeydown, onrowkeypress, onrowkeyup, etc.

7.3 RichFaces Extended Data Table

The <rich:extendedDataTable> component extends the functionality of the <rich:dataTable> component adding features such as scrolling for the table body (both hori-zontal and vertical), Ajax loading for vertical scrolling, frozen columns, row selection, andrearranging of columns. It also supports all the basic table features such as sorting, filtering,and paging.

In order to freeze some columns so that they will not be scrolled horizontally, attributefrozenColumns has to be set. The result of the following example can be seen on pictureFigure 7.5.

1 <rich:extendedDataTable value="#{carsBean.allInventoryItems}"2 var="car" id="table" frozenColumns="2"3 style="height:300px; width:500px;">4 ...5 </rich:extendedDataTable>

Another advanced feature of the extended data table is selection of table rows. There arefour modes available:

• none—no row can be selected;

• single—only one row can be selected;

60

Page 68: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

Figure 7.5: RichFaces extended data table with attribute frozenColumns set to 2

• multiple—multiple rows can be selected, it is possible to use Ctrl and Shift keys forselection; and

• multipleKeyboardFree—similar to the previous mode but multiple rows can be se-lected without using keyboard.

To use this feature of extended data table, it is necessary to set attribute selectionMode toone of the mentioned modes and bind attribute selection with a bean property.

1 <rich:extendedDataTable value="#{extTableSelectionBean.inventoryItems}"2 var="car" selection="#{extTableSelectionBean.selection}"3 id="table" frozenColumns="2" style="height:300px; width:500px;"4 selectionMode="multiple">5 ...6 </rich:extendedDataTable>

Columns in a <rich:extendedDataTable> component can be rearranged by the userby dragging each column to a different position. A graphical representation of the columnis displayed during dragging. Filtering and sorting features are implemented in <rich:extendedDataTable> in the same way as in <rich:dataTable>. Pagination is imple-mented using a data scroller described in the following section.

7.4 RichFaces Data Scroller

The <rich:dataScroller> component is used for navigating through multiple pages oftables. There are two ways how to use <rich:dataScroller>:

1. placing it in a facet of the data table or grid which it needs to control; or

61

Page 69: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

2. using the for attribute to bind the parent table or grid to the scroller.

The bound table or grid should also have the rows attribute defined to limit the numberof rows per page. The <rich:dataScroller> component must be rerendered whenevera filter changes on the bound table, so that the scroller matches the current model for thetable. The table with data scrollers in following example will be rendered like one in Fig-ure 7.6.

1 <rich:datascroller for="table" maxPages="5">2 <rich:dataTable id="table" value="#{capitalsBean.capitals}" var="cap"3 rows="5">4 ...5

6 <f:facet name="footer">7 <rich:datascroller maxPages="5">8 </f:facet>9 </rich:dataTable>

The appearance of the component can be customized using facets (first, last, next,previous, fastForward, and fastRewind). Additionally, there are facets for the con-trols’ disabled states: first_disabled, last_disabled, next_disabled, etc. The at-tribute maxPages can be used to limit the number of page controls that appear.

Figure 7.6: RichFaces data table with two scrollers

The <rich:dataScroller> component is not limited only to RichFaces data table but itcan be used with all standard JSF iteration components and with all RichFaces iteration com-ponents. Moreover, it is possible to use <rich:dataScroller> for scrolling PrimeFacesiteration components.

62

Page 70: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

7.5 OpenFaces ForEach

The ForEach component is an iteration component that renders the specified set of com-ponents multiple times based on its parameters. The ForEach component is similar to theJSTL <c:forEach> tag and RichFaces <a4j:repeat>. It is used in similar way as <a4j:repeat>:

1 <ul>2 <o:forEach items="#{bean.employees}" var="employee">3 <li>#{employee.name}: #{employee.phoneNumber}</li>4 </o:forEach>5 </ul>

Although <o:forEach> component is very similar to <a4j:repeat> component, thereare two differences for which it is more generally usable. First, it contains attribute stepwhich specifies the index increase step between the successive iteration rounds. Using this,it is possible to render only every third row or iterate backwards. the second feature is ex-tended support for types usable in attribute items. Unlike in standard JSF components andRichFaces components, it is possible to use any of these:

• java.util.Collection (or any of its implementations);

• array;

• javax.faces.model.DataModel (or any of its implementations);

• java.sql.ResultSet; or

• javax.servlet.jsp.jstl.sql.Result.

7.6 OpenFaces Data Table

The <o:dataTable> component provides all the advanced functionality that RichFacesextended data table provides. The <o:dataTable> component defines several facets—above, below, header, subHeader, footer, and noDataMessage. The content of facetabove renders before the table and facet below renders after the table.

Inside OpenFaces data table, it is possible to use <o:column> which renders standard col-umn with content by user. Another option is to use <o:selectionColumn> which rendersa column with checkboxes for multiple row selection or radio buttons for single row selec-tion. The third tag usable inside <o:dataTable> is <o:checkboxColumn> which ren-ders a column of checkboxes whose values are not store in the row data object. OpenFacesdata table provides an ability to specify dynamic number of columns—it is done using <o:columns>.

63

Page 71: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

It is possible to let the user reorder columns interactively with drag and drop by adding the<o:columnReordering> tag into the <o:dataTable> tag. When this feature is turnedon, the user can drag the column by its header and drop it into the appropriate place in-between columns. The current drop target is highlighted for user’s convenience. [16, sectionData Table]

Figure 7.7: OpenFaces data table with scrolling, filtering and sorting turned on

Columns can be made resizable by adding the <o:columnResizing> tag as a child of <o:dataTable> tag. When column resizing is turned on, the user can drag the column headerseparators to resize columns. The total table width is not affected by the process of resizingcolumns. Sample data table with resizable columns might look like this:

1 <o:dataTable var="employee" value="#{bean.employees}" width="100%">2 <o:columnResizing resizeHandleWidth="10px" minColWidth="100px"/>3 <o:column id = "name"> #{employee.name}</o:column>4 <o:column id = "title"> #{employee.title}</o:column>5 </o:dataTable>

One of the features that differ <o:dataTable> from RichFaces tables is ability to add thecolumn menu to allow performing the standard column operations such as sorting, showingand hiding columns, or to provide custom column-specific operations. This feature is turnedon by specifying the columnMenu facet. Specifying this facet makes a drop-down buttonto appear in the column’s header when the user hovers over the header and pressing thisbutton shows the menu. It is possible to specify the standard column menu with the tag<o:columnMenu> in this facet, or a custom menu with the <o:popupMenu> facet. Thefollowing sample from OpenFaces Developers Guide [16, section Data Table] illustrates howto use this feature:

1 <o:dataTable id="table" ...>2 ...

64

Page 72: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

3 <f:facet name="columnMenu">4 <o:columnMenu indentStyle="color: yellow">5 <o:sortAscendingMenuItem/>6 <o:sortDescendingMenuItem/>7 <o:hideColumnMenuItem/>8 <o:menuSeparator/>9 <o:menuItem value="Columns">

10 <o:columnVisibilityMenu/>11 </o:menuItem>12 <o:menuSeparator/>13 <o:menuItem value="Select Column" onclick="selectColumn(O$(’form:table’)

.getCurrentColumn().index);"/>14 <o:menuItem value="Unselect Column" onclick="unselectColumn(O$(’form:

table’).getCurrentColumn().index);"/>15 </o:columnMenu>16 </f:facet>17 ...18 </o:dataTable>

Sometimes the data set is too big and therefore also the table is too long and takes toomuch space on the page. In such case, it is possible to configure <o:dataTable> to scrollits content. This can be done simply by placing the <o:scrolling> inside of the <o:dataTable> component. Header and footer rows remain fixed independent of scrolling.Sample data table with vertical scrolling is displayed in the picture in Figure 7.7. Similarlyto RichFaces extended data table’s attribute frozenColumns, it is possible to exclude oneor more columns from horizontal scrolling and fix them on the table’s left or right side byspecifying the fixed attribute of the appropriate column:

1 <o:dataTable ...>2 <o:scrolling horizontal="true"/>3 <o:column fixed="true" .../>4 <o:column .../>5 <o:column .../>6 ...7 </o:dataTable>

To enable pagination in the <o:dataTable> component, one need to specify the pageSizeattribute. This attribute defines the number of rows to be displayed on each data table

page. If it is set to 0 (default), no pagination is provided. Also, optionally one can use thepageIndex attribute to specify the number of a currently displayed table page. Similarlyto RichFaces, setting an attribute is not sufficient. The <o:dataTablePaginator> com-ponent has to be placed on the page. The paginator component has to be placed inside thebelow or above facets of an <o:dataTable> and its id attribute has to be specified. Open-Faces paginator can be customized in many ways similarly to the <rich:dataScroller>component.

Sorting in OpenFaces data table can be turned on using attributes sortingExpressionand sortingComparator of a column. Sorting expression defines row’s value that will

65

Page 73: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

Figure 7.8: OpenFaces data table with paginator placed inside table’s below facet

be used for sorting. It should contain an EL expression. The sortingComparator at-tribute defines the comparator that is used to compare the values provided by the attributesortingExpression. This attribute should be specified as a value-binding expression andshould reference the object that implements the java.util.Comparator interface. If thesortingComparator attribute is not defined, sortingExpression should evaluate toeither a primitive type or an object that implements the java.lang.Comparable inter-face, for example String. [16, section Data Table] In Figure 7.7 the column “InstitutionName” is sortable and is set to sort ascending.

1 <o:dataTable var="employee" value="#{bean.employees}">2 <o:column id="nameColumn" sortingExpression="#{emplyee.name}"3 sortingComparator="caseInsensitiveText">4 <f:facet name="header">5 Name6 </f:facet>7 <h:outputText id="name" value="#{employee.name}" />8 </o:column>9 ...

10 </o:dataTable>

Filtering in <o:dataTable> component is implemented in a very general way and in manyaspects is easier to use than filtering in RichFaces data table or extended data table. Open-Faces Developer Guide [16, section Data Table] lists what is possible with filtering feature inOpenFaces data table:

• define column data filters;

• define filters that search data on a complex expression rather than a single-columnexpression;

• use different types of filter components;

• place filter components inside of the table or anywhere on the page;

66

Page 74: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

• customize all aspects of filtering behavior including search condition, case sensitivity,etc.;

• customize all aspects of filters’ visual appearance;

• use the composite filter builder2 as a universal filter component to allow the user buildcomplex filter criteria interactively; and

• easily add support for handling large data sets while utilizing all kinds of filters at-tached to the table.

Even though the list of features is long, it is quite easy to incorporate filtering into a table.The filtering functionality is defined using one of the filter tags (<o:inputTextFilter>, <o:dropDownFieldFilter>, <o:comboBoxFilter>, or <o:compositeFilter>).These filters can be used in two ways. First, a filter tag can be placed anywhere in col-umn’s facet. Second way is to place a filter anywhere on the page and specify the for at-tribute which works in the same way as for attribute of <h:outputLabel>. Figure 7.9shows a data table with filtering define as in the following code snippet. The first columncontains a combo box filter which displays a drop-down field with all possible values forgiven attribute of the bean. The second column contains an input text filter which ren-ders an input text field and so it is possible to input whichever string. There is a specialattribute called condition which accepts simple conditions like contains, beginsWith,less, greaterOrEqual, etc. It is even possible to create negative predicates. The thirdcolumn in Figure 7.9 contains a drop down field filter. It filters the data according to theexpression specified in the filter. This filter autocompletes user-typed input by default. Both<o:comboBoxFilter> and <o:dropDownFieldFilter> are filled with select optionsaccording to actual context (see Figure 7.9).

1 <o:dataTable ...>2 ...3 <o:column id="columnSex">4 <f:facet name="header">5 ...6 <o:comboBoxFilter expression="#{record.sex}"/>7 </f:facet>8 ...9 </o:column>

10

11 <o:column id="columnName">12 <f:facet name="header">13 ...14 <o:inputTextFilter caseSensitive="false" condition="contains"15 expression="#{record.name}"/>16 </f:facet>17 ...18 </o:column>19

2. The composite filter component http://openfaces.org/display/JSFC/CompositeFilter

67

Page 75: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

20 <o:column id="columnTitle">21 <f:facet name="header">22 ...23 <o:dropDownFieldFilter expression="#{record.title}"24 autoComplete="false" autoFilterDelay="500"/>25 </f:facet>26 ...27 </o:column>28 ...29 </o:dataTable>

Figure 7.9: OpenFaces data table with filtering using three types of filter

The last noteworthy feature of the <o:dataTable> component is row selection. There aretwo row selection modes available: single and multiple. Like in RichFaces, a user can selectthe rows either using mouse or using keyboard. Optionally, user can add a checkbox columnto the table which render checkboxes usable for selection. The following example definestwo data tables with different selection mode—the first one uses single mode and the secondone uses multiple mode.

1 <o:dataTable var="employee" value="#{bean.employees}" >2 <o:singleRowSelection rowData="#{bean.selectedEmployee"/>3 <o:column>4 <f:facet name="header">5 <h:outputText value="name"/>6 </f:facet>7 <h:outputText value="#{employee.name}" />8 </o:column>9 </o:dataTable>

10

11 <o:dataTable var="employee" value="#{bean.employees}" >12 <o:multipleRowSelection rowDatas="#{bean.selectedEmployees}"/>13 <o:column>14 <f:facet name="header">15 <h:outputText value="name"/>16 </f:facet>17 <h:outputText value="#{employee.name}" />

68

Page 76: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

18 </o:column>19 </o:dataTable>

Figure 7.10: OpenFaces data table with row selection in multiple mode and checkbox column

7.7 PrimeFaces Data Grid

PrimeFaces data grid component is very similar to standard <h:panelGrid> and <rich:dataGrid> components. It even has the same API. Simple <p:dataGrid> might be de-fined like in the following example.

1 <p:dataGrid id="dataGrid" value="#{model.capitals}" var="record"2 columns="3" rows="9" paginator="true">3 <p:panel header="#{record.state}">4 <h:outputText value="#{record.name}" />5 </p:panel>6 </p:dataGrid>

The <p:dataGrid> component provides very comparable functionality to RichFaces datagrid. PrimeFaces data grid supports pagination. However, it is implemented in differentway than in OpenFaces or RichFaces. The compononent has an attribute paginatorwhich,when set to true, will render two paginators—one above the data grid and one below. Us-ing the paginatorPosition attribute it is possible to specify where the paginator willbe displayed. The attribute accepts three values: top, bottom, and both (default). More-over, it is possible to customize paginator using so called paginator template set in attributepaginatorTemplate. This attribute accepts the following keywords:

• FirstPageLink;

• LastPageLink;

• PreviousPageLink;

69

Page 77: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

• NextPageLink;

• PageLinks;

• CurrentPageReport; and

• RowsPerPageDropDown.

To customize paginator, these keywords have to be put into curly brackets. The default tem-plate corresponds to the following string:

1 {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}

One feature that is unique for PrimeFaces data grid is ability to define effects for transi-tioning between pages of a data grid. When the attribute effect is set to true, the switchingpages will not be animated. Moreover, it is possible to define the speed of the effect usingeffectSpeed attribute (possible values are slow, normal, and fast).

Figure 7.11: PrimeFaces data grid with paginators

7.8 PrimeFaces Data List

Like RichFaces, also PrimeFaces has a component rendering a list. The way of use is prettysimilar to RichFaces list. The list can contain paginator and effect for which the same rulesapply as for paginator and effect in PrimeFaces data grid. Similarly to RichFaces, the <p:dataList> component supports three types of lists—unordered, ordered, and definitionlist. Although it is possible to use custom bullets in <rich:list> using CSS, in PrimeFacesit is made easier using the attribute itemType. There are several options for itemTypeattribute, such as disc, circle, and square for unordered lists. For ordered lists, there arethese options:

70

Page 78: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

• 1—renders a sequence of numbers;

• a—renders a sequence of lower-case characters;

• A—renders a sequence of upper-case characters; and

• i—renders a sequence of Roman numerals.

Figure 7.12: PrimeFaces ordered data list

7.9 PrimeFaces Data Table

PrimeFaces data table, while very similar to OpenFaces and RichFaces data tables, it hasone special feature. It can work in two modes: dynamic and non-dynamic. According toPrimeFaces Developer Guide [22, p. 111] when a table is non-dynamic (default) it works asa pure client side component. Dynamic data tables fetch their data from backing bean modelwith Ajax. Features including paging, sorting and filtering are both implemented on clientside and server side. For small data sets non-dynamic data tables are much faster and havethe advantage of avoiding roundtrips to server with Ajax.

Pagination in the <p:dataTable> is implemented in exactly the same way as in Prime-Faces data grid and data list components.

To make a column sortable, it is needed to define sortBy attribute. If the table is in non-dynamic mode, attribute parser has to be defined, too. This defines client-side parsers forcolumn data. Possible values are string, number and date. In the case that user needs touse custom sorting function, the attribute sortFunction has to be defined. This attributeought be bound to a method with two parameters and it should return integer.

1 public int sort(Employee e1, Employee e2) {2 // performs comparison and returns -1 if e1 < e2, 0 if e1 = e2, 1 if e1 > e23 }

If the table is in non-dynamic mode, a JavaScript function has to be provided in attributesortFunction. In the following example a and b are JavaScript objects representing row

71

Page 79: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

data, desc is a boolean value representing sorting order (true for descending) and field rep-resents column key to be used to retrieve column value.

1 sort = function(a, b, desc, field) {2 var val1 = a.getData(field);3 var val2 = b.getData(field);4 // return an integer -1, 0, or 15 }

Like RichFaces and OpenFaces, PrimeFaces table support two modes for selection of rows—single and multiple. To turn on the selection, attribute selectionMode has to be set. Inaddition to the two mentioned modes for selecting rows of table, PrimeFaces table supportalso selecting cells of a table. It is possible to select one cell or block of cells.

Filtering is implemented in PrimeFaces by using attribute filterBy bound to managedbean property that ought be used for filtering. By default, filtering is triggered by keyupevent but it is configurable using attribute filterEvent.

7.10 ICEfaces Data Table

ICEfaces contain a data table that is functionally comparable to RichFaces, OpenFaces andPrimeFaces data tables. It can be very minimalist but also its functionality can be greatlyextended when combined with the components <ice:commandSortHeader> and <ice:dataPaginator>. The <ice:commandSortHeader> component allows column basedsorting by clicking on a column header. The <ice:dataPaginator> renders a paginatorfor the attached data table. The columns of the table can be made resizable by setting theattribute resizable to true.

Basic usage is the same as with standard JSF data table or RichFaces data table:

1 <ice:dataTable id="dataTable" value="#{model.capitals}" var="record">2

3 <ice:column id="columnState">4 <f:facet name="header">State</f:facet>5 <h:outputText value="#{record.state}" />6 </ice:column>7

8 <ice:column id="columnCapital">9 <f:facet name="header">Capital</f:facet>

10 <h:outputText value="#{record.name}" />11 </ice:column>12

13 </ice:dataTable>

To make the table paginated, an <ice:dataPaginator> has to be used. If the attributepaginator is set to false, the page number links will not be rendered.

72

Page 80: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

1 <ice:dataPaginator id="dataScroller" for="dataTable" paginator="true"2 fastStep="3" paginatorMaxPages="4">3 <f:facet name="first" ><h:graphicImage ... /></f:facet>4 <f:facet name="last"><h:graphicImage .../></f:facet>5 <f:facet name="previous"><h:graphicImage .../></f:facet>6 <f:facet name="next"><h:graphicImage .../></f:facet>7 <f:facet name="fastforward"><h:graphicImage .../></f:facet>8 <f:facet name="fastrewind"><h:graphicImage .../></f:facet>9 </ice:dataPaginator>

Figure 7.13: ICEfaces data table with paginator

In order to make a column sortable, attributes sortColumn and sortAscending of datatable have to be set. Then, the <ice:commandSortHeader> component has to be put in-side the <ice:column> component. After that, sorting code in managed bean has to bewritten including a comparator for data model. For multi-column sorting the code might bevery complicated.

1 <ice:column id="columnState">2 <f:facet name="header">3 <ice:commandSortHeader columnName="state" arrow="true">4 <h:outputText id="columnHeaderState" value="State" />5 </ice:commandSortHeader>6 </f:facet>7

8 <h:outputText value="#{record.state}" />9 <f:facet name="footer">

10 <h:outputText id="columnFooterState" value="State" />11 </f:facet>12 </ice:column>

73

Page 81: Comparison of AJAX JSF Libraries Functionality and Interoperability

7. ITERATION COMPONENTS

ICEfaces data table does not provide any means for filtering column. Row selection is im-plemented using the <ice:rowSelector> component inside a column. It supports bothsingle selection and multi selection.

1 <ice:dataTable...>2 <ice:column>3 <ice:rowSelector .../>4 <f:facet name="header">5 <ice:outputText .../>6 </f:facet>7 <ice:outputText .../>8 </ice:column>9 ...

10 </ice:dataTable>

74

Page 82: Comparison of AJAX JSF Libraries Functionality and Interoperability

8 Charts

In web applications working with large amounts of data it is usually not enough to displaythem in tables or other iteration components. In such cases, charts come in handy. Rich-Faces do not include any prepared charts components. However, it is possible to reuse exist-ing Java charting libraries, such as JFreeChart, with combination of <a4j:mediaOutput>components that is suitable for displaying dynamically generated images.

Another option is to use some JavaScript library creating charts using canvas or SVG. SomeJavaScript libraries (e.g. Flotr) are also packaged as JSF components (project JSFlot). How-ever, these solution are not tested and supported with RichFaces.

8.1 Charts in PrimeFaces

PrimeFaces contains Flash-based chart components using YUI library. There these types ofcharts available:

• bar chart;

• column chart;

• line chart;

• pie chart;

• stacked bar chart; and

• stacked column chart.

It is really simple to create charts in PrimeFaces. First, a model has to be created. Pie chart inPrimeFaces require a special list-like model represented by class PieChartModel.

1 public class ChartBean {2 private PieChartModel sales;3

4 public ChartBean() {5 sales = new PieChartModel();6 sales.set("Brand 1", 540);7 sales.set("Brand 2", 325);8 sales.set("Brand 3", 702);9 sales.set("Brand 4", 367);

10 }11 ...12 }

After that, component has to be placed on a page. The model attribute should be boundto managed bean’s property with model. The component has to have width and height

75

Page 83: Comparison of AJAX JSF Libraries Functionality and Interoperability

8. CHARTS

attributes specified, otherwise nothing will be rendered on the page and a JavaScript errorwill occur.

1 <p:barChart id="barChart" model="#{chartBean.births}" width="400px"2 height="250px"/>

Figure 8.1: PrimeFaces pie chart component

All other chart components in PrimeFaces can be used with another type of model—a modelfor Cartesian data represented by class CartesianChartModel.

1 public class ChartBean {2 private CartesianChartModel births;3

4 public ChartBean() {5 births = new CartesianChartModel();6 ChartSeries birthsBoys = new ChartSeries("boys");7 birthsBoys.set("2006", 120);8 ...9

10 ChartSeries birthsGirls = new ChartSeries("girls");11 birthsGirls.set("2006", 52);12 ...13

14 births.addSeries(birthsGirls);15 births.addSeries(birthsBoys);16 }17 ...18 }

When the model is created, it is very simple to us whichever chart component:1 <p:barChart model="#{chartBean.births}" width="400px" height="250px"/>2 <p:columnChart model="#{chartBean.births}" width="400px" height="250px"/>3 <p:lineChart model="#{chartBean.births}" width="400px" height="250px"/>4 <p:stackedBarChart model="#{chartBean.births}" width="400px" height="250px"/>5 <p:stackedColumnChart model="#{chartBean.births}" width="400px"6 height="250px"/>

76

Page 84: Comparison of AJAX JSF Libraries Functionality and Interoperability

8. CHARTS

Figure 8.2: PrimeFaces bar chart

Although the PrimeFaces charts are based on Flash, they are highly customizable. Stylingis done using JavaScript because, obviously, it is not possible to use CSS. Style attributeof a chart component should contain name of a JavaScript object. The following exampledemonstrates how to set chart’s border and legend, full list of all options that can be set canbe found in PrimeFaces Developer Guide. [22, p. 63]

1 <script type="text/javascript">2 var chartStyle = {3 border : { color : red, size : 3 },4 legend : { display : "left" }5 }6 </script>7

8 <p:pieChart id="pieChart" model="#{chartBean.sales}" style="chartStyle"/>

PrimeFaces charts have built-in support for Ajax polling and live data displaying. In orderto use this feature, attribute live has to be set to true and refreshInterval attributeshould contain time how often the component should be updated (in milliseconds).

1 <p:pieChart id="pieChart" model="#{chartBean.sales}" style="chartStyle"2 live="true" refreshInterval="4000"/>

Like in RichFaces, it is possible to create static charts using JFreeChart. In such case, <p:graphicImage> component has to be used for generated image.

8.2 Charts in OpenFaces

All OpenFaces charts are based on JFreeChart library. There is support for three chart typesin OpenFaces library: pie, bar, and line charts. The API of OpenFaces charts is unified—alltypes of charts use the same tag (<o:chart>) and the same model (represented by class org.openfaces.component.chart.ChartModel). OpenFaces Developer Guide [16, sec-tion Chart] shows how to create a simple chart model:

77

Page 85: Comparison of AJAX JSF Libraries Functionality and Interoperability

8. CHARTS

1 public ChartModel getPopulation() {2 Map data = new HashMap();3 data.put("London, United Kingdom", new Integer(7615000));4 data.put("Berlin, Germany", new Integer(3396990));5 data.put("Madrid, Spain", new Integer(3155359));6 data.put("Rome, Italy", new Integer(2542003));7 data.put("Paris, France", new Integer(2142800));8

9 PlainSeries series = new PlainSeries();10 series.setData(data);11 series.setKey("Largest cities of the European Union");12

13 PlainModel model = new PlainModel();14 model.addSeries(series);15 return model;16 }

When the model is prepared, the <o:chart> component can be placed on a page likethis:

1 <o:chart model="#{oChartBean.population}" view="bar"2 titleText="Largest Cities of the European Union by Population"3 legendVisible="true" width="800"/>

The code above will render a bar chart. Pie chart and line chart can be rendered usingthe same code with just changing view attribute to pie or line. Alternatively, the type ofchart can be specified by using one of <o:pieChartView>, <o:lineChartView>, or <o:barChartView> components inside the <o:chart> component, e.g.:

1 <o:chart model="#{oChartBean.population}"2 titleText="Largest Cities of the European Union by Population"3 legendVisible="true" width="800">4 <o:lineChartView/>5 </o:chart>

Figure 8.3: OpenFaces line chart

In this case, developer has more options for customization of chart component. For instance,it is possible to turn off labels and turn on tooltip instead:

78

Page 86: Comparison of AJAX JSF Libraries Functionality and Interoperability

8. CHARTS

1 <o:chart model="#{oChartBean.population}"2 titleText="Largest Cities of the European Union by Population"3 legendVisible="true" width="800">4

5 <o:pieChartView labelsVisible="false"6 tooltip="#{sector.key} - #{sector.value}"/>7

8 </o:chart>

Figure 8.4: OpenFaces pie chart with default settings

Line and bar charts can be vertically or horizontally oriented. To specify the orientation,the orientation attribute has to be set to vertical (default) or horizontal. Charts can be alsodisplayed in 3D mode. To use this feature, attribute enable3D has to be set to true.

1 <o:chart ...>2 <o:barChartView enable3D="true"/>3 </o:chart>

Since OpenFaces charts are generated on the server side, it is not possible to use CSS forstyling. However, there are few attributes for setting visual properties of charts such asbackgroundPaint, titlePaint, showGradient, or wallColor. Much more informa-tion about styling OpenFaces charts, grid lines, labels, tooltips, context menus, etc. can befound in OpenFaces Developer Guide. [16, section Chart]

8.3 Charts in ICEfaces

Charts in ICEfaces are static and are implemented using JCharts library and thus they arevery similar to those generated with JFreeChart. ICEfaces support these types of charts:

79

Page 87: Comparison of AJAX JSF Libraries Functionality and Interoperability

8. CHARTS

• area;

• areastacked;

• bar;

• barclustered;

• barstacked;

• line;

• pie2D;

• pie3D;

• point;

• stock; and

• custom.

All these types of charts use the same underlying data model which can be for examplestandard Java list. Moreover, it is possible to define data directly on page.

To use the ICEfaces charts, it is necessary to map Faces Servlet to “/icefaces/*”, otherwisecharts will not be rendered on the page.

1 <servlet>2 <servlet-name>Faces Servlet</servlet-name>3 <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>4 <load-on-startup>1</load-on-startup>5 </servlet>6 <servlet-mapping>7 <servlet-name>Faces Servlet</servlet-name>8 <url-pattern>/icefaces/*</url-pattern>9 </servlet-mapping>

After that, it is possible to use the <ice:outputChart> component.

1 <ice:outputChart data="10, 30, 40, 33" width="300" height="300" type="pie3D"/>

Figure 8.5: ICEfaces 3D pie chart

80

Page 88: Comparison of AJAX JSF Libraries Functionality and Interoperability

8. CHARTS

When the chart type is set to custom, it is possible to create charts of mixed type.

Figure 8.6: ICEfaces custom chart mixing bar chart and line chart, picture from [14]

81

Page 89: Comparison of AJAX JSF Libraries Functionality and Interoperability

9 Validation

Validation of user’s inputs is a very important part of creating a rich internet application.Validations in JSF are performed in third phase of JSF lifecycle (called Process validations). Ifthe validation fails, the fourth and fifth phase (Update model values and Invoke application)are skipped.

9.1 Faces Validation

Tags <f:validateLongRange>, <f:validateLength>, etc. were used in JSF 1.x for val-idation. Although this approach worked well, there was a need for validating using Ajax orvalidating using Hibernate Validator which represented a general approach to validatingacross all tiers of an enterprise application. The value in the following sample would bevalidated in order to ensure that the string’s length is between 4 and 10 including.

1 <h:inputText value="#{bean.value}">2 <f:validateLength minimum="4" maximum="10"/>3 </h:inputText>

9.2 Bean Validation

Java EE 6 came with a new standard JSR-303 Bean Validation of which Red Hat is the speci-fication lead. Hibernate Validator 4.x became the reference implementation of JSR-303. JSR-303 defines a metadata model and API for JavaBean validation. The default metadata sourceis annotations, with the ability to override and extend the metadata through the use of XMLvalidation descriptors. The API is not tied to a specific application tier or programmingmodel. It is specifically not tied to either the web tier or the persistence tier, and is availablefor both server-side application programming, as well as rich client application developer.The sample from previous section can be rewritten like in the following sample. The mostnoticeable change is the usage of an annotation @Size instead of <f:validateLength>tag. Otherwise, the two samples are equivalent. Although JSF validation tags are supportedin JSF 2, it is recommended to use Bean validation.

1 @ManagedBean2 public class Bean {3 private String value;4

5 @Size(min = 4, max = 10)6 public String getValue() {7 return value;8 }9 ...

82

Page 90: Comparison of AJAX JSF Libraries Functionality and Interoperability

9. VALIDATION

10 }

1 <h:inputText value="#{bean.value}"/>

9.3 Client Side Validation

The added value of JSF component libraries is support for client side validation. FiringHTML or Ajax request for each input in a form might overload the server. However, whenthe inputs are first validated on client and after that they are sent to the server, the loadand traffic is much lower. To use client-side validation in RichFaces, the behavior <rich:validator> has to be attached to validated input. The former example rewritten using theclient-side validation would be very similar:

1 @ManagedBean2 public class Bean {3 private String value;4

5 @Size(min = 4, max = 10)6 public String getValue() {7 return value;8 }9 ...

10 }

1 <h:inputText value="#{bean.value}">2 <rich:validator event="keyup"/>3 </h:inputText>

Although the last two examples are very similar, there is a huge difference in functionality.In the later example, a JavaScript validation would be executed. If no client-side valida-tion method exists for a registered server-side validator, Ajax fallback is used. The <rich:validator> behavior invokes all available client-side validators. If all the client-side val-idators return valid, RichFaces performs an Ajax request to invoke the remaining validatorson the server side. [15, section Validation]

In OpenFaces, there is also a feature called client-side validation. However, it does not workfor fields annotated with Bean validation annotations, only for field with attached JSF val-idator tags. To enable the feature, a context parameter has to be set in web.xml:

1 <context-param>2 <param-name>org.openfaces.validation.clientValidation</param-name>3 <param-value>onSubmit</param-value>4 </context-param>

When the context parameter is set, every input field with attached JSF validator tag is vali-dated on the client before the form is submitted. It is possible to set validation not only for

83

Page 91: Comparison of AJAX JSF Libraries Functionality and Interoperability

9. VALIDATION

whole application but also for a form or even for an individual component. Single compo-nent can be validated with following code:

1 <h:inputText required="true" onchange="O$.validate(this);"/>

Particular form will be validated if <o:clientValidationSupport> component is at-tached to the form.

1 <h:form>2 <o:clientValidationSupport clientValidation="onSubmit"3 useDefaultClientValidationPresentation="true"4 useDefaultServerValidationPresentation="true"/>5

6 ...7 <h:inputText value="#{bean.value}">8 <f:validateDoubleRange minimum="4"/>9 </h:inputText>

10 ...11 </h:form>

There is no support for client-side validation in PrimeFaces nor ICEfaces. However it ispossible to validate fields with Ajax in ICEfaces using the attribute partialSubmit set totrue.

9.4 Cross-field Validation

RichFaces contain the <rich:graphValidator> component which is used to wrap a setof input components related to one object. The object defined by the component <rich:graphValidator> can then be completely validated. The validation includes all objectproperties, even those which are not bound to the individual form components. Valida-tion performed in this way allows for cross-field validation in complex forms. [15, sectionrich:graphValidator object validation] Internally, RichFaces clone validated object in orderto interrupt lifecycle correctly after the Process validations phase.

1 <rich:graphValidator value="#{bean}" id="gv">2 <h:outputText value="Enter new password:" />3 <h:inputSecret value="#{bean.password}" id="pass" />4 <br/><br/>5 <h:outputText value="Confirm the new password:" />6 <h:inputSecret value="#{bean.confirm}" id="conf" />7 <a4j:commandButton value="Store changes" action="#{bean.storeNewPassword}"

/>8 </rich:graphValidator>

1 @ManagedBean2 @SessionScoped3 public class Bean implements Cloneable, Serializable{4 @Size(min = 5, max = 15, message = "Wrong size for password")

84

Page 92: Comparison of AJAX JSF Libraries Functionality and Interoperability

9. VALIDATION

5 private String password="";6 @Size(min = 5, max = 15, message = "Wrong size for confirmation")7 private String confirm="";8

9 @AssertTrue(message = "Different passwords entered!")10 public boolean isPasswordsEquals() {11 return password.equals(confirm);12 }13

14 public void storeNewPassword() {15 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(

FacesMessage.SEVERITY_INFO, "Succesfully changed!", "Succesfullychanged!"));

16 }17

18 @Override19 public Object clone() throws CloneNotSupportedException {20 return super.clone();21 }22

23 // getters and setters omitted24 }

The next specification of JSF will probably contain some support for cross-field valida-tion.

9.5 Messages

The <h:message> and <h:messages> are standard JSF components for displaying mes-sages. The <h:message> component displays only one message for a particular componentwhile <h:messages> display all messages that occured. Although both of these compo-nents work fine for HTTP requests, a placeholder is needed when the validation is per-formed using Ajax requests. This is related to the fact that with Ajax it is much easier toreplace elements in DOM than create them. To work around this drawback, JSF componentlibraries implement their own messages.

The <rich:message> component displays one message for one component specified infor attribute. Unlike standard <h:message> component, RichFaces message contains alsoan icon and is highly customizable. Analogically, the <rich:messages> component willdisplay all messages for all components.

1 <h:outputText value="Age:" />2 <h:inputText label="Age" id="age" required="true" value="#{userBean.age}">3 <f:validateLength minimum="1" maximum="10" />4 </h:inputText>5 <rich:message for="age" ajaxRendered="true"/>

85

Page 93: Comparison of AJAX JSF Libraries Functionality and Interoperability

9. VALIDATION

Figure 9.1: RichFaces message

PrimeFaces contain a component called <p:growl>, inspired by Mac’s growl component.Growl is a replacement for <h:messages> and thus it is very simple to use it. By defaulteach message is hidden after six seconds. However, it is possible to cancel this behaviorby setting attribute sticky to true. It is also possible to change the duration of displayinggrowl. This can be done using attribute life (in milliseconds).

Figure 9.2: PrimeFaces growl component with three messages

OpenFaces displays an image over an invalid component and applies a CSS style to it. Thiskind of error messaging does not affect the page layout and, therefore, can be used as defaultvalidation error presentation.

Figure 9.3: Standard styling of input after validation error in OpenFaces

In order to customize validation output, it is possible to use <o:floatingIconMessage>component.

1 <h:inputText id="requiredInput" required="true"/>2 <o:floatingIconMessage for="requiredInput" style="border: 2px solid red;"/>

9.6 Captcha

PrimeFaces contain a captcha component based on reCAPTCHA—a popular online anti-bot service that helps digitalize books. There are four themes and it is possible to select

86

Page 94: Comparison of AJAX JSF Libraries Functionality and Interoperability

9. VALIDATION

component’s language as well. To use the component, user needs to generate a key pair onreCAPTCHA web site.1 Then keys have to be set in web.xml:

1 <context-param>2 <param-name>primefaces.PRIVATE_CAPTCHA_KEY</param-name>3 <param-value>...</param-value>4 </context-param>5 <context-param>6 <param-name>primefaces.PUBLIC_CAPTCHA_KEY</param-name>7 <param-value>...</param-value>8 </context-param>

When keys are set, the component can be placed on a web page. When a user types in awrong string, a validation message will be displayed.

1 <p:captcha id="captcha" value="#{bean.value}"/>

Figure 9.4: PrimeFaces captcha

1. reCAPTCHA home page, http://www.google.com/recaptcha

87

Page 95: Comparison of AJAX JSF Libraries Functionality and Interoperability

10 Conclusion

The first objective of this thesis was to compare three open source JSF component libraries,namely PrimeFaces, OpenFaces and ICEfaces with RichFaces. The second objective was toimplement a sample application that would demonstrate the use of all components men-tioned in this work.

Regarding functionality, all of these four component libraries are very comparable. How-ever, it was not possible to make a one-to-one comparison of all components because be-cause some components do not have their counterparts in other libraries. The author triedto make a per-component comparison where it was possible. Where it was not possible (e.g.chapter Panels).

In the past, there were many problems in interoperability of JSF component libraries, e.g.PrimeFaces and OpenFaces did not work together until November 2010.1 Since both Rich-Faces and PrimeFaces use jQuery JavaScript library, there used to be also problems in inter-operability of these two.2 Author suggests RichFaces to use jQuery in no-conflict mode inorder to avoid future problems with multiple versions of jQuery. In general, nowadays allfour work quite well. The author performed some smoke tests for interoperability betweencomponents. The majority of bugs can be fixed by just adjusting CSS styles.

PrimeFaces is a lightweight library which has pros and cons. On one hand it is extremelyeasy to learn and use but, on the other hand, it brings some disadvantages. For example,some PrimeFaces components still use old approach to Ajax (designed for PrimeFaces 1.x)and therefore it is not possible to attach <f:ajax> to them (e.g. <p:colorPicker>). An-other consequence is that RichFaces status component cannot show the status of PrimeFacesrequests. At the moment, PrimeFaces are the only popular JSF 2 component library that hassupport for mobile devices. They are working towards even better support for mobile de-vices in PrimeFaces 3. PrimeFaces use jQuery ThemeRoller for skinning. It is possible togenerate a skin in ThemeRoller’s theme generator and then easily to use it in a JSF appli-cation. There are even some skins that are very similar to those from RichFaces. RichFacesshould consider using ThemeRoller which would make creation of new skins very easy.Also, RichFaces are missing easy-to-use chart components.

OpenFaces are full-featured JSF component library. However, there are some basic compo-nents missing, e.g. slider or poll. According to author of this thesis, OpenFaces’ best com-ponent is their data table which is very simple to use. RichFaces could inspire by that. Onthe other hand, OpenFaces require nested components to define ID in some cases, e.g. pagi-nator in data table. RichFaces team should evaluate the possibility of automatic handling ofexpired session which is quite common situation in JSF applications. Although OpenFaces

1. PrimeFaces and OpenFaces interoperability, http://cagataycivici.wordpress.com/2010/11/08/primefaces-with-openfaces-for-jsf-2-02. PrimeFaces and RichFaces interoperability, http://community.jboss.org/thread/161794

88

Page 96: Comparison of AJAX JSF Libraries Functionality and Interoperability

10. CONCLUSION

work well with RichFaces, the user has to be aware of the fact that OpenFaces do not supportMyFaces.

ICEfaces are an advanced library with theirs Automatic Ajax and Direct-to-DOM features.It contains a lot of component, however, not all are freely available. The most componentsare ported from ICEfaces 1.8. ICEfaces contains all important components. There is missingclient mode in togglable panels which is a feature used in RichFaces quite often. ICEfacesis the only library from these four which focuses on accessibility. It is possible to turn onAccessible Rich Internet Applications (ARIA) mode which adds accessibility features to ap-plication.3

All four component libraries use standard JSF mechanism for internationalization and lo-calization. The best sample is calendar component where it is possible to customize compo-nent’s language, the first day of the week, the first day of a year, etc.

There is outstanding documentation for all compared libraries. PrimeFaces User’s Guide ispaid in version 2, however, it should be free again in version 3 of PrimeFaces. Since all com-ponent libraries provide taglibs, there is no problem with code completion in most popularIDEs. Although RichFaces provides taglib, tags are auto-completed in IDEs but tags are notdocumented.

The second objective of this work was to implement a sample application using all fourcomponent libraries. Metamer is testing application and test suite which covers all of Rich-Faces 4 components and it is able to display them in different skins and also different com-ponent containers called templates—table, panel, etc. Since the application already containsall RichFaces 4 components and is easy to expand, it was chosen to demonstrate interop-erability of RichFaces with all compared libraries. Appendix C contains a screenshot fromMetamer.

For each component, there is a directory containing all associated samples. For example, inrichCalendar directory, there is a simple calendar for testing majority of attributes of theRichFaces calendar and then several pages for testing advanced features such as validation,custom models, etc.

The application is stored in a git repository on Github.4 There are several branches cre-ated:

• master—copy of original Metamer used by RichFaces team;

• primefaces—demonstrates interoperability of RichFaces and PrimeFaces;

• openfaces—demonstrates interoperability of RichFaces and OpenFaces; and

• icefaces—demonstrates interoperability of RichFaces and ICEfaces.

3. ARIA in ICEfaces, http://wiki.icefaces.org/display/ICE/Configuration4. Metamer Git repository, https://github.com/ppitonak/metamer

89

Page 97: Comparison of AJAX JSF Libraries Functionality and Interoperability

10. CONCLUSION

RichFaces team will migrate to Git soon and after that there is a plan to merge primefaces,openfaces, and icefaces branches with upstream project. RichFaces team will prepare betterthird-party integration tests based on the results of this thesis.

90

Page 98: Comparison of AJAX JSF Libraries Functionality and Interoperability

Bibliography

[1] Wikipedia, The Free Encyclopedia: Rich Internet application [online]. April 30,2011 [cited May 1, 2011]. Available at: <http://en.wikipedia.org/wiki/Rich_Internet_application>.

[2] W3C Homepage [online]. February 14, 2011 [cited April 13, 2011]. Available at: <http://www.w3.org/News/2011.html#entry-9015>.

[3] Wikipedia, The Free Encyclopedia: Model-view-controller [online]. April 27,2011 [cited April 29, 2011]. Available at: <http://en.wikipedia.org/wiki/Model-view-controller>.

[4] BURBECK, Steve. Application Programming in Smalltalk-80: How to use Model-View-Controller (MVC) [online]. 1992 [cited April 28, 2011]. Available at: <http://st-www.cs.illinois.edu/users/smarch/st-docs/mvc.html>.

[5] BURNS, Ed; GRIFFIN, Neil; SCHALK, Chris. JavaServer Faces 2.0: The Complete Ref-erence. First printing. United States of America: McGraw Hill Professional, 2009. 752 p.ISBN 978-0-07-162509-8.

[6] MANN, Kito D. JavaServer Faces in Action. First printing. Greenwich (Connecticut):Manning Publications Co., 2005. 744 p. ISBN 978-1-93-239412-2.

[7] JENDROCK, Eric; EVANS Ian; GOLLAPUDI, Devika; HAASE, Kim; SRIVATHSA, Chin-mayee. The Java EE 6 Tutorial [online]. March 2011 [cited April 28, 2011]. Available at:<http://download.oracle.com/javaee/6/tutorial/doc/>.

[8] SCHWARTZ, Andy. What’s New in JSF 2? [online]. July 31, 2009 [cited April20, 2011]. Available at: <http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2>.

[9] WADIA, Zubin; MARINSCHEK, Martin; SALEH, Hazem; BYRNE, Dennis. The Defini-tive Guide to Apache MyFaces and Facelets. First printing. United States of America:Apress, 2008. 640 p. ISBN 978-1-59-059737-8.

[10] ARANDA, Bruno; WADIA, Zubin. Facelets Essentials: Guide to JavaServer Faces ViewDefinition Framework. First printing. United States of America: Apress, 2008. 88 p. ISBN978-1-43-021049-8.

[11] SMIRNOV, Alexander. RichFaces CDK: how to create JSF component [online]. April 6,2011 [cited April 12, 2011]. Available at: <http://alexsmirnov.wordpress.com/2011/04/06/richfaces-cdk-how-to-create-jsf-component/>.

[12] ICEfaces 2.0.1 Release Notes [online]. March 30, 2011 [cited April 12, 2011].

91

Page 99: Comparison of AJAX JSF Libraries Functionality and Interoperability

10. CONCLUSION

Available at: <http://wiki.icefaces.org/display/ICE/ICEfaces+2.0.1+Release+Notes>.

[13] KATZ, Max. What RichFaces a4j:ajax adds on top JSF 2 f:ajax tag [online]. August 19,2010 [cited April 14, 2011]. Available at: <http://mkblog.exadel.com/2010/08/what-richfaces-a4jajax-adds-on-top-jsf-2-fajax-tag/>.

[14] ICEfaces wiki [online]. October 29, 2010 [cited April 15, 2011]. Available at: <http://wiki.icefaces.org/display/ICE/ICEfaces+2>.

[15] RichFaces: Component Reference [online]. April 6, 2011 [cited April 15, 2011]. Avail-able at: <http://docs.jboss.org/richfaces/nightly_4_0_X/Component_Reference/en-US/html_single/>.

[16] OpenFaces: Developer’s Guide [online]. November 4, 2010 [cited April 15, 2011]. Avail-able at: <http://www.openfaces.org/documentation/developersGuide/index.html>.

[17] CRANE, Dave; MCCARTHY, Phil. Comet and Reverse Ajax: The Next-Generation Ajax2.0. First printing. United States of America: Apress, 2008. 256 p. ISBN 978-1-59-059998-3.

[18] GRAVELLE, Rob. Comet Programming: Using Ajax to Simulate Server Push [online].March 6, 2009 [cited April 17, 2011]. Available at: <http://www.webreference.com/programming/javascript/rg28/>.

[19] WebSocket disabled in Firefox 4 [online]. December 8, 2010 [citedApril 17, 2011]. Available at: <http://hacks.mozilla.org/2010/12/websockets-disabled-in-firefox-4/>.

[20] Opera News: Regarding WebSocket [online]. December 10, 2010 [cited April 17,2011]. Available at: <http://my.opera.com/chooseopera/blog/2010/12/10/regarding-websocket>.

[21] BARTH, Adam. Experiment comparing Upgrade and CONNECT handshakes [online].November 26, 2010 [cited April 17, 2011]. Available at: <http://www.ietf.org/mail-archive/web/hybi/current/msg04744.html>.

[22] CIVICI, Cagatay; DARCIN, Yigit. PrimeFaces User’s Guide [paid documentation]. July26, 2010 [cited April 13, 2011].

92

Page 100: Comparison of AJAX JSF Libraries Functionality and Interoperability

A Sample Use of RichFaces Sub Table

1 <rich:dataTable id="richDataTable" value="#{richSubTableBean.lists}"2 var="list" keepSaved="true">3

4 <f:facet name="header">5 <rich:columnGroup id="columnGroup">6 <rich:column id="columnHeaderEmployees" colspan="3">7 <h:outputText id="columnHeaderEmployeesText" value="Employees" />8 </rich:column>9 <rich:column id="columnHeaderName" breakRowBefore="true">

10 <h:outputText id="columnHeaderNameText" value="Name" />11 </rich:column>12 <rich:column id="columnHeaderTitle">13 <h:outputText id="columnHeaderTitleText" value="Title" />14 </rich:column>15 <rich:column id="columnHeaderBirthdate">16 <h:outputText id="columnHeaderBirthdateText" value="Birthdate" />17 </rich:column>18 </rich:columnGroup>19 </f:facet>20

21 <rich:column id="columnSubTable" colspan="3">22 <rich:collapsibleSubTableToggler id="subTableTC" for="richSubTable"/>23 <h:outputText value="#{list[0].sex == ’MALE’ ? ’Men’ : ’Women’}" />24 </rich:column>25

26 <rich:collapsibleSubTable id="richSubTable" rows="5"27 value="#{richSubTableBean.state ? list : null}" var="item">28

29 <rich:column id="columnName">30 <h:outputText id="name" value="#{item.name}" />31 </rich:column>32 <rich:column id="columnTitle">33 <h:outputText id="title" value="#{item.title}" />34 </rich:column>35 <rich:column id="columnBirthdate">36 <h:outputText id="birthdate" value="#{item.birthdate}">37 <f:convertDateTime pattern="d MMM yyyy"/>38 </h:outputText>39 </rich:column>40

41 </rich:collapsibleSubTable>

93

Page 101: Comparison of AJAX JSF Libraries Functionality and Interoperability

B Sample Use of Sorting in RichFaces Table

1 <rich:dataTable value="#{dataTableScrollerBean.allCars}"2 var="category" rows="20" id="table" reRender="ds2"3 sortPriority="#{sortingBean.prioritList}">4

5 <rich:column id="make" sortBy="#{category.make}"6 sortOrder="#{sortingBean.makeDirection}">7 <f:facet name="header">8 <h:outputText styleClass="headerText" value="Make" />9 </f:facet>

10 <h:outputText value="#{category.make}" />11 </rich:column>12

13 <rich:column id="model" sortBy="#{category.model}"14 sortOrder="#{sortingBean.modelDirection}">15 <f:facet name="header">16 <h:outputText styleClass="headerText" value="Model" />17 </f:facet>18 <h:outputText value="#{category.model}" />19 </rich:column>20

21 <rich:column id="price" sortBy="#{category.price}"22 sortOrder="#{sortingBean.priceDirection}">23 <f:facet name="header">24 <h:outputText styleClass="headerText" value="Price" />25 </f:facet>26 <h:outputText value="#{category.price}" />27 </rich:column>28

29 <rich:column id="mileage" sortBy="#{category.mileage}"30 sortOrder="#{sortingBean.mileageDirection}">31 <f:facet name="header">32 <h:outputText styleClass="headerText" value="Mileage" />33 </f:facet>34 <h:outputText value="#{category.mileage}" />35 </rich:column>36

37 </rich:dataTable>

94

Page 102: Comparison of AJAX JSF Libraries Functionality and Interoperability

C Metamer Screenshot

95

Page 103: Comparison of AJAX JSF Libraries Functionality and Interoperability

D Contents of Attached CD

The attached CD contains the following items:

• source codes of the testing application Metamer;

• a PDF version of the thesis; and

• a LATEXsource file of the thesis.

96