Author: ishabalov
Date: 2007-08-01 23:10:37 -0400 (Wed, 01 Aug 2007)
New Revision: 2000
Added:
trunk/samples/local-value-demo/
trunk/samples/local-value-demo/pom.xml
trunk/samples/local-value-demo/src/
trunk/samples/local-value-demo/src/main/
trunk/samples/local-value-demo/src/main/java/
trunk/samples/local-value-demo/src/main/java/org/
trunk/samples/local-value-demo/src/main/java/org/richfaces/
trunk/samples/local-value-demo/src/main/java/org/richfaces/demo/
trunk/samples/local-value-demo/src/main/java/org/richfaces/demo/localvalue/
trunk/samples/local-value-demo/src/main/java/org/richfaces/demo/localvalue/Data.java
trunk/samples/local-value-demo/src/main/resources/
trunk/samples/local-value-demo/src/main/webapp/
trunk/samples/local-value-demo/src/main/webapp/META-INF/
trunk/samples/local-value-demo/src/main/webapp/META-INF/MANIFEST.MF
trunk/samples/local-value-demo/src/main/webapp/WEB-INF/
trunk/samples/local-value-demo/src/main/webapp/WEB-INF/faces-config.xml
trunk/samples/local-value-demo/src/main/webapp/WEB-INF/lib/
trunk/samples/local-value-demo/src/main/webapp/WEB-INF/web.xml
trunk/samples/local-value-demo/src/main/webapp/css/
trunk/samples/local-value-demo/src/main/webapp/css/common.css
trunk/samples/local-value-demo/src/main/webapp/images/
trunk/samples/local-value-demo/src/main/webapp/index.jsp
trunk/samples/local-value-demo/src/main/webapp/pages/
trunk/samples/local-value-demo/src/main/webapp/pages/local-value-demo.xhtml
trunk/samples/local-value-demo/src/test/
trunk/samples/local-value-demo/src/test/java/
Log:
Added sample for local value
Property changes on: trunk/samples/local-value-demo
___________________________________________________________________
Name: svn:ignore
+ target
.settings
.classpath
.project
Added: trunk/samples/local-value-demo/pom.xml
===================================================================
--- trunk/samples/local-value-demo/pom.xml (rev 0)
+++ trunk/samples/local-value-demo/pom.xml 2007-08-02 03:10:37 UTC (rev 2000)
@@ -0,0 +1,22 @@
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>samples</artifactId>
+ <groupId>org.richfaces</groupId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.richfaces</groupId>
+ <artifactId>local-value-demo</artifactId>
+ <packaging>war</packaging>
+ <name>local-value-demo Maven Webapp</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui</artifactId>
+ <version>3.1.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <finalName>local-value-demo</finalName>
+ </build>
+</project>
\ No newline at end of file
Added:
trunk/samples/local-value-demo/src/main/java/org/richfaces/demo/localvalue/Data.java
===================================================================
--- trunk/samples/local-value-demo/src/main/java/org/richfaces/demo/localvalue/Data.java
(rev 0)
+++
trunk/samples/local-value-demo/src/main/java/org/richfaces/demo/localvalue/Data.java 2007-08-02
03:10:37 UTC (rev 2000)
@@ -0,0 +1,44 @@
+package org.richfaces.demo.localvalue;
+
+import javax.faces.component.UIInput;
+
+public class Data {
+ private UIInput component;
+ private String creditCard;
+ private String myCreadtCard = "1234567887654321";
+ private String myCreditCardName = "Visa";
+ public String getMyCreditCardName() {
+ return myCreditCardName;
+ }
+ public void setMyCreditCardName(String myCreditCardName) {
+ this.myCreditCardName = myCreditCardName;
+ }
+ public UIInput getComponent() {
+ return component;
+ }
+ public void setComponent(UIInput component) {
+ this.component = component;
+ }
+ public String getCreditCard() {
+ return creditCard;
+ }
+ public void setCreditCard(String creditCard) {
+ this.creditCard = creditCard;
+ }
+ public String getMyCreadtCard() {
+ return myCreadtCard;
+ }
+ public void setMyCreadtCard(String myCreadtCard) {
+ this.myCreadtCard = myCreadtCard;
+ }
+ public String useMyCreditCard_incorrect() {
+ setCreditCard(getMyCreadtCard());
+ return null;
+ }
+ public String useMyCreditCard_correct() {
+ setCreditCard(getMyCreadtCard());
+ getComponent().setSubmittedValue(null);
+ getComponent().setValue(null);
+ return null;
+ }
+}
Added: trunk/samples/local-value-demo/src/main/webapp/META-INF/MANIFEST.MF
===================================================================
--- trunk/samples/local-value-demo/src/main/webapp/META-INF/MANIFEST.MF
(rev 0)
+++ trunk/samples/local-value-demo/src/main/webapp/META-INF/MANIFEST.MF 2007-08-02
03:10:37 UTC (rev 2000)
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
Property changes on: trunk/samples/local-value-demo/src/main/webapp/WEB-INF
___________________________________________________________________
Name: svn:ignore
+ .faces-config.xml.jsfdia
Added: trunk/samples/local-value-demo/src/main/webapp/WEB-INF/faces-config.xml
===================================================================
--- trunk/samples/local-value-demo/src/main/webapp/WEB-INF/faces-config.xml
(rev 0)
+++ trunk/samples/local-value-demo/src/main/webapp/WEB-INF/faces-config.xml 2007-08-02
03:10:37 UTC (rev 2000)
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces
Config 1.0//EN"
+
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
+<faces-config>
+ <managed-bean>
+ <managed-bean-name>data</managed-bean-name>
+
<managed-bean-class>org.richfaces.demo.localvalue.Data</managed-bean-class>
+ <managed-bean-scope>request</managed-bean-scope>
+ </managed-bean>
+</faces-config>
Added: trunk/samples/local-value-demo/src/main/webapp/WEB-INF/web.xml
===================================================================
--- trunk/samples/local-value-demo/src/main/webapp/WEB-INF/web.xml
(rev 0)
+++ trunk/samples/local-value-demo/src/main/webapp/WEB-INF/web.xml 2007-08-02 03:10:37 UTC
(rev 2000)
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+ <description>Local Value demo</description>
+ <display-name>local-value-demo</display-name>
+ <context-param>
+ <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
+ <param-value>.xhtml</param-value>
+ </context-param>
+ <context-param>
+ <param-name>facelets.REFRESH_PERIOD</param-name>
+ <param-value>2</param-value>
+ </context-param>
+ <context-param>
+ <param-name>facelets.DEVELOPMENT</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <context-param>
+ <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
+ <param-value>server</param-value>
+ </context-param>
+ <context-param>
+ <param-name>com.sun.faces.validateXml</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <context-param>
+ <param-name>com.sun.faces.verifyObjects</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.ajax4jsf.SKIN</param-name>
+ <param-value>blueSky</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
+ <param-value>com.sun.facelets.FaceletViewHandler</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <filter>
+ <display-name>Ajax4jsf Filter</display-name>
+ <filter-name>ajax4jsf</filter-name>
+ <filter-class>org.ajax4jsf.FastFilter</filter-class>
+ </filter>
+ <filter-mapping>
+ <filter-name>ajax4jsf</filter-name>
+ <servlet-name>Faces Servlet</servlet-name>
+ <dispatcher>FORWARD</dispatcher>
+ <dispatcher>REQUEST</dispatcher>
+ <dispatcher>INCLUDE</dispatcher>
+ </filter-mapping>
+ <servlet>
+ <servlet-name>Faces Servlet</servlet-name>
+ <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>*.jsf</url-pattern>
+ </servlet-mapping>
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ </login-config>
+</web-app>
Added: trunk/samples/local-value-demo/src/main/webapp/css/common.css
===================================================================
--- trunk/samples/local-value-demo/src/main/webapp/css/common.css
(rev 0)
+++ trunk/samples/local-value-demo/src/main/webapp/css/common.css 2007-08-02 03:10:37 UTC
(rev 2000)
@@ -0,0 +1,66 @@
+.samples {
+ vertical-align: top;
+}
+.source {
+ text-align: left;
+ font-family: monospace;
+ font-size: 12px;
+ font-weight: normal;
+ border-width: 1px;
+ border-style: solid;
+ margin-left: 30px;
+ margin-right: 30px;
+ padding: 10px;
+ background-color: #FFFF92;
+ border-color: #A7A700;
+}
+.legend {
+ text-align: justify;
+ font-family: Arial;
+ font-weight: normal;
+ font-size: 12px;
+ vertical-align: top;
+ padding-left: 20px;
+ padding-top: 0px;
+}
+.legend H3 {
+ text-decoration: underline;
+}
+
+.sample-panel {
+ width:500px;
+ height:150px
+}
+.grid {
+ width: 100%;
+}
+.formLeft {
+ padding-bottom: 5px;
+ padding-top: 5px;
+ padding-right: 5px;
+ font-size: 12px;
+ text-align: right;
+ width: 250px;
+}
+.formRight {
+ text-align: left;
+}
+.input {
+ font-size: 12px;
+ font-weight: bold;
+ border: none;
+ border-bottom-width: 2px;
+ border-bottom-style: solid;
+ font-family: Arial;
+}
+.output {
+ font-size: 12px;
+ font-weight: bold;
+ font-family: Arial;
+}
+.command {
+ text-decoration: none;
+ font-size: 12px;
+ font-weight: bold;
+ cursor: pointer;
+}
Added: trunk/samples/local-value-demo/src/main/webapp/index.jsp
===================================================================
--- trunk/samples/local-value-demo/src/main/webapp/index.jsp (rev
0)
+++ trunk/samples/local-value-demo/src/main/webapp/index.jsp 2007-08-02 03:10:37 UTC (rev
2000)
@@ -0,0 +1,7 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head></head>
+ <body>
+ <jsp:forward page="/pages/local-value-demo.jsf" />
+ </body>
+</html>
\ No newline at end of file
Added: trunk/samples/local-value-demo/src/main/webapp/pages/local-value-demo.xhtml
===================================================================
--- trunk/samples/local-value-demo/src/main/webapp/pages/local-value-demo.xhtml
(rev 0)
+++ trunk/samples/local-value-demo/src/main/webapp/pages/local-value-demo.xhtml 2007-08-02
03:10:37 UTC (rev 2000)
@@ -0,0 +1,131 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml"
+
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:a4j="http://richfaces.org/a4j"
+
xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;
charset=UTF-8"/>
+<title>
+ Local Value demo
+</title>
+<style type="text/css">
+.input {
+ border-bottom-color: #{a4jSkin.panelBorderColor};
+}
+</style>
+</head>
+<body>
+<a4j:loadStyle src="/css/common.css" />
+<span style="display:none">${a4j.version}</span>
+<h:panelGrid columns="2" columnClasses="samples,legend">
+<h:panelGroup>
+<rich:panel id="bad" styleClass="sample-panel">
+ <f:facet name="header">
+ Example of INCORRECT approach to the problem
+ </f:facet>
+ <h:form>
+ <a4j:outputPanel ajaxRendered="true">
+ <h:message for="bad_input" />
+ </a4j:outputPanel>
+ <h:panelGrid columns="2" styleClass="grid"
columnClasses="formLeft,formRight">
+ <h:outputText value="Enter credit card number:"/>
+ <h:inputText id="bad_input" value="#{data.creditCard}"
styleClass="input"/>
+ <h:outputText value="Or use your pre-defined credit card:"/>
+ <a4j:commandLink immediate="true"
action="#{data.useMyCreditCard_incorrect}" reRender="bad"
styleClass="command" value="#{data.myCreditCardName}"/>
+ <h:outputText value="Your entered credit card number:"/>
+ <h:outputText value="#{data.creditCard}"
styleClass="output"/>
+ </h:panelGrid>
+ </h:form>
+</rich:panel>
+<rich:spacer height="5px"/>
+<rich:panel id="good" styleClass="sample-panel">
+ <f:facet name="header">
+ Example of CORRECT approach to the problem
+ </f:facet>
+ <h:form>
+ <a4j:outputPanel ajaxRendered="true">
+ <h:message for="good_input" />
+ </a4j:outputPanel>
+ <h:panelGrid columns="2" columnClasses="formLeft,formRight">
+ <h:outputText value="Enter credit card number:"/>
+ <h:inputText id="good_input" value="#{data.creditCard}"
binding="#{data.component}" styleClass="input"/>
+ <h:outputText value="Or use your pre-defined credit card:"/>
+ <a4j:commandLink immediate="true"
action="#{data.useMyCreditCard_correct}" reRender="good"
styleClass="command" value="#{data.myCreditCardName}"/>
+ <h:outputText value="Your entered credit card number:"/>
+ <h:outputText value="#{data.creditCard}"
styleClass="output"/>
+ </h:panelGrid>
+ </h:form>
+</rich:panel>
+</h:panelGroup>
+<h:panelGroup styleClass="legend">
+<h3>Use case</h3>
+<p>
+I have an input field where I can enter Credit Card Number. At the same time I have some
pre-defined CC in a system, which I can choose. When I click on command link with id of
pre-defined CC, it value propagated to input.
+</p>
+<h3>Simple solution</h3>
+<p>
+So my first solution is simple. The idea is to have an action behind command link and
assign pre-defined value to CC Number.
+</p>
+<h3>Page Sources</h3>
+<p class="source">
+<h:outputText value="Enter credit card number:"/><br/>
+<h:inputText value="+{data.creditCard}"/><br/>
+<h:outputText value="Or use your pre-defined credit
card:"/><br/>
+<a4j:commandLink immediate="true"
action="+{data.useMyCreditCard}" reRender="..."
value="+{data.myCreditCardName}"/><br/>
+<h:outputText value="Your entered credit card
number:"/><br/>
+<h:outputText value="+{data.creditCard}"
styleClass="output"/><br/>
+</p>
+<h3>Bean Source (getters/setters removed)</h3>
+<p class="source">
+public String useMyCreditCard() {<br/>
+<rich:spacer width="20px"/>setCreditCard(getMyCreadtCard());<br/>
+<rich:spacer width="20px"/>return null;<br/>
+}<br/>
+</p>
+</h:panelGroup>
+</h:panelGrid>
+<h:panelGroup styleClass="legend">
+<h3>Problem</h3>
+<p>
+However, soon I discover that my simple solution does not works. The reason is simple:
inputText is a little bit more complicated than you think. In addition to value binding it
has two more values inside: submittedValue and localValue. Both are used during a request
processing. The goal is simple – whenever feasible inputText display value that was
entered by user, not value from model. The most obvious case – when validation error
occurs. The general rule is – submitted value is what come from http request. After
conversion and validation submittedValue is cleared and localValue assigned. After update
model localValue is cleared also. During rendering component looks for submittedValue
first, if any exists, than it used for rendering. If no submittedValue present – that
localValue will be considered. If no localValue exists – than value binding will be
evaluated to obtain value from model.
+</p>
+<p>
+So, valid solution is simple – you need to reset submitted and local value in component.
There are many different ways to do so. In my example I'm using the most
straightforward approach – use component binding and API to reset values.
+</p>
+<h3>Valid Page Sources</h3>
+<p class="source">
+<h:outputText <b>binding="+{data.component}"</b>
value="Enter credit card number:"/><br/>
+<h:inputText value="+{data.creditCard}"/><br/>
+<h:outputText value="Or use your pre-defined credit
card:"/><br/>
+<a4j:commandLink immediate="true"
action="+{data.useMyCreditCard}" reRender="..."
value="+{data.myCreditCardName}"/><br/>
+<h:outputText value="Your entered credit card
number:"/><br/>
+<h:outputText value="+{data.creditCard}"
styleClass="output"/><br/>
+</p>
+<h3>Valid Bean Source (getters/setters removed)</h3>
+<p class="source">
+public String useMyCreditCard() {<br/>
+<rich:spacer width="20px"/>setCreditCard(getMyCreadtCard());<br/>
+<b>
+<rich:spacer
width="20px"/>getComponent().setSubmittedValue(null);<br/>
+<rich:spacer width="20px"/>getComponent().setValue(null); //This is
actually the local value!<br/>
+</b>
+<rich:spacer width="20px"/>return null;<br/>
+}<br/>
+</p>
+<h3>Success</h3>
+<p>
+Hopefully now my solution works!
+</p>
+<h3>Conclusion</h3>
+<p>
+You need to be careful with input components. In some cases you have to be aware of their
complex internal structures.
+</p>
+<p>
+My example is based on <b>JSF 1.2 RI</b> and <b>Facelets</b>. You
can download it from <a href="#">here</a>.
+</p>
+</h:panelGroup>
+</body>
+</html>