JSF-Extension: Dynamic Faces (DynaFaces)

Sang Shin, sangshinpassion@gmail.com, www.javapassion.com/j2ee




In this lab, you are going to explore various sample applications that use Dynamic Faces.  The sample applications are from  the Dynamic Faces distribution package.


Expected duration: 100 minutes (excluding homework)


Prerequisites

This hands-on lab assumes you have some basic knowledge or programming experience on the following  technologies.


Software Needed

Before you begin, you need to install the following software on your computer. 


OS platforms you can use

Change Log


Things to do (by Sang Shin)


Lab Exercises


Exercise 1: Build and run "dyna-blank-jsp" sample application


This sample is a skeleton Dynamic Faces application using JSP.  It is just a starting place for customization.  You can create a new DynaFaces NetBeans project by copying this project.

(1.1) Open, build, and run "dyna-blank-jsp" sample application

0. Start NetBeans IDE. 
1. Open dyna-blank-jsp NetBeans project. 

2. Build and run dyna-blank-jsp project.




(1.2)  Look under the hood of the  "dyna-blank-jsp" sample application


1. web.xml

<?xml version='1.0' encoding='UTF-8'?>

<web-app version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

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

    <context-param>
        <description>
            Set this flag to true if you want the JavaServer Faces
            Reference Implementation to validate the XML in your
            faces-config.xml resources against the DTD. Default
            value is false.
        </description>
        <param-name>com.sun.faces.validateXml</param-name>
        <param-value>true</param-value>
    </context-param>

    <!-- Faces Servlet -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <init-param>
          <param-name>javax.faces.LIFECYCLE_ID</param-name>
          <param-value>com.sun.faces.lifecycle.PARTIAL</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>


    <!-- Faces Servlet Mapping -->
    <!--

         This mapping identifies a jsp page as having JSF content.  If a
         request comes to the server for foo.faces, the container will
         send the request to the FacesServlet, which will expect a
         corresponding foo.jsp page to exist containing the content.

    -->
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>

</web-app>

2. index.html

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
    <head>
        <meta http-equiv="refresh" content="2;url=home.jsf">
    </head>
   
    <body>
       
    </body>
</html>

3. home.jsp

<%@ taglib uri="http://java.sun.com/jsf/core"  prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html"  prefix="h" %>
<%@ taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces" %>

<f:view>
    <html>
        <head>
            <title>DynaFaces JSP Blank App</title>
            <jsfExt:scripts />
        </head>
        <body  bgcolor="white">
           
            <h:form id="form"> 
               
                <h1>DynaFaces JSP Blank App</h1>
               
               
            </h:form>
           
        </body>
    </html>
</f:view>



Summary

In this exercise,  you have built and run a ready-to-build-and-run "dyna-blank-jsp" sample application to get a sense how the application works. 

                                                                                                                        return to the top



Exercise 2: Build and run "dyna-cardemo" sample application


The Options page is modified to use DynaFaces to provide Ajax behavior.  The price of the car is updated without refreshing the whole page.

(2.1) Open, build, and run "dyna-cardemo" sample application

1. Open dyna-cardemo NetBeans project. 

2. Build and run dyna-cardemo project.






(2.2)  Look under the hood of the  "dyna-cardemo" sample application


1. carDetails.jsp
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="1.2"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:jsp="http://java.sun.com/JSP/Page"
          xmlns:jsfExt="http://java.sun.com/jsf/extensions/dynafaces">
    <jsp:directive.page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"/>
   
    <html>
       
        <head>
            <meta http-equiv="Content-Type" content="text/html;CHARSET=UTF-8" />
            <title>CarStore</title>
            <link rel="stylesheet" type="text/css"
                  href="${pageContext.request.contextPath}/stylesheet.css" />
        </head>
       
        <f:loadBundle basename="carstore.bundles.Resources" var="bundle"/>
       
        <body bgcolor="white">
           
            <f:view>
               
                <h:form prependId="false">
                   
                   
                    <!-- non-option details -->

                    <h:panelGrid columns="1"
                                 summary="#{bundle.carDetails}"
                                 title="#{bundle.carDetails}">
                       
                        <h:graphicImage url="/images/cardemo.jpg"/>
                       
                        <h:graphicImage
                            binding="#{carstore.currentModel.components.image}"/>
                       
                        <h:outputText styleClass="subtitlebig"
                                      binding="#{carstore.currentModel.components.title}"/>
                       
                        <h:outputText
                            binding="#{carstore.currentModel.components.description}"/>
                       
                        <jsfExt:ajaxZone id="zone1">
                           
                            <h:panelGrid columns="2">
                               
                                <h:outputText styleClass="subtitle"
                                              value="#{bundle.basePriceLabel}"/>
                               
                                <h:outputText
                                    binding="#{carstore.currentModel.components.basePrice}"/>
                               
                                <h:outputText styleClass="subtitle"
                                              value="#{bundle.yourPriceLabel}"/>
                               
                                <h:outputText value="#{carstore.currentModel.currentPrice}"/>
                               
                            </h:panelGrid>
                           
                        </jsfExt:ajaxZone>
                       
                        <h:commandButton action="#{carstore.buyCurrentCar}"
                                         value="#{bundle.buy}"/>
                       
                    </h:panelGrid>
                   
                    <jsp:include page="optionsPanel.jsp"/>
                   
                    <h:commandButton action="#{carstore.buyCurrentCar}"
                                     value="#{bundle.buy}"/>
                   
                </h:form>
               
                <jsp:include page="bottomMatter.jsp"/>
               
            </f:view>
        </body>
       
    </html>
</jsp:root>


2. optionsPanel.jsp

<%@ page contentType="text/html" language="java" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces" %>

<jsfExt:ajaxZone id="zone2" render="zone1,zone2" execute="zone2"
                 action="#{carstore.currentModel.updatePricing}">
    <h:panelGrid>
       
        <h:outputText value="#{bundle.OptionsPackages}"/>
       
        <!-- options package chooser -->

        <h:panelGrid columns="4">
           
            <h:commandButton id="Custom" value="#{bundle.Custom}"
                             styleClass="#{carstore.customizers.Custom.buttonStyle}"
                             actionListener="#{carstore.choosePackage}"/>
           
            <h:commandLink id="Standard" value="#{bundle.Standard}"
                           styleClass="#{carstore.customizers.Standard.buttonStyle}"
                           actionListener="#{carstore.choosePackage}"/>
           
            <h:commandButton id="Performance" value="#{bundle.Performance}"
                             styleClass="#{carstore.customizers.Performance.buttonStyle}"
                             actionListener="#{carstore.choosePackage}"/>
           
            <h:commandButton id="Deluxe" value="#{bundle.Deluxe}"
                             styleClass="#{carstore.customizers.Deluxe.buttonStyle}"
                             actionListener="#{carstore.choosePackage}"/>
           
        </h:panelGrid>
       
    </h:panelGrid>
   
    <h:panelGrid columns="2">
       
        <h:outputText value="#{bundle.Engine}"
                      styleClass="optionLabel"/>
       
        <h:selectOneMenu styleClass="optionValue"
                         binding="#{carstore.currentModel.components.engine}"/>
       
        <h:outputText value="#{bundle.Brakes}"
                      styleClass="optionLabel"/>
       
        <h:selectOneRadio styleClass="optionValue"
                          binding="#{carstore.currentModel.components.brake}"/>
       
        <h:outputText value="#{bundle.Suspension}"
                      styleClass="optionLabel"/>
       
        <h:selectOneMenu styleClass="optionValue"
                         binding="#{carstore.currentModel.components.suspension}"/>
       
        <h:outputText value="#{bundle.Speakers}"
                      styleClass="optionLabel"/>
       
        <h:selectOneRadio styleClass="optionValue"
                          binding="#{carstore.currentModel.components.speaker}"/>
       
        <h:outputText value="#{bundle.Audio}"
                      styleClass="optionLabel"/>
       
        <h:selectOneRadio styleClass="optionValue"
                          binding="#{carstore.currentModel.components.audio}"/>
       
        <h:outputText value="#{bundle.Transmission}"
                      styleClass="optionLabel"/>
       
        <h:selectOneMenu styleClass="optionValue"
                         binding="#{carstore.currentModel.components.transmission}"/>
       
    </h:panelGrid>
   
    <h:outputText value="#{bundle.OtherOptions}"
                  styleClass="optionLabel"/>
   
    <h:panelGrid columns="6">
       
        <h:selectBooleanCheckbox title="#{bundle.sunroofLabel}"
                                 binding="#{carstore.currentModel.components.sunroof}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.sunroofLabel}"/>
       
        <h:selectBooleanCheckbox title="#{bundle.cruiseLabel}"
                                 binding="#{carstore.currentModel.components.cruisecontrol}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.cruiseLabel}"/>
       
        <h:selectBooleanCheckbox title="#{bundle.keylessLabel}"
                                 binding="#{carstore.currentModel.components.keylessentry}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.keylessLabel}"/>
       
        <h:selectBooleanCheckbox
            title="#{bundle.securityLabel}"
            binding="#{carstore.currentModel.components.securitySystem}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.securityLabel}"/>
       
        <h:selectBooleanCheckbox title="#{bundle.skiRackLabel}"
                                 binding="#{carstore.currentModel.components.skiRack}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.skiRackLabel}"/>
       
        <h:selectBooleanCheckbox title="#{bundle.towPkgLabel}"
                                 binding="#{carstore.currentModel.components.towPackage}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.towPkgLabel}"/>
       
        <h:selectBooleanCheckbox title="#{bundle.gpsLabel}"
                                 binding="#{carstore.currentModel.components.gps}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.gpsLabel}"/>
       
    </h:panelGrid>
   
</jsfExt:ajaxZone>

Summary

In this exercise,  you have built and run a ready-to-build-and-run "dyna-cardemo" sample application to get a sense how the application works. 

                                                                                                                        return to the top


Exercise 3: Build and run "dyna-jmaki" sample application


This example shows some of the possibilities when combining DynaFaces with jMaki and custom JSF Components. Note that we have AJAX enabled the Blueprints Scroller component without modifying it at all. This component is a straight "off the shelf" component.

This example also shows how the jMaki dojo FishEye component is fully integrated with JSF. The page has two message areas that are updated via Ajax in response to the selection of one of the items in the fishEye. The jMaki FishEye widget has a value binding to an int property on a request scoped managed bean. It also has a valueChangeListener method binding pointing to a method on that same managed bean. Choosing one of the items in the list both causes the current value of the component to be updated, with type conversion to int, and the valueChangeListener to be called, which stores a message in request scope which is output by an outputText as well as making it so only the two outputText components are rendered. The selected message strings are all pulled from the managed bean.

(3.1) Open, build, and run 1st part of the "dyna-jmaki" sample application

1. Open dyna-jmaki NetBeans project. 

2. Build and run dyna-jmaki project.






(3.2)  Look under the hood of the first part of the  "dyna-jmaki" sample application


1. CustomerBean.java

package com.sun.faces.run_time_test.model;


import java.io.Serializable;


/**
 * <p>JavaBean represented the data for an individual customer.</p>
 */

public class CustomerBean implements Serializable {
   
   
    public CustomerBean() {
        this(null, null, null, 0.0);
    }
   
   
    public CustomerBean(String accountId, String name,
            String symbol, double totalSales) {
        this.accountId = accountId;
        this.name = name;
        this.symbol = symbol;
        this.totalSales = totalSales;
    }
   
   
    private String accountId = null;
   
   
    public String getAccountId() {
        return (this.accountId);
    }
   
   
    public void setAccountId(String accountId) {
        this.accountId = accountId;
    }
   
   
    private String name = null;
   
   
    public String getName() {
        return (this.name);
    }
   
   
    public void setName(String name) {
        this.name = name;
    }
   
   
    private String symbol = null;
   
   
    public String getSymbol() {
        return (this.symbol);
    }
   
   
    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }
   
   
    private double totalSales = 0.0;
   
   
    public double getTotalSales() {
        return (this.totalSales);
    }
   
   
    public void setTotalSales(double totalSales) {
        this.totalSales = totalSales;
    }
   
   
    public String toString() {
        StringBuffer sb = new StringBuffer("CustomerBean[accountId=");
        sb.append(accountId);
        sb.append(",name=");
        sb.append(name);
        sb.append(",symbol=");
        sb.append(symbol);
        sb.append(",totalSales=");
        sb.append(totalSales);
        sb.append("]");
        return (sb.toString());
    }
   
   
}

2. ResultSetBean.java

package com.sun.faces.run_time_test.model;

import javax.faces.component.UIComponent;
import javax.faces.component.UIData;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>Backing file bean for <code>ResultSet</code> com.sun.javaee.blueprints.simpleuicomponents.onents.</p>
 */

public class ResultSetBean {
   
    private List list = null;
   
   
    public ResultSetBean() {
    }
   
   
    public List getList() {
        // Construct a preconfigured customer list lazily.
        if (list == null) {
            list = new ArrayList();
            for (int i = 0; i < 1000; i++) {
                list.add(new CustomerBean(Integer.toString(i),
                        "name_" + Integer.toString(i),
                        "symbol_" + Integer.toString(i), i));
            }
        }
        return list;
    }
   
   
    public void setList(List newlist) {
        this.list = newlist;
    }
   
    // -------------------------------------------------------- Bound Components
   
    /**
     * <p>The <code>UIData</code> component representing the entire table.</p>
     */
    private UIData data = null;
   
   
    public UIData getData() {
        return data;
    }
   
   
    public void setData(UIData data) {
        this.data = data;
    }
   
   
    // ---------------------------------------------------------- Action Methods
   
   
    /**
     * <p>Scroll directly to the first page.</p>
     */
    public String first() {
        scroll(0);
        return (null);
       
    }
   
   
    /**
     * <p>Scroll directly to the last page.</p>
     */
    public String last() {
        scroll(data.getRowCount() - 1);
        return (null);
       
    }
   
   
    /**
     * <p>Scroll forwards to the next page.</p>
     */
    public String next() {
        int first = data.getFirst();
        scroll(first + data.getRows());
        return (null);
       
    }
   
   
    /**
     * <p>Scroll backwards to the previous page.</p>
     */
    public String previous() {
        int first = data.getFirst();
        scroll(first - data.getRows());
        return (null);
       
    }
   
   
    /**
     * <p>Scroll to the page that contains the specified row number.</p>
     *
     * @param row Desired row number
     */
    public void scroll(int row) {
       
        int rows = data.getRows();
        if (rows < 1) {
            return; // Showing entire table already
        }
        if (row < 0) {
            data.setFirst(0);
        } else if (row >= data.getRowCount()) {
            data.setFirst(data.getRowCount() - 1);
        } else {
            data.setFirst(row - (row % rows));
        }
       
    }
   
   
    /**
     * Handles the ActionEvent generated as a result of clicking on a
     * link that points a particular page in the result-set.
     */
    public void processScrollEvent(ActionEvent event) {
        int currentRow = 1;
        FacesContext context = FacesContext.getCurrentInstance();
        UIComponent component = event.getComponent();
        Integer curRow = (Integer) component.getAttributes().get("currentRow");
        if (curRow != null) {
            currentRow = curRow.intValue();
        }
        // scroll to the appropriate page in the ResultSet.
        scroll(currentRow);
    }
   
   
}


(3.3) Run the 2nd part of the "dyna-jmaki" sample application





(3.4)  Look under the hood of the 2nd part of the  "dyna-jmaki" sample application


1. FishEyeBean.java

package com.sun.faces.run_time_test.model;

import com.sun.faces.extensions.avatar.lifecycle.AsyncResponse;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;

/**
 *
 * @author edburns
 */
public class FishEyeBean {
   
    /** Creates a new instance of FishEyeBean */
    public FishEyeBean() {
    }
   
    public void valueChanged(ValueChangeEvent e) {
        FacesContext context = FacesContext.getCurrentInstance();
        AsyncResponse async = AsyncResponse.getInstance();
        String message = " oldValue: " +
                e.getOldValue() + " newValue: " + e.getNewValue();
        context.getExternalContext().getRequestMap().put("fishEyeMessage", message);
        // Request DynaFaces to re-render only the fishEyeMessage.
        List<String> renderSubtrees = async.getRenderSubtrees();
        renderSubtrees.clear();
        renderSubtrees.add("fishEyeMessage");
        renderSubtrees.add("personMessage");
        renderSubtrees.add(e.getComponent().getClientId(context));
    }

    /**
     * Holds value of property selectedIndex.
     */
    private int selectedIndex;

    /**
     * Getter for property selectedIndex.
     * @return Value of property selectedIndex.
     */
    public int getSelectedIndex() {
        return this.selectedIndex;
    }

    /**
     * Setter for property selectedIndex.
     * @param selectedIndex New value of property selectedIndex.
     */
    public void setSelectedIndex(int selectedIndex) {
        this.selectedIndex = selectedIndex;
    }

    /**
     * Holds value of property personMessages.
     */
    private String [] personMessages;

    /**
     * Getter for property personMessages.
     * @return Value of property personMessages.
     */
    public String [] getPersonMessages() {
        return this.personMessages;
    }

    /**
     * Setter for property personMessages.
     * @param personMessages New value of property personMessages.
     */
    public void setPersonMessages(String [] personMessages) {
        this.personMessages = personMessages;
    }

    /**
     * Getter for property personMessage.
     * @return Value of property personMessage.
     */
    public String getPersonMessage() {
        return personMessages[getSelectedIndex()];
    }
   
}

2. fisheye.jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces"%>

<f:view>
   
    <html>
        <head>
            <title><%@ include file="title.jsp" %></title>
           
            <link rel="stylesheet" href="css/default_developer.css" />
            <link rel="stylesheet" href="css/default.css" />
            <link rel="stylesheet" href="css/homepage.css" />   
            <jsfExt:scripts/>
            <%@ include file="extraHeadContent.jsp" %>
        </head>
       
        <%@ page contentType="text/html" %>
       
        <body leftmargin="0" topmargin="0" marginheight="0" marginwidth="0" rightmargin="0" bgcolor="#ffffff" class="vaa2v0">
           
            <a name="top"></a>
           
            <%@ include file="masthead.jsp" %>
           
            <!-- BEGIN PAGETITLE -->
            <div class="pagetitle"><%@ include file="title.jsp" %></div>
            <!-- END PAGETITLE -->
           
            <%@ include file="topPanelFishEye.jsp" %>
           
           
            <!-- BEGIN WRAPPER TABLE, 2 COLUMN, MAIN/RIGHT -->
            <table border="0" cellpadding="0" cellspacing="10" width="100%">
                <tr valign="top"><td>
                       
                        <!-- BEGIN MAIN COLUMN -->
                       
                        <%@ include file="mainColumnFishEye.jsp" %>
                       
                    </td>
                   
                    <!-- BEGIN RIGHT COLUMN -->
                    <td>
                       
                        <div class="e15"><div class="e15v0">
                                <div class="cornerTL"><div class="cornerTR"></div></div>
                                <div class="pad">
                                   
                                    <%@ include file="rightColumnFishEye.jsp" %>
                                   
                                </div>
                                <div class="cornerBL"><div class="cornerBR"></div></div>
                               
                        </div></div>
                       
                    </td>
                   
                </tr>
               
               
                <tr>
                    <td class="headerbar3">
                       
                        <div class="headerpadding2"><span style="color:#fff;">Running the Demo</span></div>
                       
                    </td>
                   
                </tr>
                <tr>
                   
                    <td>
                       
                        <%@ include file="bottomPanelFishEye.jsp" %>
                       
                    </td>
                </tr>
               
            </table>
           
        </body>
    </html>
</f:view>

2. mainColumnFishEye.jsp

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/blueprints/ui" prefix="d" %>
<%@ taglib prefix="a" uri="http://java.sun.com/jmaki-jsf" %>
<%@taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces"%>

<jsfExt:scripts/>

<h:form id="form" prependId="false">
   
   
    <table bgcolor="#eeeeee" border="0" cellpadding="2" cellspacing="0" width="100%" class="vtop">
        <colgroup>
            <col width="100%" />
        </colgroup>
       
        <tr>
            <td class="headerbar3" colspan="2">
                <div class="headerpadding2"><span style="color:#fff;">JSF, Dynamic Faces, and the Dojo FishEye widget.</span></div>
               
            </td>
        </tr>
       
        <tr>
           
            <td colspan="2">
               
                <a:ajax name="dojo.fisheye"
                        value="#{fishEyeBean.selectedIndex}"
                        valueChangeListener="#{fishEyeBean.valueChanged}"
                        args="{items:[
                        {iconSrc:'images/3_Galbraith_small.jpg',caption:'Ben',index:0},
                        {iconSrc:'images/2_Almaer_small.jpg',caption:'Dion',index:1},
                        {iconSrc:'images/1255_Raskin_small.jpg',caption:'Aza',index:2},
                        {iconSrc:'images/1254_Lewis_Ship_small.jpg',caption:'Howard',index:3}
                        ]}"

                />
               
               
            </td>
        </tr>
       
        <tr>
           
            <td colspan="2">
               
                <p>This example shows how the jMaki dojo FishEye component is fully
                    integrated with JSF.  The page has two message areas that are updated
                    via Ajax in response to the selection of one of the items in the
                    fishEye.  The jMaki FishEye widget has a value binding to an
                    <code>int</code> property on a request scoped managed bean.  It also has
                    a <code>valueChangeListener</code> method binding pointing to a method
                    on that same managed bean.  Choosing one of the items in the list both
                    causes the current value of the component to be updated, with type
                    conversion to <code>int</code>, and the <code>valueChangeListener</code>
                    to be called, which stores a message in request scope which is output by
                    an <code>outputText</code> as well as making it so only the two
                    <code>outputText</code> components are rendered.  The selected message
                strings are all pulled from the managed bean.</p>
               
            </td>
           
        </tr>
       
       
        <tr>
           
            <td>Selected Person <h:outputText id="personMessage" value="#{fishEyeBean.personMessage}" />
            </td>
           
            <td>Message from ValueChangeListener <h:outputText id="fishEyeMessage" value="#{requestScope.fishEyeMessage}" />
               
            </td>
           
        </tr>
       
    </table>
   
</h:form>


Exercise 4: Build and run "dyna-simple-events" sample application


This example shows how to dispatch a jsf ValueChangeEvent from JavaScript directly to the JSF Lifecycle via AJAX.  Any valueChangeListeners installed on components that are subject to traversal in this transaction will be fired as normal.

This example also shows how to dispatch a jsf ActionEvent from JavaScript directly to the JSF Lifecycle via AJAX.  Any actionListeners installed on components that are subject to traversal in this transaction will be fired as normal.

(4.1) Open, build, and run "dyna-simple-events" sample application

1. Open dyna-simple-events NetBeans project. 

2. Build and run dyna-simple-events project.







(4.2)  Look under the hood of the  "dyna-simple-events" sample application


<will be added later>

Exercise 5: Build and run "dyna-simple-partial-update" sample application



(5.1) Open, build, and run "dyna-simple-partial-update" sample application

1. Open dyna-simple-partial-update NetBeans project. 

2. Build and run dyna-simple-partial-update project.



(5.2)  Look under the hood of the  "core-flags-with-fparam" sample application


<will be added later>

Exercise 6: Build and run "dyna-flash" sample application

The series of pages in this sample application illustrates the usage of the flash concept taken from Ruby On Rails.

In JSF, the flash is exposed naturally via the new Unified Expression Language in Java EE 5. It is implemented via a custom ELResolver that introduces a new implicit object called "flash". I considered calling it "dhhIsMyHero" but opted for the simpler "flash" instead.

Using the flash is simple, and semantically identical to the way it works in Rails. It's a Map. Stuff you put in the Map will be accessible on the "next" view shown to user. The Map will be cleared when the user has been shown the "next" view.


(6.1) Open, build, and run "dyna-flash" sample application

1. Open dyna-flash NetBeans project. 

2. Remove broken references and add DynaFaces library files to the project as you've done in Exercise 1 above.

3. Build and run dyna-flash project.



(6.2)  Look under the hood of the  "dyna-flash" sample application


<will be added later>


Exercise 7: Build and run "dyna-fire-ajax-transaction" sample application


This sample illustrates the behavior of the DynaFaces.fireAjaxTransaction method, and in particular, the behavior of the execute and render options. Complete reference materials for these options are available at the project homepage.

The View area is a view of PanelGrid and CommandButton components. Initially, each of these components has a green border, meaning that all these components have gone through the initial render phase of the lifecycle.

Each of the fireAjaxTransaction buttons causes a different DynaFaces.fireAjaxTransaction event to occur, affecting one or more components in the view. The color of a component may change color depending on what lifecycle phase the component was processed.

The Options area shows the options used with the fireAjaxTransaction command. Press the Reset button before firing a new command.

(7.1) Open, build, and run "dyna-fire-ajax-transaction" sample application

1. Open dyna-fire-ajax-transaction NetBeans project. 

2. Build and run dyna-fire-ajax-transaction project.



(7.2)  Look under the hood of the  "dyna-fire-ajax-transaction" sample application


1. home.jsp

<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="1.2"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:jsp="http://java.sun.com/JSP/Page"
          xmlns:jsfExt="http://java.sun.com/jsf/extensions/dynafaces">
    <jsp:directive.page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"/>

    <f:view>  
        <html>
            <head>
                <meta http-equiv="Content-Type" content="text/html;CHARSET=UTF-8" />
                <title>Dynamic Faces fireAjaxTransaction</title>
                <link rel="stylesheet" type="text/css"
                      href="${pageContext.request.contextPath}/stylesheet.css" />
                <jsfExt:scripts />
            </head>
            <body  bgcolor="white">
                <h:form id="form" prependId="false"> 
                   
                    <h1>Dynamic Faces fireAjaxTransaction</h1>
                   
                    <jsp:include page="colorKey.jsp"/>
                   
                    <h:panelGrid columns="2" cellspacing="30">    
                        <jsp:include page="fireajax.jsp"/>            
                        <jsp:include page="componentMap.jsp"/>            
                    </h:panelGrid>
                   
                    <h:panelGrid border="1" columns="2" cellspacing="40">
                        <h:commandButton id="reset"
                                         value="reset"
                                         onclick="DynaFaces.fireAjaxTransaction(this,
                                         {execute:'reset'}); return false;"
                                         actionListener="#{bean.reset}"/>
                        <h:panelGrid columns="2">
                            <h:panelGrid id="optionsTitle">
                                <h:outputText value="Options: " styleClass="options-prompt"/>
                            </h:panelGrid>
                            <h:panelGrid id="fireOptions">                        
                                <h:outputText value="#{bean.fireOptions}" styleClass="options"/>                       
                            </h:panelGrid>
                        </h:panelGrid>
                    </h:panelGrid>             
                   
                </h:form> 
               
            </body>
        </html>
    </f:view>
   
</jsp:root>

2. fireajax.jsp

<%@ page contentType="text/html" language="java" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="g" uri="http://java.sun.com/jsf/fireAjaxTrans" %>

<h:panelGrid border="1" columns="2" cellspacing="10" headerClass="keytitle">
    <f:facet name="header">
        <h:outputText value="Command"/>
    </f:facet>
    <h:commandButton id="ajax1"
                     value="fireAjaxTransaction [ajax1]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax1,_1'}); return false;"
                     actionListener="#{bean.getOptions}"/> 
    <h:commandButton id="ajax2"
                     value="fireAjaxTransaction [ajax2]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax2,_6,_10'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax3"
                     value="fireAjaxTransaction [ajax3]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax3,_5'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax4"
                     value="fireAjaxTransaction [ajax4]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax4,_4,_9'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax5"
                     value="fireAjaxTransaction [ajax5]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax5',render:'_1,optionsTitle,fireOptions'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax6"
                     value="fireAjaxTransaction [ajax6]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax6',render:'_6,optionsTitle,fireOptions'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax7"
                     value="fireAjaxTransaction [ajax7]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax7,_10',render:'_5,optionsTitle,fireOptions'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax8"
                     value="fireAjaxTransaction [ajax8]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax8,_1,_2,_3,_4',render:'_1,_2,_3,_4,optionsTitle,fireOptions'}); return false;"
                     actionListener="#{bean.getOptions}"/>
</h:panelGrid>


Exercise 8: Build and run "dyna-tictactoe" sample application


(8.1) Open, build, and run "dyna-tictactoe" sample application

1. Open dyna-tictactoe NetBeans project. 

2. Build and run dyna-tictactoe project.



(8.2)  Look under the hood of the  "dyna-tictactoe" sample application


<will be added later>


Exercise 9: Build and run "dyna-blank-facelets" sample application


(9.1) Open, build, and run "dyna-blank-facelets" sample application

1. Open dyna-blank-facelets NetBeans project. 

2. Build and run dyna-blank-facelets project.



(9.2)  Look under the hood of the  "dyna-blank-facelets" sample application


<will be added later>

Homework Exercise (for people who are taking Sang Shin's "Java EE Programming online course")


<to be provided>

                                                                                                                    return to the top