mvc sample working
This commit is contained in:
@@ -1,16 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<project name="swf-booking-jsf" default="dist">
|
||||
<project name="swf-booking-MVC" default="dist">
|
||||
|
||||
<property file="build.properties" />
|
||||
<property file="project.properties" />
|
||||
<property file="${common.build.dir}/build.properties" />
|
||||
<property file="${common.build.dir}/project.properties" />
|
||||
<property file="${user.home}/build.properties" />
|
||||
|
||||
<property name="build.web" value="true" />
|
||||
|
||||
|
||||
<import file="${common.build.dir}/common-targets.xml" />
|
||||
|
||||
<import file="${common.build.dir}/tomcat-targets.xml" />
|
||||
</project>
|
||||
@@ -1,13 +1,15 @@
|
||||
package org.springframework.webflow.samples.booking.flow.booking;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.springframework.binding.message.Messages;
|
||||
import org.springframework.binding.message.Severity;
|
||||
import org.springframework.webflow.action.MultiAction;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.beans.propertyeditors.CustomDateEditor;
|
||||
import org.springframework.validation.DataBinder;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.webflow.action.FormAction;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.samples.booking.app.Booking;
|
||||
import org.springframework.webflow.samples.booking.app.Hotel;
|
||||
@@ -18,8 +20,20 @@ import org.springframework.webflow.samples.booking.app.User;
|
||||
* definition at the appropriate points. Actions allow an externalized flow definition to delegate out to Java code to
|
||||
* perform processing.
|
||||
*/
|
||||
public class BookingActions extends MultiAction {
|
||||
public class BookingActions extends FormAction {
|
||||
|
||||
public BookingActions() {
|
||||
setFormObjectName("booking");
|
||||
setValidator(new BookingValidator());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initBinder(RequestContext context, DataBinder binder) {
|
||||
binder.setRequiredFields(new String[] { "checkinDate", "checkoutDate", "creditCard", "creditCardName" });
|
||||
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Create a new booking object and register it with the flow-managed entity manager. The booking is not actually
|
||||
* flushed to the database at this time; that only occurs when the booking flow reaches its "bookingAuthorized"
|
||||
@@ -31,37 +45,23 @@ public class BookingActions extends MultiAction {
|
||||
* @param context the current flow execution request context
|
||||
* @return success if the booking was created successfully.
|
||||
*/
|
||||
public Event createBooking(RequestContext context) {
|
||||
protected Object createFormObject(RequestContext context) throws Exception {
|
||||
Hotel hotel = (Hotel) context.getFlowScope().get("hotel");
|
||||
User user = (User) context.getConversationScope().get("user");
|
||||
Booking booking = new Booking(hotel, user);
|
||||
EntityManager em = (EntityManager) context.getFlowScope().get("entityManager");
|
||||
em.persist(booking);
|
||||
context.getFlowScope().put("booking", booking);
|
||||
return success();
|
||||
return booking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform some custom server-side validation on the flow-scoped Booking object updated by the booking form.
|
||||
*
|
||||
* It is expected a future milestone of Spring Web Flow 2.0 will add a Messages abstraction that decouples SWF
|
||||
* artifacts from environment-specific constructs like the FacesContext.
|
||||
* @param context the current flow execution request context
|
||||
* @return success if validation was successful, error if not
|
||||
*/
|
||||
public Event validateBooking(RequestContext context) {
|
||||
Booking booking = (Booking) context.getFlowScope().get("booking");
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.DAY_OF_MONTH, -1);
|
||||
if (booking.getCheckinDate().before(calendar.getTime())) {
|
||||
context.getMessageContext().addMessage(
|
||||
Messages.text("checkinDate", "Check in date must be a future date", Severity.ERROR));
|
||||
return error();
|
||||
} else if (!booking.getCheckinDate().before(booking.getCheckoutDate())) {
|
||||
context.getMessageContext().addMessage(
|
||||
Messages.text("checkoutDate", "Check out date must be later than check in date", Severity.ERROR));
|
||||
return error();
|
||||
public class BookingValidator implements Validator {
|
||||
|
||||
public boolean supports(Class clazz) {
|
||||
return Booking.class.equals(clazz);
|
||||
}
|
||||
return success();
|
||||
|
||||
public void validate(Object object, Errors errors) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,8 @@ package org.springframework.webflow.samples.booking.flow.main;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.webflow.action.MultiAction;
|
||||
import org.springframework.validation.DataBinder;
|
||||
import org.springframework.webflow.action.FormAction;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.samples.booking.app.Booking;
|
||||
@@ -15,7 +16,7 @@ import org.springframework.webflow.samples.booking.app.User;
|
||||
* at the appropriate points. Actions allow an externalized flow definition to delegate out to Java code to perform
|
||||
* processing.
|
||||
*/
|
||||
public class MainActions extends MultiAction {
|
||||
public class MainActions extends FormAction {
|
||||
|
||||
private BookingService bookingService;
|
||||
|
||||
@@ -56,8 +57,10 @@ public class MainActions extends MultiAction {
|
||||
* @param context the current flow execution request context
|
||||
* @return success
|
||||
*/
|
||||
public Event findHotels(RequestContext context) {
|
||||
public Event findHotels(RequestContext context) throws Exception {
|
||||
SearchCriteria search = (SearchCriteria) context.getFlowScope().get("searchCriteria");
|
||||
DataBinder binder = createBinder(context, search);
|
||||
doBind(context, binder);
|
||||
List<Hotel> hotels = bookingService
|
||||
.findHotels(search.getSearchString(), search.getPageSize(), search.getPage());
|
||||
context.getFlowScope().put("hotels", hotels);
|
||||
|
||||
@@ -54,5 +54,4 @@ public class SearchCriteria implements Serializable {
|
||||
public void setPage(int page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,10 @@
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
|
||||
version="2.4">
|
||||
|
||||
<listener>
|
||||
<listener-class>org.apache.tiles.web.startup.TilesListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<!-- The front controller of the Spring MVC Web application, responsible for handling all application requests -->
|
||||
<servlet>
|
||||
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
|
||||
|
||||
@@ -1,265 +0,0 @@
|
||||
/* Setup defaults since variable in browsers
|
||||
----------------------------------------------- */
|
||||
body, div, dd, dt, dl, img, ul, ol, li, p, h1, h2, h3, h4, h5, form, hr, fieldset {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
/* Element Defaults
|
||||
----------------------------------------------- */
|
||||
html {
|
||||
height: 100%;
|
||||
background-color: #9cac7c;
|
||||
}
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
body {
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: small;
|
||||
line-height: 1.25em;
|
||||
color: #362F2D;
|
||||
position: relative;
|
||||
width: 760px;
|
||||
height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
label {
|
||||
font-weight: bold;
|
||||
color: #5E5147;
|
||||
}
|
||||
input {
|
||||
border: 1px solid #C3BBB6;
|
||||
padding: 4px;
|
||||
margin: 5px 0;
|
||||
background: #fff url(../images/input.bg.gif) 0 0 repeat-x;
|
||||
}
|
||||
select {
|
||||
border: 1px solid #C3BBB6;
|
||||
padding: 4px;
|
||||
margin: 5px 0;
|
||||
background: #fff url(../images/input.bg.gif) 0 0 repeat-x;
|
||||
}ol, ul {
|
||||
margin: 10px 0px 10px 6px;
|
||||
}
|
||||
li {
|
||||
margin: 10px 12px;
|
||||
}
|
||||
fieldset {
|
||||
border: 0;
|
||||
}
|
||||
/* Layout
|
||||
----------------------------------------------- */
|
||||
#document {
|
||||
padding: 0 1px;
|
||||
background: #fff url(../images/bg.gif) 0 0 repeat-y;
|
||||
float: left;
|
||||
border-bottom: 1px solid #C3BBB6;
|
||||
}
|
||||
#header {
|
||||
float: left;
|
||||
width: 758px;
|
||||
height:36px;
|
||||
background-color: #414f23;
|
||||
}
|
||||
#container {
|
||||
float: left;
|
||||
width: 758px;
|
||||
background: url(../images/header.jpg) 0 0 repeat-x;
|
||||
}
|
||||
#sidebar {
|
||||
float: left;
|
||||
width: 205px;
|
||||
margin-left: 5px;
|
||||
margin-top: 185px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
#content {
|
||||
float: left;
|
||||
width: 448px;
|
||||
margin-top: 195px;
|
||||
padding-top: 5px;
|
||||
background: #fff url(../images/cnt.bg.gif) 0 0 repeat-x;
|
||||
}
|
||||
#footer {
|
||||
clear: both;
|
||||
margin-top: 40px;
|
||||
float: left;
|
||||
padding: 20px;
|
||||
border-top: 1px solid #C3BBB6;
|
||||
background-color: #fff;
|
||||
width: 718px;
|
||||
text-align: right;
|
||||
}
|
||||
/* General
|
||||
----------------------------------------------- */
|
||||
input[type="submit"], input[type="button"] {
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
border: 1px solid #5D1414;
|
||||
height: 26px;
|
||||
background: #fff url(../images/btn.bg.gif) 0 0 repeat-x;
|
||||
border-style: none;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.entry {
|
||||
clear: both;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.entry .label {
|
||||
float: left;
|
||||
padding-top: 10px;
|
||||
padding-right: 5px;
|
||||
font-weight: bold;
|
||||
width: 150px;
|
||||
text-align: right;
|
||||
}
|
||||
.entry .output {
|
||||
float: left;
|
||||
width: 250px;
|
||||
padding-top: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
.entry .input {
|
||||
float: left;
|
||||
width: 250px;
|
||||
text-align: left;
|
||||
}
|
||||
/* Sidebar
|
||||
----------------------------------------------- */
|
||||
.notes {
|
||||
text-align: center;
|
||||
font-size: small;
|
||||
}
|
||||
.errors {
|
||||
font-size: small;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
color: #600;
|
||||
}
|
||||
.errors div {
|
||||
text-align: left;
|
||||
}
|
||||
.errors input {
|
||||
border: 1px solid #600;
|
||||
}
|
||||
.errors ul {
|
||||
list-style: none;
|
||||
}
|
||||
.buttonBox {
|
||||
text-align: center;
|
||||
padding: 5px 0;
|
||||
}
|
||||
#sidebar p {
|
||||
font-size: small;
|
||||
color: #8B7869;
|
||||
line-height: 150%;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
#sidebar li {
|
||||
font-size: small;
|
||||
color: #8B7869;
|
||||
}
|
||||
#sidebar h1 {
|
||||
line-height: normal;
|
||||
font-weight: bold;
|
||||
font-size: small;
|
||||
}
|
||||
/*
|
||||
#sidebar p:hover {
|
||||
color: #362F2D;
|
||||
}
|
||||
*/
|
||||
/* Content
|
||||
----------------------------------------------- */
|
||||
#content .section {
|
||||
float: left;
|
||||
width: 518px;
|
||||
padding: 15px 15px 0 10px;
|
||||
}
|
||||
#content .section h1 {
|
||||
font-family: "Trebuchet MS", Arial, sans-serif;
|
||||
line-height: normal;
|
||||
font-weight: normal;
|
||||
font-size: large;
|
||||
}
|
||||
#content .section p {
|
||||
line-height: 150%;
|
||||
padding: 10px 0;
|
||||
font-size: small;
|
||||
}
|
||||
#content table {
|
||||
width: 100%;
|
||||
border: 1px solid #D2C9C4;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
#content table caption {
|
||||
padding-bottom: 6px;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
}
|
||||
#content table thead th {
|
||||
border-left: 1px solid #D2C9C4;
|
||||
background: #fff url(../images/th.bg.gif) 0 100% repeat-x;
|
||||
border-bottom: 1px solid #D2C9C4;
|
||||
padding: 6px;
|
||||
text-align: left;
|
||||
font-size: small;
|
||||
}
|
||||
#content table tbody td {
|
||||
border-left: 1px solid #E4DBD5;
|
||||
padding: 4px;
|
||||
border-bottom: 1px solid #D2C9C4;
|
||||
font-size: 8pt;
|
||||
}
|
||||
#content dt {
|
||||
font-weight: bold;
|
||||
float: left;
|
||||
width: 33%;
|
||||
}
|
||||
#content dd {
|
||||
padding-left: 10px;
|
||||
float: left;
|
||||
width: 66%;
|
||||
}
|
||||
#radio table {
|
||||
border: 0px;
|
||||
}
|
||||
#radio table tr td {
|
||||
border: 0px;
|
||||
border-left: 0px;
|
||||
border-bottom: 0px;
|
||||
}
|
||||
#content .section .prev {
|
||||
float: left;
|
||||
width: 120px;
|
||||
}
|
||||
#content .section .next {
|
||||
float: left;
|
||||
}
|
||||
/* Header
|
||||
----------------------------------------------- */
|
||||
#title {
|
||||
float: left;
|
||||
padding: 10px 0 6px 15px;
|
||||
color: #e9efdb;
|
||||
}
|
||||
#status {
|
||||
color: #e9efdb;
|
||||
float: right;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: x-small;
|
||||
text-align: right;
|
||||
padding-top: 14px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
#status a {
|
||||
color: #e9efdb;
|
||||
text-decoration: none;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<flow xmlns="http://www.springframework.org/schema/webflow"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/webflow
|
||||
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">
|
||||
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
|
||||
|
||||
<attribute name="description" value="The flow that handles the process of booking a hotel for a user"/>
|
||||
|
||||
@@ -27,18 +27,16 @@
|
||||
<method-result name="hotel" scope="flow" />
|
||||
</bean-action>
|
||||
</render-actions>
|
||||
<transition on="book" to="createBooking" />
|
||||
<transition on="book" to="enterBookingDetails" />
|
||||
<transition on="cancel" to="cancel" />
|
||||
</view-state>
|
||||
|
||||
<action-state id="createBooking">
|
||||
<action method="createBooking" bean="bookingActions"/>
|
||||
<transition on="success" to="enterBookingDetails" />
|
||||
</action-state>
|
||||
|
||||
<view-state id="enterBookingDetails" view="bookingForm.jsp">
|
||||
<render-actions>
|
||||
<action method="setupForm" bean="bookingActions"/>
|
||||
</render-actions>
|
||||
<transition on="proceed" to="confirmBooking">
|
||||
<action method="validateBooking" bean="bookingActions" />
|
||||
<action method="bindAndValidate" bean="bookingActions" />
|
||||
</transition>
|
||||
<transition on="cancel" to="cancel" />
|
||||
</view-state>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
|
||||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
|
||||
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<tiles:insertTemplate template="/template.jsp">
|
||||
<tiles:putAttribute name="content">
|
||||
@@ -8,146 +11,124 @@
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h:form id="booking">
|
||||
<h:messages errorClass="errors" />
|
||||
<form:form id="booking" modelAttribute="booking">
|
||||
<form:errors path="*" cssClass="errors" />
|
||||
<fieldset>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Name:</div>
|
||||
<div class="output">#{hotel.name}</div>
|
||||
<div class="output">${hotel.name}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Address:</div>
|
||||
<div class="output">#{hotel.address}</div>
|
||||
<div class="output">${hotel.address}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">City, State:</div>
|
||||
<div class="output">#{hotel.city}, #{hotel.state}</div>
|
||||
<div class="output">${hotel.city}, ${hotel.state}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Zip:</div>
|
||||
<div class="output">#{hotel.zip}</div>
|
||||
<div class="output">${hotel.zip}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Country:</div>
|
||||
<div class="output">#{hotel.country}</div>
|
||||
<div class="output">${hotel.country}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Nightly rate:</div>
|
||||
<div class="output">
|
||||
<h:outputText value="#{hotel.price}">
|
||||
<f:convertNumber type="currency" currencySymbol="$"/>
|
||||
</h:outputText>
|
||||
<spring:bind path="hotel.price">${status.value}</spring:bind>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
<h:outputLabel for="checkinDate">Check In Date:</h:outputLabel>
|
||||
<label for="checkinDate">Check In Date:</label>
|
||||
</div>
|
||||
<div class="input">
|
||||
<sf:clientDateValidator allowBlank="false" msgDisplay="block" msgClass="errors">
|
||||
<h:inputText id="checkinDate" value="#{booking.checkinDate}" required="true">
|
||||
<f:convertDateTime pattern="MM/dd/yy" timeZone="EST"/>
|
||||
</h:inputText>
|
||||
</sf:clientDateValidator>
|
||||
<form:errors path="checkinDate" cssClass="errors"/>
|
||||
<form:input id="checkinDate" path="checkinDate"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
<h:outputLabel for="checkoutDate">Check Out Date:</h:outputLabel>
|
||||
<label for="checkoutDate">Check Out Date:</label>
|
||||
</div>
|
||||
<div class="input">
|
||||
<sf:clientDateValidator allowBlank="false" msgDisplay="block" msgClass="errors">
|
||||
<h:inputText id="checkoutDate" value="#{booking.checkoutDate}" required="true">
|
||||
<f:convertDateTime pattern="MM/dd/yy" timeZone="EST"/>
|
||||
</h:inputText>
|
||||
</sf:clientDateValidator>
|
||||
<form:errors path="checkoutDate" cssClass="errors"/>
|
||||
<form:input id="checkoutDate" path="checkoutDate"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
<h:outputLabel for="beds">Room Preference:</h:outputLabel>
|
||||
<label for="beds">Room Preference:</label>
|
||||
</div>
|
||||
<div class="input">
|
||||
<h:selectOneMenu id="beds" value="#{booking.beds}">
|
||||
<f:selectItem itemLabel="One king-size bed" itemValue="1"/>
|
||||
<f:selectItem itemLabel="Two double beds" itemValue="2"/>
|
||||
<f:selectItem itemLabel="Three beds" itemValue="3"/>
|
||||
</h:selectOneMenu>
|
||||
<form:select id="beds" path="beds">
|
||||
<form:option label="One king-size bed" value="1"/>
|
||||
<form:option label="Two double beds" value="2"/>
|
||||
<form:option label="Three beds" value="3"/>
|
||||
</form:select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
<h:outputLabel for="smoking">Smoking Preference:</h:outputLabel>
|
||||
<label for="smoking">Smoking Preference:</label>
|
||||
</div>
|
||||
<div id="radio" class="input">
|
||||
<h:selectOneRadio id="smoking" value="#{booking.smoking}" layout="pageDirection">
|
||||
<f:selectItem itemLabel="Smoking" itemValue="true"/>
|
||||
<f:selectItem itemLabel="Non Smoking" itemValue="false"/>
|
||||
</h:selectOneRadio>
|
||||
<form:radiobutton id="smoking" path="smoking" label="Smoking" value="true"/>
|
||||
<form:radiobutton path="smoking" label="Non Smoking" value="false"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
<h:outputLabel for="creditCard">Credit Card #:</h:outputLabel>
|
||||
<label for="creditCard">Credit Card #:</label>
|
||||
</div>
|
||||
<div class="input">
|
||||
<sf:clientNumberValidator allowBlank="false" allowNegative="false" allowDecimals="false" minLength="16" maxLength="16" msgDisplay="block" msgClass="errors">
|
||||
<h:inputText id="creditCard" value="#{booking.creditCard}" required="true"/>
|
||||
</sf:clientNumberValidator>
|
||||
<form:errors path="creditCard" cssClass="errors"/>
|
||||
<form:input id="creditCard" path="creditCard"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
<h:outputLabel for="creditCardName">Credit Card Name:</h:outputLabel>
|
||||
<label for="creditCardName">Credit Card Name:</label>
|
||||
</div>
|
||||
<div class="input">
|
||||
<sf:clientTextValidator allowBlank="false" msgDisplay="block" msgClass="errors">
|
||||
<h:inputText id="creditCardName" value="#{booking.creditCardName}" required="true"/>
|
||||
</sf:clientTextValidator>
|
||||
<form:errors path="creditCardName" cssClass="errors"/>
|
||||
<form:input id="creditCardName" path="creditCardName"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
<h:outputLabel for="creditCardExpiryMonth">Credit Card Expiry:</h:outputLabel>
|
||||
<label for="creditCardExpiryMonth">Credit Card Expirty:</label>
|
||||
</div>
|
||||
<div class="input">
|
||||
<h:selectOneMenu id="creditCardExpiryMonth" value="#{booking.creditCardExpiryMonth}">
|
||||
<f:selectItem itemLabel="Jan" itemValue="1"/>
|
||||
<f:selectItem itemLabel="Feb" itemValue="2"/>
|
||||
<f:selectItem itemLabel="Mar" itemValue="3"/>
|
||||
<f:selectItem itemLabel="Apr" itemValue="4"/>
|
||||
<f:selectItem itemLabel="May" itemValue="5"/>
|
||||
<f:selectItem itemLabel="Jun" itemValue="6"/>
|
||||
<f:selectItem itemLabel="Jul" itemValue="7"/>
|
||||
<f:selectItem itemLabel="Aug" itemValue="8"/>
|
||||
<f:selectItem itemLabel="Sep" itemValue="9"/>
|
||||
<f:selectItem itemLabel="Oct" itemValue="10"/>
|
||||
<f:selectItem itemLabel="Nov" itemValue="11"/>
|
||||
<f:selectItem itemLabel="Dec" itemValue="12"/>
|
||||
</h:selectOneMenu>
|
||||
<h:selectOneMenu id="creditCardExpiryYear" value="#{booking.creditCardExpiryYear}">
|
||||
<f:selectItem itemLabel="2005" itemValue="2005"/>
|
||||
<f:selectItem itemLabel="2006" itemValue="2006"/>
|
||||
<f:selectItem itemLabel="2007" itemValue="2007"/>
|
||||
<f:selectItem itemLabel="2008" itemValue="2008"/>
|
||||
<f:selectItem itemLabel="2009" itemValue="2009"/>
|
||||
</h:selectOneMenu>
|
||||
<form:select id="creditCardExpiryMonth" path="creditCardExpiryMonth">
|
||||
<form:option label="Jan" value="1"/>
|
||||
<form:option label="Feb" value="2"/>
|
||||
<form:option label="Mar" value="3"/>
|
||||
<form:option label="Apr" value="4"/>
|
||||
<form:option label="May" value="5"/>
|
||||
<form:option label="Jun" value="6"/>
|
||||
<form:option label="Jul" value="7"/>
|
||||
<form:option label="Aug" value="8"/>
|
||||
<form:option label="Sep" value="9"/>
|
||||
<form:option label="Oct" value="10"/>
|
||||
<form:option label="Nov" value="11"/>
|
||||
<form:option label="Dec" value="12"/>
|
||||
</form:select>
|
||||
<form:select path="creditCardExpiryYear">
|
||||
<form:option label="2007" value="1"/>
|
||||
<form:option label="2008" value="2"/>
|
||||
<form:option label="2009" value="3"/>
|
||||
</form:select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry errors">
|
||||
<h:messages globalOnly="true"/>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="label"> </div>
|
||||
<div class="input">
|
||||
<sf:validateAllOnClick>
|
||||
<h:commandButton id="proceed" action="proceed" value="Proceed"/>
|
||||
</sf:validateAllOnClick> 
|
||||
<h:commandButton id="cancel" immediate="true" value="Cancel" action="cancel"/>
|
||||
</div>
|
||||
<div class="buttonGroup">
|
||||
<input type="submit" name="_eventId_proceed" value="Proceed"/> 
|
||||
<input type="submit" name="_eventId_cancel" value="Cancel"/> 
|
||||
</div>
|
||||
</fieldset>
|
||||
</h:form>
|
||||
</form:form>
|
||||
</div>
|
||||
|
||||
</tiles:putAttribute>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
|
||||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
|
||||
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<tiles:insertTemplate template="/template.jsp">
|
||||
<tiles:putAttribute name="content">
|
||||
@@ -8,60 +11,54 @@
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h:form id="confirm">
|
||||
<form:form id="confirm" modelAttribute="booking">
|
||||
<fieldset>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Name:</div>
|
||||
<div class="output">#{hotel.name}</div>
|
||||
<div class="output">${hotel.name}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Address:</div>
|
||||
<div class="output">#{hotel.address}</div>
|
||||
<div class="output">${hotel.address}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">City, State:</div>
|
||||
<div class="output">#{hotel.city}, #{hotel.state}</div>
|
||||
<div class="output">${hotel.city}, ${hotel.state}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Zip:</div>
|
||||
<div class="output">#{hotel.zip}</div>
|
||||
<div class="output">${hotel.zip}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Country:</div>
|
||||
<div class="output">#{hotel.country}</div>
|
||||
<div class="output">${hotel.country}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Total payment:</div>
|
||||
<div class="output">
|
||||
<h:outputText value="#{booking.total}">
|
||||
<f:convertNumber type="currency"
|
||||
currencySymbol="$"/>
|
||||
</h:outputText>
|
||||
<div class="output">
|
||||
<spring:bind path="total">${status.value}</spring:bind>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Check In Date:</div>
|
||||
<div class="output"><h:outputText value="#{booking.checkinDate}"/></div>
|
||||
<div class="output"><spring:bind path="checkinDate">${status.value}</spring:bind></div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Check Out Date:</div>
|
||||
<div class="output"><h:outputText value="#{booking.checkoutDate}"/></div>
|
||||
<div class="output"><spring:bind path="checkoutDate">${status.value}</spring:bind></div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="field">
|
||||
<div class="label">Credit Card #:</div>
|
||||
<div class="output">#{booking.creditCard}</div>
|
||||
<div class="output">${booking.creditCard}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="label"> </div>
|
||||
<div class="input">
|
||||
<h:commandButton id="confirm" value="Confirm" action="confirm"/> 
|
||||
<h:commandButton id="revise" value="Revise" action="revise"/> 
|
||||
<h:commandButton id="cancel" value="Cancel" action="cancel"/>
|
||||
</div>
|
||||
<div class="buttonGroup">
|
||||
<input type="submit" name="_eventId_confirm" value="Confim"/> 
|
||||
<input type="submit" name="_eventId_revise" value="Revise"/> 
|
||||
<input type="submit" name="_eventId_cancel" value="Cancel"/> 
|
||||
</div>
|
||||
</fieldset>
|
||||
</h:form>
|
||||
</form:form>
|
||||
</div>
|
||||
|
||||
</tiles:putAttribute>
|
||||
</tiles:insertTemplate>
|
||||
</tiles:insertTemplate>
|
||||
@@ -1,4 +1,7 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
|
||||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
|
||||
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<tiles:insertTemplate template="/template.jsp">
|
||||
<tiles:putAttribute name="content">
|
||||
@@ -8,48 +11,45 @@
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="entry">
|
||||
<div class="label">Name:</div>
|
||||
<div class="output">#{hotel.name}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="label">Address:</div>
|
||||
<div class="output">#{hotel.address}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="label">City:</div>
|
||||
<div class="output">#{hotel.city}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="label">State:</div>
|
||||
<div class="output">#{hotel.state}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="label">Zip:</div>
|
||||
<div class="output">#{hotel.zip}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="label">Country:</div>
|
||||
<div class="output">#{hotel.country}</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<div class="label">Nightly rate:</div>
|
||||
<div class="output">
|
||||
<h:outputText value="#{hotel.price}">
|
||||
<f:convertNumber type="currency" currencySymbol="$"/>
|
||||
</h:outputText>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h:form id="hotel">
|
||||
<fieldset class="buttonBox">
|
||||
<h:commandButton id="book" action="book" value="Book Hotel"/> 
|
||||
<h:commandButton id="cancel" action="cancel" value="Back to Search"/>
|
||||
<form:form id="hotel" modelAttribute="hotel">
|
||||
<fieldset>
|
||||
<div class="field">
|
||||
<div class="label">Name:</div>
|
||||
<div class="output">${hotel.name}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">Address:</div>
|
||||
<div class="output">${hotel.address}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">City:</div>
|
||||
<div class="output">${hotel.city}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">State:</div>
|
||||
<div class="output">${hotel.state}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">Zip:</div>
|
||||
<div class="output">${hotel.zip}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">Country:</div>
|
||||
<div class="output">${hotel.country}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">Nightly rate:</div>
|
||||
<div class="output">
|
||||
<spring:bind path="price">${status.value}</spring:bind>
|
||||
</div>
|
||||
</div>
|
||||
<div class="buttonGroup">
|
||||
<input type="submit" name="_eventId_book" value="Book Hotel"/> 
|
||||
<input type="submit" name="_eventId_cancel" value="Back to Search"/> 
|
||||
</div>
|
||||
</fieldset>
|
||||
</h:form>
|
||||
</form:form>
|
||||
</div>
|
||||
|
||||
</titles:putAttribute>
|
||||
</tiles:putAttribute>
|
||||
</tiles:insertTemplate>
|
||||
@@ -8,7 +8,7 @@
|
||||
<form:form modelAttribute="searchCriteria">
|
||||
<div class="section">
|
||||
<span class="errors">
|
||||
<form:errors/>
|
||||
<form:errors path="*"/>
|
||||
</span>
|
||||
<h1>Search Hotels</h1>
|
||||
<fieldset>
|
||||
@@ -19,15 +19,11 @@
|
||||
<form:option label="10" value="10"/>
|
||||
<form:option label="20" value="20"/>
|
||||
</form:select>
|
||||
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}" />
|
||||
<input type="submit" class="button" name="_eventId_findHotels" value="Find Hotels" style="width: 165px; height: 15px;" />
|
||||
<input type="submit" class="button" name="_eventId_findHotels" value="Find Hotels" />
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<c:if test="#{hotels.empty == 0}">
|
||||
No Hotels Found
|
||||
</c:if>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -38,18 +34,14 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<c:forEach var="hotel" items="#{hotels}">
|
||||
<c:forEach var="hotel" items="${hotels}">
|
||||
<tr>
|
||||
<td>#{hotel.name}</td>
|
||||
<td>#{hotel.address}</td>
|
||||
<td>#{hotel.city}, #{hotel.state}, #{hotel.country}</td>
|
||||
<td>#{hotel.zip}</td>
|
||||
<td>${hotel.name}</td>
|
||||
<td>${hotel.address}</td>
|
||||
<td>${hotel.city}, ${hotel.state}, ${hotel.country}</td>
|
||||
<td>${hotel.zip}</td>
|
||||
<td>
|
||||
<c:url var="viewHotelLink">
|
||||
<c:param name="hotelId" value="#{hotel.id}"/>
|
||||
<c:param name="_flowExecutionKey" value="#{flowExecutionKey}" />
|
||||
</c:url>
|
||||
<a href="#{viewHotelLink}">View Hotel</a>
|
||||
<a href="${flowExecutionUrl}?_eventId=selectHotel&hotelId=${hotel.id}">View Hotel</a>
|
||||
</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
@@ -62,10 +54,6 @@
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<c:if test="#{bookings.empty}">
|
||||
No Bookings Found
|
||||
</c:if>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -79,20 +67,16 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<c:forEach var="booking" items="#{bookings}">
|
||||
<c:forEach var="booking" items="${bookings}">
|
||||
<tr>
|
||||
<td>#{booking.hotel.name}</td>
|
||||
<td>#{booking.hotel.address}</td>
|
||||
<td>#{booking.hotel.city}, #{booking.hotel.state}</td>
|
||||
<td>#{booking.checkinDate}</td>
|
||||
<td>#{booking.checkoutDate}</td>
|
||||
<td>#{booking.id}</td>
|
||||
<td>${booking.hotel.name}</td>
|
||||
<td>${booking.hotel.address}</td>
|
||||
<td>${booking.hotel.city}, ${booking.hotel.state}</td>
|
||||
<td>${booking.checkinDate}</td>
|
||||
<td>${booking.checkoutDate}</td>
|
||||
<td>${booking.id}</td>
|
||||
<td>
|
||||
<c:url var="cancelBookingLink">
|
||||
<c:param name="bookingId" value="#{booking.id}"/>
|
||||
<c:param name="_flowExecutionKey" value="#{flowExecutionKey}" />
|
||||
</c:url>
|
||||
<a href="#{cancelBookingLink}">Cancel</a>
|
||||
<a href="${flowExecutionUrl}?_eventId=cancelBooking&bookingId=${booking.id}">Cancel</a>
|
||||
</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<flow xmlns="http://www.springframework.org/schema/webflow"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/webflow
|
||||
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">
|
||||
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
|
||||
|
||||
<attribute name="description" value="The main flow of the application that handles searching for hotels to book"/>
|
||||
|
||||
|
||||
@@ -5,25 +5,35 @@
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>Spring Faces: Hotel Booking Sample Application</title>
|
||||
<link href="/swf-booking-jsf/css/screen.css" rel="stylesheet" type="text/css" />
|
||||
<tiles:insertAttribute name="headIncludes" />
|
||||
<style type="text/css" media="screen">
|
||||
@import url("/swf-booking-mvc/spring/resources/css-framework/css/tools.css");
|
||||
@import url("/swf-booking-mvc/spring/resources/css-framework/css/typo.css");
|
||||
@import url("/swf-booking-mvc/spring/resources/css-framework/css/forms.css");
|
||||
@import url("/swf-booking-mvc/spring/resources/css-framework/css/layout-navtop-localleft.css");
|
||||
@import url("/swf-booking-mvc/spring/resources/css-framework/css/layout.css");
|
||||
@import url("/swf-booking-mvc/spring/resources/css/booking.css");
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="document">
|
||||
<div id="header">
|
||||
<div id="title">Spring Faces: Hotel Booking Sample Application</div>
|
||||
<div id="status">
|
||||
Welcome #{user.name}
|
||||
<body class="tundra spring">
|
||||
<div id="page">
|
||||
<div id="header" class="clearfix spring">
|
||||
<div id="welcome">
|
||||
<div class="left">Spring Web Flow + Spring MVC: Hotel Booking Sample Application</div>
|
||||
<div class="right">
|
||||
Welcome, ${user.name}
|
||||
</div>
|
||||
</div>
|
||||
<div id="branding" class="spring">
|
||||
<img src="/swf-booking-mvc/spring/resources/images/header.jpg" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="container">
|
||||
<div id="sidebar">
|
||||
<div id="content" class="clearfix spring">
|
||||
<div id="local" class="spring">
|
||||
<a href="http://www.thespringexperience.com">
|
||||
<c:url value="/images/diplomat.jpg" />
|
||||
<img src="/swf-booking-mvc/spring/resources/images/diplomat.jpg"/>
|
||||
</a>
|
||||
<a href="http://www.thespringexperience.com">
|
||||
<c:url value="/images/tse.gif" />
|
||||
<img src="/swf-booking-mvc/spring/resources/images/tse.gif"/>
|
||||
</a>
|
||||
<p>
|
||||
The features illustrated in this sample are just the beginning.
|
||||
@@ -32,14 +42,15 @@
|
||||
December 12 - 15, 2007 at the Westin Diplomat in Hollywood, Florida.
|
||||
</p>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div id="main">
|
||||
<tiles:insertAttribute name="content" />
|
||||
</div>
|
||||
<div id="footer">
|
||||
<a href="http://www.springframework.org"><img src="/swf-booking-jsf/images/powered-by-spring.png" /></a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" class="clearfix spring">
|
||||
<a href="http://www.springframework.org">
|
||||
<img src="/swf-booking-mvc/spring/resources/images/powered-by-spring.png"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user