SWF-1367 Add support for JSF 2 Ajax requests, update booking-faces sample (JSF 2 based Ajax, jsr-303 validation), add chained delegation to AjaxHandlers, other miscellaneous improvements

This commit is contained in:
Rossen Stoyanchev
2010-07-28 12:56:24 +00:00
parent 507fec3edf
commit fe9229cf15
36 changed files with 722 additions and 494 deletions

View File

@@ -1,13 +1,27 @@
#Sun Apr 27 09:05:45 EDT 2008
#Wed Jul 28 13:06:21 BST 2010
eclipse.preferences.version=1
instance/org.eclipse.core.net/org.eclipse.core.net.hasMigrated=true
org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true
org.springframework.ide.eclipse.core.builders.enable.beanmetadatabuilder=true
org.springframework.ide.eclipse.core.builders.enable.osgibundleupdater=true
org.springframework.ide.eclipse.core.enable.project.preferences=true
org.springframework.ide.eclipse.core.validator.enable.com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.bestpractices.beansvalidator=true
org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.server.quickfix.manifestvalidator=false
org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=true
org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.webflow.core.validator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivationPolicyRule-com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivatorRule-com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleManifestVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.exportPackageRule-com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.importRule-com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.parsingProblemsRule-com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.requireBundleRule-com.springsource.server.ide.manifest.core.manifestvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.AvoidDriverManagerDataSource-com.springsource.sts.bestpractices.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ImportElementsAtTopRulee-com.springsource.sts.bestpractices.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ParentBeanSpecifiesAbstractClassRule-com.springsource.sts.bestpractices.beansvalidator=true
@@ -16,6 +30,11 @@ org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UnnecessaryValueElementRule-com.springsource.sts.bestpractices.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UseBeanInheritance-com.springsource.sts.bestpractices.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.legacyxmlusage.jndiobjectfactory-com.springsource.sts.bestpractices.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importLibraryVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importPackageVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.requireBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.autowire.autowire-org.springframework.ide.eclipse.beans.core.beansvalidator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanAlias-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanClass-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanConstructorArgument-org.springframework.ide.eclipse.beans.core.beansvalidator=true
@@ -28,6 +47,7 @@ org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.i
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.methodOverride-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.parsingProblems-org.springframework.ide.eclipse.beans.core.beansvalidator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.toolAnnotation-org.springframework.ide.eclipse.beans.core.beansvalidator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.action-org.springframework.ide.eclipse.webflow.core.validator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.actionstate-org.springframework.ide.eclipse.webflow.core.validator=true

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<webflow-project-description>
<version>1</version>
<pluginVersion><![CDATA[2.2.1.v200811281800]]></pluginVersion>
<pluginVersion><![CDATA[2.3.3.201005082200-CI-R3771-B737]]></pluginVersion>
<configs>
<config>
<file>src/main/webapp/WEB-INF/flows/booking/booking-flow.xml</file>
@@ -10,8 +10,7 @@
</config>
<config>
<file>src/main/webapp/WEB-INF/flows/main/main-flow.xml</file>
<name><![CDATA[main]]></name>
<beans-config><![CDATA[1:BeansModel|2:swf-booking-faces|3:src/main/webapp/WEB-INF/config/web-application-config.xml]]></beans-config>
<name><![CDATA[main-flow]]></name>
</config>
</configs>
</webflow-project-description>

View File

@@ -30,8 +30,10 @@
<dependency org="org.hibernate" name="com.springsource.org.hibernate" rev="3.2.6.ga" conf="compile->runtime"/>
<dependency org="org.hibernate" name="com.springsource.org.hibernate.annotations" rev="3.3.0.ga" conf="compile->runtime"/>
<dependency org="org.hibernate" name="com.springsource.org.hibernate.ejb" rev="3.3.1.ga" conf="compile->runtime"/>
<dependency org="org.hibernate" name="com.springsource.org.hibernate.validator" rev="4.1.0.GA" />
<dependency org="org.hsqldb" name="com.springsource.org.hsqldb" rev="1.8.0.9" conf="compile->runtime"/>
<dependency org="org.joda" name="com.springsource.org.joda.time" rev="1.6.0" conf="compile->runtime"/>
<dependency org="org.slf4j" name="com.springsource.slf4j.log4j" rev="1.5.6" />
<dependency org="org.springframework" name="org.springframework.aop" rev="3.0.3.RELEASE" conf="compile->runtime"/>
<dependency org="org.springframework" name="org.springframework.beans" rev="3.0.3.RELEASE" conf="compile->runtime"/>
<dependency org="org.springframework" name="org.springframework.context" rev="3.0.3.RELEASE" conf="compile->runtime"/>

View File

@@ -42,6 +42,11 @@
<artifactId>com.springsource.org.hibernate.ejb</artifactId>
<version>3.3.1.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>com.springsource.org.hibernate.validator</artifactId>
<version>4.1.0.GA</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>com.springsource.org.hsqldb</artifactId>
@@ -52,6 +57,11 @@
<artifactId>joda-time</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>com.springsource.slf4j.log4j</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.aop</artifactId>

View File

@@ -15,6 +15,9 @@ import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
@@ -34,12 +37,17 @@ public class Booking implements Serializable {
private Hotel hotel;
@NotNull
private Date checkinDate;
@NotNull
private Date checkoutDate;
@Pattern(regexp = "[0-9]{16}", message = "Credit card number must be 16 digits.")
private String creditCard;
@NotNull
@Size(min = 3, message = "A valid credit card name is required.")
private String creditCardName;
private int creditCardExpiryMonth;

View File

@@ -36,6 +36,9 @@
<!-- Dispatches requests mapped to flows to FlowHandler implementations -->
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
<property name="ajaxHandler">
<bean class="org.springframework.faces.webflow.JsfAjaxHandler"/>
</property>
</bean>
<!-- Dispatches requests mapped to org.springframework.web.HttpRequestHandler implementations -->

View File

@@ -3,11 +3,9 @@
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:sf="http://www.springframework.org/tags/faces"
template="/WEB-INF/layouts/standard.xhtml">
<ui:define name="content">
<div class="span-5">
<h3>${booking.hotel.name}</h3>
<address>
@@ -18,12 +16,8 @@
${booking.hotel.country}
</address>
</div>
<div class="span-12">
<ui:fragment id="messages">
<div id="messagesInsertionPoint">
<h:messages errorClass="error" layout="table"/>
</div>
</ui:fragment>
<h:panelGroup id="bookingsFragment" styleClass="span-12" layout="block">
<h:messages errorClass="error" layout="table"/>
<h:form id="bookingForm">
<fieldset>
<legend>Book Hotel</legend>
@@ -45,11 +39,9 @@
</div>
<div class="span-7 last">
<p>
<sf:clientDateValidator required="true">
<h:inputText id="checkinDate" value="#{booking.checkinDate}" required="true">
<f:convertDateTime pattern="MM-dd-yyyy" timeZone="EST"/>
</h:inputText>
</sf:clientDateValidator>
<h:inputText id="checkinDate" value="#{booking.checkinDate}" required="true">
<f:convertDateTime pattern="MM-dd-yyyy" timeZone="EST"/>
</h:inputText>
</p>
</div>
</div>
@@ -59,11 +51,9 @@
</div>
<div class="span-7 last">
<p>
<sf:clientDateValidator required="true">
<h:inputText id="checkoutDate" value="#{booking.checkoutDate}" required="true">
<f:convertDateTime pattern="MM-dd-yyyy" timeZone="EST"/>
</h:inputText>
</sf:clientDateValidator>
<h:inputText id="checkoutDate" value="#{booking.checkoutDate}" required="true">
<f:convertDateTime pattern="MM-dd-yyyy" timeZone="EST"/>
</h:inputText>
</p>
</div>
</div>
@@ -116,9 +106,7 @@
</div>
<div class="span-7 last">
<p>
<sf:clientTextValidator required="true" regExp="[0-9]{16}" invalidMessage="A 16-digit credit card number is required.">
<h:inputText id="creditCard" value="#{booking.creditCard}" required="true"/>
</sf:clientTextValidator>
<h:inputText id="creditCard" value="#{booking.creditCard}"/>
</p>
</div>
</div>
@@ -128,9 +116,7 @@
</div>
<div class="span-7 last">
<p>
<sf:clientTextValidator required="true">
<h:inputText id="creditCardName" value="#{booking.creditCardName}" required="true"/>
</sf:clientTextValidator>
<h:inputText id="creditCardName" value="#{booking.creditCardName}"/>
</p>
</div>
</div>
@@ -150,14 +136,13 @@
</div>
</div>
<div>
<sf:validateAllOnClick>
<sf:commandButton id="proceed" action="proceed" processIds="*" value="Proceed"/>&#160;
</sf:validateAllOnClick>
<sf:commandButton id="cancel" value="Cancel" action="cancel"/>
<h:commandButton id="proceed" action="proceed" value="Proceed">
<f:ajax render=":bookingsFragment" execute="@form" />
</h:commandButton>&#160;
<h:commandButton id="cancel" value="Cancel" action="cancel" immediate="true" />
</div>
</fieldset>
</h:form>
</div>
</h:panelGroup>
</ui:define>
</ui:composition>

View File

@@ -3,7 +3,6 @@
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:sf="http://www.springframework.org/tags/faces"
template="/WEB-INF/layouts/standard.xhtml">
<ui:define name="content">
@@ -70,7 +69,7 @@
<div>
<h:commandButton id="confirm" value="Confirm" action="confirm"/>&#160;
<h:commandButton id="revise" value="Revise" action="revise"/>&#160;
<h:commandButton id="cancel" value="Cancel" action="cancel"/>
<h:commandButton id="cancel" value="Cancel" action="cancel" />
</div>
</fieldset>
</h:form>

View File

@@ -3,81 +3,78 @@
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:sf="http://www.springframework.org/tags/faces"
template="/WEB-INF/layouts/standard.xhtml">
<ui:define name="content">
<ui:fragment id="hotelSearchFragment">
<div id="hotelSearch">
<h2>Search Hotels</h2>
<span class="errors">
<h:messages globalOnly="true" />
</span>
<h:form id="mainForm" styleClass="inline">
<fieldset>
<div class="span-8">
<h:outputLabel for="searchString">Search String: </h:outputLabel>
<sf:clientTextValidator promptMessage="Search hotels by name, address, city, or zip.">
<h:inputText id="searchString" value="#{searchCriteria.searchString}" />
</sf:clientTextValidator>
</div>
<div class="span-6">
<h:outputLabel for="pageSize">Maximum Results: </h:outputLabel>
<h:selectOneMenu id="pageSize" value="#{searchCriteria.pageSize}">
<f:selectItems value="#{referenceData.pageSizeOptions}" />
</h:selectOneMenu>
</div>
<div class="span-3 last">
<sf:commandButton id="findHotels" value="Find Hotels" processIds="*" action="search" />
</div>
</fieldset>
</h:form>
</div>
</ui:fragment>
<h:panelGroup id="hotelSearch" layout="block">
<h2>Search Hotels</h2>
<span class="errors">
<h:messages globalOnly="true" />
</span>
<h:form id="mainForm" styleClass="inline">
<fieldset>
<div class="span-8">
<h:outputLabel for="searchString">Search String: </h:outputLabel>
<h:inputText id="searchString" value="#{searchCriteria.searchString}" />
</div>
<div class="span-6">
<h:outputLabel for="pageSize">Maximum Results: </h:outputLabel>
<h:selectOneMenu id="pageSize" value="#{searchCriteria.pageSize}">
<f:selectItems value="#{referenceData.pageSizeOptions}" />
</h:selectOneMenu>
</div>
<div class="span-3 last">
<h:commandButton id="findHotels" value="Find Hotels" action="search" >
<f:ajax render="@form" execute="@form" />
</h:commandButton>
</div>
</fieldset>
</h:form>
</h:panelGroup>
<ui:fragment id="bookingsFragment" rendered="#{currentUser!=null}">
<div id="bookingsSection">
<h2>Current Hotel Bookings</h2>
<h:outputText value="No Bookings Found" rendered="#{bookings.rowCount==0}"/>
<h:form id="bookingsForm" rendered="#{bookings.rowCount > 0}">
<h:dataTable id="bookings" styleClass="summary" value="#{bookings}" var="booking">
<h:column>
<f:facet name="header">Name</f:facet>
#{booking.hotel.name}
</h:column>
<h:column>
<f:facet name="header">Address</f:facet>
#{booking.hotel.address}
</h:column>
<h:column>
<f:facet name="header">City, State</f:facet>
#{booking.hotel.city}, #{booking.hotel.state}
</h:column>
<h:column>
<f:facet name="header">Check in date</f:facet>
<h:outputText value="#{booking.checkinDate}">
<f:convertDateTime dateStyle="short"/>
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">Check out date</f:facet>
<h:outputText value="#{booking.checkoutDate}">
<f:convertDateTime dateStyle="short"/>
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">Confirmation number</f:facet>
#{booking.id}
</h:column>
<h:column>
<f:facet name="header">Action</f:facet>
<sf:commandLink id="cancel" value="Cancel" processIds="bookingsFragment" action="cancelBooking" />
</h:column>
</h:dataTable>
</h:form>
</div>
</ui:fragment>
<h:panelGroup id="bookingsFragment" rendered="#{currentUser!=null}" layout="block">
<h2>Current Hotel Bookings</h2>
<h:outputText value="No Bookings Found" rendered="#{bookings.rowCount==0}"/>
<h:form id="bookingsForm" rendered="#{bookings.rowCount > 0}">
<h:dataTable id="bookings" styleClass="summary" value="#{bookings}" var="booking">
<h:column>
<f:facet name="header">Name</f:facet>
#{booking.hotel.name}
</h:column>
<h:column>
<f:facet name="header">Address</f:facet>
#{booking.hotel.address}
</h:column>
<h:column>
<f:facet name="header">City, State</f:facet>
#{booking.hotel.city}, #{booking.hotel.state}
</h:column>
<h:column>
<f:facet name="header">Check in date</f:facet>
<h:outputText value="#{booking.checkinDate}">
<f:convertDateTime dateStyle="short"/>
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">Check out date</f:facet>
<h:outputText value="#{booking.checkoutDate}">
<f:convertDateTime dateStyle="short"/>
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">Confirmation number</f:facet>
#{booking.id}
</h:column>
<h:column>
<f:facet name="header">Action</f:facet>
<h:commandLink id="cancel" value="Cancel" action="cancelBooking">
<f:ajax render=":bookingsFragment" />
</h:commandLink>
</h:column>
</h:dataTable>
</h:form>
</h:panelGroup>
</ui:define>
</ui:composition>

View File

@@ -24,20 +24,17 @@
</on-render>
<transition on="sort">
<set name="searchCriteria.sortBy" value="requestParameters.sortBy" />
<render fragments="hotels:searchResultsFragment" />
</transition>
<transition on="previous">
<evaluate expression="searchCriteria.previousPage()" />
<render fragments="hotels:searchResultsFragment" />
</transition>
<transition on="next">
<evaluate expression="searchCriteria.nextPage()" />
<render fragments="hotels:searchResultsFragment" />
</transition>
<transition on="select" to="reviewHotel">
<set name="flowScope.hotel" value="hotels.selectedRow" />
</transition>
<transition on="changeSearch" to="changeSearchCriteria" />
<transition on="changeSearch" to="enterSearchCriteria" />
</view-state>
<view-state id="reviewHotel">
@@ -50,15 +47,6 @@
<transition on="bookingConfirmed" to="finish" />
<transition on="bookingCancelled" to="enterSearchCriteria" />
</subflow-state>
<view-state id="changeSearchCriteria" view="enterSearchCriteria.xhtml" popup="true">
<on-entry>
<render fragments="hotelSearchFragment" />
</on-entry>
<transition on="search" to="reviewHotels">
<evaluate expression="searchCriteria.resetPage()"/>
</transition>
</view-state>
<end-state id="finish" />

View File

@@ -3,7 +3,6 @@
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:sf="http://www.springframework.org/tags/faces"
template="/WEB-INF/layouts/standard.xhtml">
<ui:define name="content">

View File

@@ -3,60 +3,60 @@
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:sf="http://www.springframework.org/tags/faces"
template="/WEB-INF/layouts/standard.xhtml">
<ui:define name="content">
<h:form id="hotels">
<h:form id="hotelResults">
<div>
<h2>Hotel Results</h2>
<p>
<sf:commandLink value="Change Search" action="changeSearch"/>
<h:commandLink value="Change Search" action="changeSearch"/>
</p>
<ui:fragment id="searchResultsFragment">
<div id="searchResults">
<h:outputText id="noHotelsText" value="No Hotels Found" rendered="#{hotels.rowCount == 0}"/>
<h:dataTable id="hotels" styleClass="summary" value="#{hotels}" var="h" rendered="#{hotels.rowCount > 0}">
<h:column>
<f:facet name="header">
<sf:commandLink id="sortByNameLink" action="sort" value="Name" processIds="*">
<f:param name="sortBy" value="name" />
</sf:commandLink>
</f:facet>
#{h.name}
</h:column>
<h:column>
<f:facet name="header">Address</f:facet>
#{h.address}
</h:column>
<h:column>
<f:facet name="header">
<sf:commandLink id="sortByCity" action="sort" value="City, State" processIds="*" >
<f:param name="sortBy" value="city" />
</sf:commandLink>
</f:facet>
#{h.city}, #{h.state}, #{h.country}
</h:column>
<h:column>
<f:facet name="header">Zip</f:facet>
#{h.zip}
</h:column>
<h:column>
<f:facet name="header">Action</f:facet>
<sf:commandLink id="viewHotelLink" value="View Hotel" action="select"/>
</h:column>
</h:dataTable>
<div class="buttonGroup">
<div class="span-3">
<sf:commandLink id="previousPageLink" value="Previous results" action="previous" rendered="#{searchCriteria.page > 0}"/>
</div>
<div class="span-15 last">
<sf:commandLink id="nextPageLink" value="More Results" action="next" rendered="#{not empty hotels and hotels.rowCount == searchCriteria.pageSize}"/>
</div>
</div>
<div id="searchResults">
<h:outputText id="noHotelsText" value="No Hotels Found" rendered="#{hotels.rowCount == 0}"/>
<h:dataTable id="hotels" styleClass="summary" value="#{hotels}" var="h" rendered="#{hotels.rowCount > 0}">
<h:column>
<f:facet name="header">
<h:commandLink id="sortByNameLink" action="sort" value="Name">
<f:param name="sortBy" value="name" />
<f:ajax render="hotels" />
</h:commandLink>
</f:facet>
#{h.name}
</h:column>
<h:column>
<f:facet name="header">Address</f:facet>
#{h.address}
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink id="sortByCity" action="sort" value="City, State">
<f:param name="sortBy" value="city" />
<f:ajax render="hotels" />
</h:commandLink>
</f:facet>
#{h.city}, #{h.state}, #{h.country}
</h:column>
<h:column>
<f:facet name="header">Zip</f:facet>
#{h.zip}
</h:column>
<h:column>
<f:facet name="header">Action</f:facet>
<h:commandLink id="viewHotelLink" value="View Hotel" action="select"/>
</h:column>
</h:dataTable>
<div class="buttonGroup">
<h:commandLink id="previousPageLink" value="Previous Results" action="previous" rendered="#{searchCriteria.page > 0}">
<f:ajax render="@form" />
</h:commandLink>
&nbsp;
<h:commandLink id="nextPageLink" value="More Results" action="next" rendered="#{not empty hotels and hotels.rowCount == searchCriteria.pageSize}">
<f:ajax render="@form" />
</h:commandLink>
</div>
</ui:fragment>
</div>
</div>
</h:form>
</ui:define>

View File

@@ -7,7 +7,7 @@
xmlns:sf="http://www.springframework.org/tags/faces"
contentType="text/html" encoding="UTF-8">
<html>
<head>
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring Faces: Hotel Booking Sample Application</title>
<sf:includeStyles/>
@@ -18,7 +18,7 @@
<![endif]-->
<link rel="stylesheet" href="${request.contextPath}/styles/booking.css" type="text/css" media="screen" />
<ui:insert name="headIncludes"/>
</head>
</h:head>
<body class="tundra">
<div id="page" class="container">
<div id="header">

View File

@@ -17,7 +17,7 @@ input[type=submit] {
color: #fff;
background: #fff url(../images/btn.bg.gif) 0 0 repeat-x;
border-style: none;
margin:0.4em 0;
margin:0.4em 0.4em 0.4em 0;
height: 1.8em;
}