Getting Started with ICEfaces 3

compared with
Current by Ken Fyten
on Apr 13, 2012 11:24.


 
Key
These lines were removed. This word was removed.
These lines were added. This word was added.

View page history


There are 47 changes. View first change.

 h1. Getting Started with ICEfaces 2
  h1. Getting Started with ICEfaces 3
  
ICEfaces 2.0 is the new version of the ICEfaces framework that integrates with JavaServer Faces (JSF) 2.0. With ICEfaces 2.0, our goal is to deliver the highest value existing ICEfaces features, as well as important new enhancements, cleanly integrated into the JSF 2.0 platform. There are a number of ways to take advantage of ICEfaces 2 in your JSF 2 application:
  ICEfaces 3 is the new version of the ICEfaces framework that integrates with JavaServer Faces (JSF) 2. With ICEfaces 3, our goal is to deliver the highest value existing ICEfaces features, as well as important new enhancements, cleanly integrated into the JSF 2 platform. There are a number of ways to take advantage of ICEfaces 3 in your JSF 2 application:
  
First, add the icefaces.jar to your project. This immediately allows you to take advantage of Direct-to-DOM (D2D) rendering technology. D2D only sends browser DOM changes from the server to the browser, minimizing bandwidth consumption without the need to specify the new "f:ajax" component in your pages. Once the icefaces.jar is added to your project, you can also take advantage of ICEfaces Window Scope and Single Submit features.
  First, add the icefaces.jar to your project. This immediately allows you to take advantage of [Direct-to-DOM|Direct-to-DOM Rendering] (D2D) rendering technology. D2D only sends browser DOM changes from the server to the browser, minimizing bandwidth consumption without the need to specify the new "f:ajax" component in your pages. Once the icefaces.jar is added to your project, you can also take advantage of ICEfaces Window Scope and Single Submit features.
  
 After adding the icefaces.jar to your project, you can start adding components:
  
* The "ICEfaces Advanced Components" are next-generation ICEfaces components. They are based on the all-new Advanced Component Environment (ACE) component development platform which implements a consistent approach to component authoring, meta-data management, and automates common component development tasks and optimizations.
  * The [ACE Components] (ICEfaces Advanced Components) are the next-generation of open source ICEfaces components. Currently featuring over 40 components including the industry-leading ace:dataTable, the ACE Components utilize a blend of server-side and client-based rendering techniques to provide a rich, responsive user-experience with reduced network and server-processing requirements.
  
* ICEfaces 2 provides a compatible component library based on the ICEfaces 1.x component suite. This set of components are referred to as "ICEfaces Components" and immediately allow developers to build ICEfaces 2 applications with a mature AJAX component suite.
  * The [ICE Components] (ICEfaces Components) are based on the original ICEfaces Component Suite in ICEfaces 1.x. The components have been updated to support JSF 2 and more recent versions of ICEfaces. The ICE Components are a complete set of mature JSF components that have benefited from thousands of successful project deployments since their inception. The ICE components are primarily implemented using traditional JSF server-side rendering techniques with limited JavaScript. When combined with ICEfaces automatic-Ajax technology, the ICE Components exhibit extensive partial-page-rendering, providing a rich, dynamic user-experience, even on older legacy browsers.
  
Finally, you may want to take advantage of asynchronous server-initiated updates using ICEpush. ICEpush draws on years of expertise with Ajax Push in ICEfaces/JSF and gives applications the power of real-time, web-based collaboration.
  
  Finally, you may want to take advantage of asynchronous server-initiated updates using [AJAX Push|Ajax Push - Overview]. Adding icepush.jar to your application enables Ajax Push, and allows you to add collaborative capabilities that will revolutionize your application.
 ----
 \\
{panel}This tutorial will discuss the following topics related to ICEfaces 2:
  {panel}This tutorial will discuss the following topics related to ICEfaces 3:
  
* [Adding ICEfaces 2 to a JSF 2 Project|#adding]
  * [Adding ICEfaces 3 to a JSF 2 Project|#adding]
 ** [Direct-to-DOM (D2D) Rendering|#D2D]
 ** [Single Submit|#singlesubmit]
 ** [Window Scope|#window]
 * [Adding ICEfaces ACE Components|#ace]
* [Adding ICEfaces Components|#components]
 * [Adding ICEpush|#icepush]
  * [Adding ICEfaces ICE Components|#components]
 * [Adding AJAX Push|#icepush]
 * [Tutorial Source Code Download|#download]
{panel}
 \\
  {panel}\\
 ----
h3. {anchor:adding}Adding ICEfaces 3 to a JSF 2 Project
  
h3. {anchor:adding}Adding ICEfaces to a JSF 2 Project
 \\
 
 h5. {anchor:D2D}Direct-to-DOM Rendering
  
 This tutorial makes use of a JSF 2 application. The application consists of a page to add a new Job Applicant:
  
 !addapplicant.png!
  
 And a page that displays the applicants:
  
 !applicantlist.png!
  
 The clear button in job-applicant.xhtml consists of the following markup:
  
{code:xml}
 <h:commandButton id="clearButton" value="Clear">
  <f:ajax event="click" render="@form" listener="#{applicantController.clearForm}" immediate="true" />
  {code:xml}<h:commandButton id="clearButton" value="Clear">
  <f:ajax event="click"
 render="@form"
  listener="#{applicantController.clearForm}"
  immediate="true" />
 </h:commandButton>
 {code}
Here we see the use of stock JSF tags including the new (as of JSF 2) f:ajax tag. The _render="@form"_ attribute on the f:ajax tag informs JSF that only the form should be rendered after the lifecycle is executed.
  
Here we see the use of stock JSF tags including the new f:ajax tag. The _render="@form"_ attribute on the f:ajax tag informs JSF that only the form should be rendered after the lifecycle is executed.
  
 Pressing the "Clear" button under these circumstances will generate the following response, which includes the entire form:
  
 {code:xml}
<?xml version="1.0" encoding="utf-8"?>
 <partial-response><changes><update id="form"><![CDATA[
 <form id="form" name="form" method="post" action="/jobApplication/job-applicant.jsf"
  enctype="application/x-www-form-urlencoded">
 <input type="hidden" name="form" value="form" />
 <div class="header">
  <img src="/jobApplication/javax.faces.resource/icefaces.png.jsf?ln=images" alt="" /></div>
 <div class="content">
 <div class="menu">
  <input type="button" onclick="window.location.href='/jobApplication/applicants.jsf'; return false;"
  value="Listing Page" />
 </div>
 <div class="contentBody">
  <div id="form:table" style="background-color:;">
  <table>
  <tr>
  <td><label for="form:title">Title</label></td>
  <td>
  <table id="form:title">
  <tr>
  <td>
  <input type="radio" name="form:title" id="form:title:0" value="1" />
  <label for="form:title:0"> Dr.</label>
  </td>
  <td>
  <input type="radio" name="form:title" id="form:title:1" value="2" />
  <label for="form:title:1"> Ms.</label>
  </td>
  <td>
  <input type="radio" name="form:title" id="form:title:2" value="3" />
  <label for="form:title:2"> Mrs.</label>
  </td>
  <td>
  <input type="radio" name="form:title" id="form:title:3" value="4" />
  <label for="form:title:3"> Miss</label>
  </td>
  <td>
  <input type="radio" name="form:title" id="form:title:4" value="5" />
  <label for="form:title:4"> Mr.</label>
  </td>
  </tr>
  </table>
  </td>
  <td></td>
  </tr>
  <tr>
  <td>
  <label for="form:firstName:input" style="float:left;">First Name</label>
  </td>
  <td>
  <input id="form:firstName:input" type="text" name="form:firstName:input" value=""
  style="float:left;" />
  </td>
  <td>
  <span id="form:firstName:msg"></span>
  </td>
  </tr>
  <tr>
  <td>
  <label for="form:lastName:input" style="float:left;">Last Name</label>
  </td>
  <td>
  <input id="form:lastName:input" type="text" name="form:lastName:input" value=""
  style="float:left;" />
  </td>
  <td>
  <span id="form:lastName:msg"></span>
  </td>
  </tr>
  <tr>
  <td>
  <label for="form:email:input" style="float:left;">Email </label>
  </td>
  <td>
  <input id="form:email:input" type="text" name="form:email:input" value=""
  style="float:left;" onblur="mojarra.ab(this,event,'blur',0,'form:email:msg')" />
  </td>
  <td>
  <span id="form:email:msg"></span>
  </td>
  </tr>
  <tr>
  <td>
  <input type="submit" name="form:j_idt50" value="Submit Applicant" />
  </td>
  <td>
  <input id="form:clearButton" type="submit" name="form:clearButton" value="Clear"
  onclick="mojarra.ab(this,event,'click',0,'@form');return false" />
  </td>
  <td>
  <input id="form:cancelButton" type="submit" name="form:cancelButton" value="Cancel" />
  </td>
  </tr>
  </table>
  <?xml version='1.0' encoding='UTF-8'?>
 <partial-response>
 <changes>
 <update id="form">
 <![CDATA[<form id="form"
 name="form"
  method="post"
  action="/gettingStarted/job-applicant.jsf"
  enctype="application/x-www-form-urlencoded">
  <input type="hidden" name="form" value="form" />
  <div class="header">
  <img src="/gettingStarted/javax.faces.resource/icefaces.png.jsf?ln=images" alt="" />
  </div>
</div>
 <div style="clear:both;"></div>
 </div>
 </form>]]></update>
 <update id="javax.faces.ViewState">
 <![CDATA[6613003036389132071:131205412038135456]]>
 </update></changes></partial-response>
 {code}
   <div class="content">
  <div class="menu">
  <input type="button"
  onclick="window.location.href='/gettingStarted/applicants.jsf'; return false;"
  value="Listing Page" />
  </div>
  <div class="contentBody">
  <div id="form:table">
  <table>
  <tr>
  <td>
  <label for="form:title">Title</label>
  </td>
  <td>
  <table id="form:title">
  <tr>
  <td>
  <input type="radio" name="form:title" id="form:title:0" value="1" />
  <label for="form:title:0"> Dr.</label>
  </td>
  <td>
  <input type="radio" name="form:title" id="form:title:1" value="2" />
  <label for="form:title:1"> Ms.</label>
  </td>
  <td>
  <input type="radio" name="form:title" id="form:title:2" value="3" />
  <label for="form:title:2"> Mrs.</label>
  </td>
  <td>
  <input type="radio" name="form:title" id="form:title:3" value="4" />
  <label for="form:title:3"> Miss</label>
  </td>
  <td>
  <input type="radio" name="form:title" id="form:title:4" value="5" />
  <label for="form:title:4"> Mr.</label>
  </td>
  </tr>
  </table>
  </td>
  <td>
  </td>
  </tr>
  <tr>
  <td>
  <label for="form:firstName">First Name</label>
  </td>
  <td>
  <input id="form:firstName" type="text" name="form:firstName" value="" />
  </td>
  <td>
  </td>
  </tr>
  <tr>
  <td>
  <label for="form:lastName">Last Name</label>
  </td>
  <td>
  <input id="form:lastName" type="text" name="form:lastName" value="" />
  </td>
  <td>
  </td>
  </tr>
  <tr>
  <td>
  <label for="form:email">Email</label>
  </td>
  <td>
  <input id="form:email" type="text" name="form:email" value="" />
  </td>
  <td>
  </td>
  </tr>
  <tr>
  <td>
  <input type="submit" name="form:j_idt49" value="Submit Applicant" />
  </td>
  <td>
  <input id="form:clearButton"
  type="submit"
  name="form:clearButton"
  value="Clear"
  onclick="mojarra.ab(this,event,'click',0,'@form');return false" />
  </td>
  <td>
  <input id="form:cancelButton"
  type="submit"
  name="form:cancelButton"
  value="Cancel" />
  </td>
  </tr>
  </table>
  </div>
  </div>
  <div style="clear:both;"></div>
  </div>
 </form>]]>
 </update>
 <update id="javax.faces.ViewState"><![CDATA[1247154892383314770:-4900614983041719481]]></update>
 </changes>
 </partial-response>
 {code}
 ICEfaces renders component markup to a server-side DOM (Document Object Model) that reflects the current client view. Each time the JSF lifecycle runs a DOM comparison is done and, if there are any changes, a concise set of page updates are sent back to the client to be applied to the page. We call this Direct-to-DOM or D2D rendering.
  
ICEfaces 2.0 renders component markup to a server-side DOM (Document Object Model) that reflects the current client view. Each time the JSF lifecycle runs a DOM comparison is done and, if there are any changes, a concise set of page updates are sent back to the client to be applied to the page. We call this Direct-to-DOM or D2D rendering.
  Adding the ICEfaces 3 library to an existing JSF 2 application will provide dynamic partial-page-updates for all compliant components, without the need to specify the "f:ajax" component in your pages.
  
Adding the ICEfaces 2.0 library to an existing JSF 2.0 application will provide dynamic partial-page-updates for all compliant components, without the need to specify the "f:ajax" component in your pages.
  Make the following change to the "Clear" button as we will no longer need the f:ajax tag (the clearForm method parameter will have to be changed from an AjaxBehaviorEvent to an ActionEvent):
  
Simply add the icefaces.jar to the application and you will have Direct-to-Dom (D2D) rendering applied to the page. Now, when we press the "Clear" button, we get the following response which only updates two hidden fields:
  {code:xml}<h:commandButton id="clearButton"
  value="Clear"
  actionListener="#{applicantController.clearForm}"
  immediate="true" />
 {code}
  
Now, simply add the *icefaces.jar* to the application and we have Direct-to-Dom (D2D) rendering applied to the page. When we press the "Clear" button this time, we get the following response:
  
 {code:xml}
<?xml version="1.0" encoding="utf-8"?>
 <partial-response><changes><update id="v3wbj72"><![CDATA[
 <form action="/jobApplication/job-applicant.jsf" id="v3wbj72" method="post" name="v3wbj72">
  <input name="v3wbj72" type="hidden" value="v3wbj72" />
  <input autocomplete="off" id="javax.faces.ViewState" name="javax.faces.ViewState" type="hidden"
  value="-6647367167940831220:-1927413051417630450" />
 </form>]]>
 </update>
 <update id="javax.faces.ViewState">
 <![CDATA[-6647367167940831220:-1927413051417630450]]>
 </update><eval><![CDATA[ice.applyFocus('form:clearButton');]]></eval></changes></partial-response>
  <?xml version='1.0' encoding='UTF-8'?>
 <partial-response>
  <changes>
  <update id="javax.faces.ViewState"><![CDATA[1197926691644194967:-7719694313423626628]]></update>
  <eval><![CDATA[ice.applyFocus('form:clearButton');]]></eval>
  </changes>
 </partial-response>
 {code}
Notice the difference in the amount of markup sent back in the response - and this is for a small form with only four fields. Direct-to-DOM rendering is powerful stuff. The beauty is that from a developer point of view, it takes place automatically under the covers. This is what we call [Automatic Ajax]. The AJAX is built in to the framework and you do not have to concern yourself with how updates are applied, Direct-to-DOM rendering takes care of it for you.
  
# A list of String data
 # A list of arbitrarily complex child components
  h5. {anchor:singlesubmit}Single Submit
  
The following code sample shows an implementation using a list of String data:
  The [Single Submit] feature is basically the ability to specify that one component will execute in the JSF lifecycle. ICEfaces 3 Single Submit is similar in intent to ICEfaces Partial Submit, but is an improvement which leverages JSF 2 expanded capabilities.
  
{code:xml}
 <ice:selectInputText rows="10" width="300" valueChangeListener="#{autoCompleteBean.updateList}">
  <f:selectItems value="#{autoCompleteBean.list}"/>
 </ice:selectInputText>
  The <icecore:singleSubmit> tag is a convenient and easy way to Single Submit enable standard h: components, without having to litter the page with <f:ajax> tags. It allows an entire page region to be enabled at once.
  
 Simply add the icecore namespace to your page. In job-applicant.xhtml add the following:
  
 {code:xml}xmlns:icecore="http://www.icefaces.org/icefaces/core"
 {code}
  
This will display a drop-down list of cities that match the text input. The 'rows' attribute defines how many results will be returned when text is entered. The 'width' attribute sets the width of the input text box and the drop-down list. The 'valueChangeListener' attribute binds to a backing bean method that determines the associated list when a value is changed.
  And then nest the tag in your form:
  
Nested in the ice:selectInputText component tag is an f:selectItems JSF tag. The 'value' binding in this tag provides the list of available options. The screen shot below shows the component in action:
  {code:xml}<icecore:singleSubmit submitOnBlur="true" />
 {code}
  
!autocomplete-action.png!
  All the form fields will now behave as if they have a nested f:ajax tag with the _execute="@this"_ attribute. As the user tabs through fields in the form, the individual fields are executed in the JSF lifecycle and immediate feedback is provided, enhancing the user experience:
  
The following code sample shows an implementation with a list of arbitrarily complex child components:
  !singlesubmit.png!
  
{code:xml}
 <ice:selectInputText rows="6"
  width="300"
  listVar="city"
  valueChangeListener="#{autoCompleteBean.updateList}"
  listValue="#{autoCompleteBean.list}">
  <f:facet name="selectInputText">
  <ice:panelGrid columns="3"
  style="margin-bottom:-20px;"
  columnClasses="cityCol,stateCol,zipCol">
  <ice:outputText value="#{city.city}"/>
  <ice:outputText value="#{city.state}"/>
  <ice:outputText value="#{city.zip}"/>
  </ice:panelGrid>
  </f:facet>
 </ice:selectInputText>
 {code}
  In this case, we have tabbed through the first three fields and those components have been executed on the server. They all have the _required="true"_ attribute and because nothing was input in the field, a FacesMessage was automatically generated and output in the page via the h:message tag. We have arrived at the email field without performing a full form submit, but have been able to generate feedback on fields we have already visited.
  
This will display values similar to the first way but adds more information to the drop down menu, such as state and zip, in addition to the city. The screen shot below shows this method in action:
  h5. {anchor:window}Window Scope
  
!autocomplete-action2.png!
  ICEfaces 3 also features a custom scope called "Window" scope. This custom scope is designed to fill in a gap in the existing scopes available for JSF 2, as it exists for the life of a browser window or tab including surviving reloads and refreshes.
 \\
 \\
 ----
h3. {anchor:ace}Adding ICEfaces ACE Components
  
h3. {anchor:beans}Create the Backing Beans
 \\
In the application we use three main backing beans:
  The ACE Components (ICEfaces Advanced Components) are the next-generation of open source ICEfaces components. Currently featuring over 40 components including the industry-leading ace:dataTable, the ACE Components utilize a blend of server-side and client-based rendering techniques to provide a rich, responsive user-experience with reduced network and server-processing requirements.
  
* _AutoCompleteBean:_ Stores the values gathered from the AutoCompleteDictionary class. Also contains utility methods for updating the list and getting the matches from the dictionary list.
 * _AutoCompleteDictionary:_ Gets the dictionary list from a file in the file system. Also sorts the dictionary appropriately.
 * _City:_ Basic class used as an object in the dictionary list.
  Key features of the ACE Components include:
  
 * Leverage powerful JavaScript components from leading 3rd-party libraries, such as jQuery, while shielding ICEfaces application developers from having to learn/use JavaScript directly.
 * Support extensive client-side functionality to improve component richness, responsiveness, and scalability.
 * Provide a flexible and consistent approach to UI theming/skinning across all components, based on jQuery ThemeRoller themes.
 * Support complete flexibilty in how forms are used with respect to container components, such as TabSet. TabSet allows the use of multiple forms as required, with no limitation that all tabPanes be included in the same form as the tabSet itself.
 * The ACE Components are authored using the ICEfaces Advanced Component Environment, which implements a consistent approach to component authoring, meta-data management, and automates common component development tasks and optimizations.To use the components, add the *icefaces-ace.jar* to your application.
  
 See the [Getting Started with the ACE Components] topic to start using the ACE Components in your application.
  
 \\
 \\
 ----
h3. {anchor:components}Adding ICEfaces ICE Components
  
h3. {anchor:dictionary}Create the Dictionary
 \\
The backing beans retrieve lists of viable options from AutoCompleteDictionary. Our dictionary is populated from an xml file as follows:
  The ICE Components (ICEfaces Components) are based on the original ICEfaces Component Suite in ICEfaces 1.x. The components have been updated to support JSF 2 and more recent versions of ICEfaces. The ICE Components are a complete set of mature JSF components that have benefited from thousands of successful project deployments since their inception.
  
The ICE components are primarily implemented using traditional JSF server-side rendering techniques with limited JavaScript. When combined with ICEfaces automatic-Ajax technology, the ICE Components exhibit extensive partial-page-rendering, providing a rich, dynamic user-experience, even on older legacy browsers.
  
 The ICE Components are recommended under the following circumstances:
  
 * Legacy Browser Support. The ICE Components are ideally suited for projects that are required to support older legacy browsers, such as Internet Explorer 6 / 7. These browsers have significantly less efficient JavaScript processing engines, effectively preventing them from supporting most contemporary JavaScript libraries. The ICE Components can provide good performance on older browsers due to their reliance on predominantly server-side rendering and processing techniques.
 * Application Migration. The ICE Components are tag-compatible with the ICEfaces 1.x Component Suite. This greatly simplifies the migration of ICEfaces 1.x applications to more recent versions of ICEfaces. See the ICEfaces 1.x Compatibility section for more information on porting an existing ICEfaces 1.x application to the current version of ICEfaces.
 * Specialized Applications. Some projects with specific accessibility or security requirements may be required to minimize client-side JavaScript rendering and data-processing. In these cases, the ICE Components may be better suited to meet those requirements.
 * It is also possible to mix both ICE and ACE components as needed in the same ICEfaces application, or even in the same page (with some limitations).
  
 See the [Getting Started with the ICE Components] topic to start using the ICE Components in your application.
  
 \\
 \\
 ----
 h3. {anchor:icepush}Adding AJAX Push
  
 \\
 To enable Ajax Push with ICEfaces 3, you simply add the *icepush.jar* library to your application.
  
 ICEfaces 3 provides a new [API|Ajax Push - API] for using Ajax Push from within your application. As a developer, the class you need to be aware of is org.icefaces.application.PushRenderer. The PushRenderer contains the methods to support using Ajax Push in your application. The new API is very similar to the SessionRenderer API from ICEfaces 1.8.x.
  
 Add a session and all associated pages (views) to a group using:
  
 {code:java}PushRenderer.addCurrentSession(String groupName);
 {code}
  
 Add only a particular page to a group using:
  
 {code:java}PushRenderer.addCurrentView(String groupName);
 {code}
  
 When something of note changes in the application, you can request the client get a notification to get the updates by calling:
  
 {code:java}PushRenderer.render(groupName);
 {code}
  
 You can also use the icecore:push tag to automatically configure Ajax Push behavior on a per-view basis.
  
 {code:xml}
<java version="1.6.0_21" class="java.beans.XMLDecoder">
  <object class="java.util.ArrayList">
  <void method="add">
  <object class="com.icesoft.icefaces.tutorial.component.autocomplete.City">
  <void property="areaCode">
  <string>631</string>
  </void>
  <void property="city">
  <string>Holtsville</string>
  </void>
  <void property="country">
  <string>Suffolk</string>
  </void>
  <void property="state">
  <string>New York</string>
  </void>
  <void property="stateCode">
  <string>NY</string>
  </void>
  <void property="zip">
  <string>00501</string>
  </void>
  </object>
  </void>
  </object>
 </java>
  <icecore:push group="applicantsGroup"/>
 {code}
  
In this case, we have encapsulated the options available to the user in a zipped xml file that is deployed with the applications. Options available to the user could also be retrieved from a database.
  We will use this technique in our tutorial application to update the applicants page after a new job applicant has been added.
  
 First, add icepush.jar to the application. Next, go to applicants.xhtml and add the icecore namespace to the view:
  
 {code:xml}
 xmlns:icecore="http://www.icefaces.org/icefaces/core"
 {code}
  
 In applicants.xhtml add the icecore:push tag to the page:
  
 {code:xml}
 ...
 <ui:define name="content">
  <icecore:push group="applicantsGroup" />
  <h:dataTable value="#{applicants.applicantsList}"
 ...
 {code}
  
 The icecore:push tag ensures any user viewing this page will receive an update when the PushRenderer renders the 'applicantsGroup'.
  
 The next step is to push an update out to everyone once a new job applicant has been added. In our ApplicantController.java class we add the following to the addApplicant() method:
  
 {code:title=ApplicantController.java|borderStyle=solid}
  PushRenderer.render("applicantsGroup");
 {code}
  
 This was a simple two step process of associating a push group with a page and then making a render call to that group when the page has changed. Let's see it in action.
  
 Open a browser window in Internet Explorer and one in FireFox. This will create two separate sessions running in our tutorial application. In FireFox, we see a job applicant already added to our applicants list:
  
 !FFbeforePush.png!
  
 In Internet Explorer, we now add a new job applicant:
  
 !IEbeforePush.png!
  
 After the "Submit Applicant" button has been pressed, the Firefox window immediately receives an update via AJAX push:
  
 !FFafterPush.png!
  
 With AJAX Push added to the application, users receive real-time updates from the server without needing to initiate a request to the server.
 \\
 \\
 ----
 
  Adding icefaces.jar, icefaces-ace.jar and icepush.jar to your JSF 2 applications will equip you with all the tools necessary to create AJAX enabled Rich Internet Applications.
 \\
 ----
 h3. {anchor:download}Tutorial Source Code Downloads
 
 \\
 || Example || Source || Notes ||
 | autocomplete-tutorial |[autocomplete-tutorial source code|^autocomplete-tutorial.zip|Download Source Code]| Simple example on how to use the Auto-Complete component.|
  | getting-started-tutorial | [getting-started-tutorial source code|Getting Started with ICEfaces 3^getting-started.zip|Download Source Code] | Source code for a basic JSF 2 application ready for ICEfaces enhancements.
 In Eclipse Indigo create a Dynamic Web Project, JavaServer Faces V2.0 Project (download Mojarra 2.1.3 jar).
 Import the source code in to the project and add the Tomcat 7 runtime to your build path. |

© Copyright 2021 ICEsoft Technologies Canada Corp.