Author: msorokin
Date: 2009-05-07 13:35:57 -0400 (Thu, 07 May 2009)
New Revision: 14075
Added:
trunk/docs/realworld_app_guide/en/src/main/docbook/includes/button.xml
trunk/docs/realworld_app_guide/en/src/main/docbook/includes/datascroller.xml
Modified:
trunk/docs/realworld_app_guide/en/src/main/docbook/includes/validators.xml
Log:
added button and datascroller chapters
https://jira.jboss.org/jira/browse/RF-5768
Added: trunk/docs/realworld_app_guide/en/src/main/docbook/includes/button.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/includes/button.xml
(rev 0)
+++ trunk/docs/realworld_app_guide/en/src/main/docbook/includes/button.xml 2009-05-07
17:35:57 UTC (rev 14075)
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section id="Button">
+ <title>How the button is created and how it acts
+ </title>
+ <para>
+
+ Due to specific design of the buttons in the Photo Album application, it's
necessary to clarify some design and development points about the button. The button is
visually represented by Facelets template stored in the
<property>button.xhtml</property> file.
+
+ </para>
+ <para>Please have a look at the content of the file:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
+
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:c="http://java.sun.com/jstl/core"
+
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
+
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
+
xmlns:a4j="http://richfaces.org/a4j"
xmlns:richx="http://richfaces.org/richx">
+ <a4j:loadScript src="/scripts/buttons.js" />
+ <richx:actionMapper>
+ <a4j:outputPanel layout="block" style="#{style}"
+ styleClass="photoalbumButton #{styleClass}" lang="#{lang}"
dir="#{dir}"
+ title="#{title}" rendered="#{empty rendered or rendered}"
+ onmousedown="RF_RW_DEMO.toPressed(this)"
onmouseup="RF_RW_DEMO.toReleased(this)"
+ onmouseout="RF_RW_DEMO.toReleased(this)">
+
+ <h:graphicImage value="/img/shell/button.png" alt="" />
+ <h:graphicImage value="/img/shell/button_press.png"
+ style="display: none;" alt="" />
+
+ <div>#{value}</div>
+
+ <a4j:commandButton accesskey="#{accesskey}"
+ ajaxSingle="#{ajaxSingle}" alt="#{alt}" type="image"
image="/img/shell/spacer.gif"
+ actionListener="#{mappedActionListener}"
action="#{mappedAction}"
+ bypassUpdates="#{bypassUpdates}" data="#{data}"
disabled="#{disabled}"
+ eventsQueue="#{eventsQueue}" focus="#{focus}"
ignoreDupResponses="#{ignoreDupResponses}"
+ immediate="#{immediate}" limitToList="#{limitToList}"
+ onbeforedomupdate="#{onbeforedomupdate}" timeout="#{timeout}"
+ tabindex="#{tabindex}" status="#{status}"
similarityGroupingId="#{similarityGroupingId}"
+ reRender="#{reRender}" requestDelay="#{requestDelay}"
process="#{process}"
+ oncomplete="#{oncomplete}" onblur="#{onblur}"
onclick="#{onclick}"
+ ondblclick="#{ondblclick}" onfocus="#{onfocus}"
onkeydown="#{onkeydown}"
+ onkeypress="#{onkeypress}" onkeyup="#{onkeyup}"
onmousedown="#{onmousedown}"
+ onmousemove="#{onmousemove}" onmouseout="#{onmouseout}"
onmouseover="#{onmouseover}"
+ onmouseup="#{onmouseup}" />
+
+ </a4j:outputPanel>
+ </richx:actionMapper>
+
+</ui:composition>
+<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
+
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:c="http://java.sun.com/jstl/core"
+
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
+
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
+
xmlns:a4j="http://richfaces.org/a4j"
xmlns:richx="http://richfaces.org/richx">
+ <a4j:loadScript src="/scripts/buttons.js" />
+ <richx:actionMapper>
+ <a4j:outputPanel layout="block" style="#{style}"
+ styleClass="photoalbumButton #{styleClass}" lang="#{lang}"
dir="#{dir}"
+ title="#{title}" rendered="#{empty rendered or rendered}"
+ onmousedown="RF_RW_DEMO.toPressed(this)"
onmouseup="RF_RW_DEMO.toReleased(this)"
+ onmouseout="RF_RW_DEMO.toReleased(this)">
+
+ <h:graphicImage value="/img/shell/button.png" alt="" />
+ <h:graphicImage value="/img/shell/button_press.png"
+ style="display: none;" alt="" />
+
+ <div>#{value}</div>
+
+ <a4j:commandButton accesskey="#{accesskey}"
+ ajaxSingle="#{ajaxSingle}" alt="#{alt}" type="image"
image="/img/shell/spacer.gif"
+ actionListener="#{mappedActionListener}"
action="#{mappedAction}"
+ bypassUpdates="#{bypassUpdates}" data="#{data}"
disabled="#{disabled}"
+ eventsQueue="#{eventsQueue}" focus="#{focus}"
ignoreDupResponses="#{ignoreDupResponses}"
+ immediate="#{immediate}" limitToList="#{limitToList}"
+ onbeforedomupdate="#{onbeforedomupdate}" timeout="#{timeout}"
+ tabindex="#{tabindex}" status="#{status}"
similarityGroupingId="#{similarityGroupingId}"
+ reRender="#{reRender}" requestDelay="#{requestDelay}"
process="#{process}"
+ oncomplete="#{oncomplete}" onblur="#{onblur}"
onclick="#{onclick}"
+ ondblclick="#{ondblclick}" onfocus="#{onfocus}"
onkeydown="#{onkeydown}"
+ onkeypress="#{onkeypress}" onkeyup="#{onkeyup}"
onmousedown="#{onmousedown}"
+ onmousemove="#{onmousemove}" onmouseout="#{onmouseout}"
onmouseover="#{onmouseover}"
+ onmouseup="#{onmouseup}" />
+
+ </a4j:outputPanel>
+ </richx:actionMapper>
+
+</ui:composition><ui:composition
xmlns="http://www.w3.org/1999/xhtml"
+
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:c="http://java.sun.com/jstl/core"
+
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
+
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
+
xmlns:a4j="http://richfaces.org/a4j"
xmlns:richx="http://richfaces.org/richx">
+ <a4j:loadScript src="/scripts/buttons.js" />
+ <richx:actionMapper>
+ <a4j:outputPanel layout="block" style="#{style}"
+ styleClass="photoalbumButton #{styleClass}" lang="#{lang}"
dir="#{dir}"
+ title="#{title}" rendered="#{empty rendered or rendered}"
+ onmousedown="RF_RW_DEMO.toPressed(this)"
onmouseup="RF_RW_DEMO.toReleased(this)"
+ onmouseout="RF_RW_DEMO.toReleased(this)">
+
+ <h:graphicImage value="/img/shell/button.png" alt="" />
+ <h:graphicImage value="/img/shell/button_press.png"
+ style="display: none;" alt="" />
+
+ <div>#{value}</div>
+
+ <a4j:commandButton accesskey="#{accesskey}"
+ ajaxSingle="#{ajaxSingle}" alt="#{alt}" type="image"
image="/img/shell/spacer.gif"
+ actionListener="#{mappedActionListener}"
action="#{mappedAction}"
+ bypassUpdates="#{bypassUpdates}" data="#{data}"
disabled="#{disabled}"
+ eventsQueue="#{eventsQueue}" focus="#{focus}"
ignoreDupResponses="#{ignoreDupResponses}"
+ immediate="#{immediate}" limitToList="#{limitToList}"
+ onbeforedomupdate="#{onbeforedomupdate}" timeout="#{timeout}"
+ tabindex="#{tabindex}" status="#{status}"
similarityGroupingId="#{similarityGroupingId}"
+ reRender="#{reRender}" requestDelay="#{requestDelay}"
process="#{process}"
+ oncomplete="#{oncomplete}" onblur="#{onblur}"
onclick="#{onclick}"
+ ondblclick="#{ondblclick}" onfocus="#{onfocus}"
onkeydown="#{onkeydown}"
+ onkeypress="#{onkeypress}" onkeyup="#{onkeyup}"
onmousedown="#{onmousedown}"
+ onmousemove="#{onmousemove}" onmouseout="#{onmouseout}"
onmouseover="#{onmouseover}"
+ onmouseup="#{onmouseup}" />
+
+ </a4j:outputPanel>
+ </richx:actionMapper>
+
+</ui:composition>
+<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
+
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:c="http://java.sun.com/jstl/core"
+
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
+
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
+
xmlns:a4j="http://richfaces.org/a4j"
xmlns:richx="http://richfaces.org/richx">
+ <a4j:loadScript src="/scripts/buttons.js" />
+ <richx:actionMapper>
+ <a4j:outputPanel layout="block" style="#{style}"
+ styleClass="photoalbumButton #{styleClass}" lang="#{lang}"
dir="#{dir}"
+ title="#{title}" rendered="#{empty rendered or rendered}"
+ onmousedown="RF_RW_DEMO.toPressed(this)"
onmouseup="RF_RW_DEMO.toReleased(this)"
+ onmouseout="RF_RW_DEMO.toReleased(this)">
+
+ <h:graphicImage value="/img/shell/button.png" alt="" />
+ <h:graphicImage value="/img/shell/button_press.png"
+ style="display: none;" alt="" />
+
+ <div>#{value}</div>
+
+ <a4j:commandButton accesskey="#{accesskey}"
+ ajaxSingle="#{ajaxSingle}" alt="#{alt}" type="image"
image="/img/shell/spacer.gif"
+ actionListener="#{mappedActionListener}"
action="#{mappedAction}"
+ bypassUpdates="#{bypassUpdates}" data="#{data}"
disabled="#{disabled}"
+ eventsQueue="#{eventsQueue}" focus="#{focus}"
ignoreDupResponses="#{ignoreDupResponses}"
+ immediate="#{immediate}" limitToList="#{limitToList}"
+ onbeforedomupdate="#{onbeforedomupdate}" timeout="#{timeout}"
+ tabindex="#{tabindex}" status="#{status}"
similarityGroupingId="#{similarityGroupingId}"
+ reRender="#{reRender}" requestDelay="#{requestDelay}"
process="#{process}"
+ oncomplete="#{oncomplete}" onblur="#{onblur}"
onclick="#{onclick}"
+ ondblclick="#{ondblclick}" onfocus="#{onfocus}"
onkeydown="#{onkeydown}"
+ onkeypress="#{onkeypress}" onkeyup="#{onkeyup}"
onmousedown="#{onmousedown}"
+ onmousemove="#{onmousemove}" onmouseout="#{onmouseout}"
onmouseover="#{onmouseover}"
+ onmouseup="#{onmouseup}" />
+
+ </a4j:outputPanel>
+ </richx:actionMapper>
+
+</ui:composition>
+...]]></programlisting>
+ <para>
+ The <emphasis role="bold">
<property><richx:actionMapper></property></emphasis>
+ tag is covered in more detail further in the text. In brief, it's a special
tag developed deliberately to pass to the button a method expression of the action which
must be performed when the button is clicked.
+
+ </para>
+ <para>
+ To make sure the button works correctly we include the required JavaScript code that is
located in the button.js file using <code> <a4j:loadScript
src="/scripts/buttons.js" /> </code> component.
+ </para>
+ <para>
+ The button consists of several parts:
+ </para>
+ <itemizedlist>
+ <listitem><para>2 images (pressed and not
pressed)</para></listitem>
+ <listitem><para><div> element that displays the
button's text </para></listitem>
+ <listitem><para><emphasis
role="bold"><property><a4j:commandButton></property></emphasis>
that sends Ajax request to the server</para></listitem>
+
+ </itemizedlist>
+ <para>
+ These elements are wrapped by <emphasis
role="bold"><property><a4j:outputPanel></property></emphasis>
to adjust the look-and-feel.
+ </para>
+ <para>
+ In the application the button is used for example like this:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<richx:commandButton actionListener="#{authenticator.register(user)}"
reRender="mainform, headerPanel"
value="#{messages['user.register']}" />
+...]]></programlisting>
+ <para>
+ We can pass to the <emphasis
role="bold"><property><richx:commandButton></property></emphasis>
all required attributes, in the example only actionListener, reRender and value are
passed.
+ </para>
+ <para>
+ <emphasis
role="bold"><property><richx:commandButton></property></emphasis>
+ is a custom tag that is declared in the photoalbum-taglib.xml tag library:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<?xml version="1.0"?>
+<!DOCTYPE facelet-taglib PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
+ "facelet-taglib_1_0.dtd">
+<facelet-taglib>
+ <
namespace>http://richfaces.org/richx</namespace>
+ <tag>
+ <tag-name>commandButton</tag-name>
+ <source>templates/button.xhtml</source>
+ </tag>
+ <tag>
+ <tag-name>actionMapper</tag-name>
+ <handler-class>org.richfaces.photoalbum.util.ActionMapperTagHandler</handler-class>
+ </tag>
+</facelet-taglib>
+...]]></programlisting>
+ <para>
+ In order to use the <emphasis
role="bold"><property><richx:commandButton></property></emphasis>
on the page the namespace of the taglib must be declared:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
+ ...
+xmlns:richx="http://richfaces.org/richx">
+...]]></programlisting>
+ <para>
+ A more complex part of the button implementation, as we said earlier, is <emphasis
role="bold"><property><richx:actionMapper></property></emphasis>
which is also described in tablib. But it is not just a simple tag-template since it has
Facelets handler-class which specifies how it is handled when declared on the page. It is
created because Facelets templates do not allow to make the MethodExpression a
Facelets-template parameter. Please find below the code of the class(some irrelevant
details are omitted):
+ </para>
+ <programlisting role="JAVA"><![CDATA[...
+ public class ActionMapperTagHandler extends TagHandler {
+
+ private static final Class<?>[] ACTION_PARAM_TYPES = new Class[0];
+
+ private static final Class<?>[] ACTION_LISTENER_PARAM_TYPES = new Class[]
{ActionEvent.class};
+
+ private static final String ACTION = "action";
+
+ private static final String ACTION_LISTENER = "actionListener";
+
+ private static final String MAPPED_ACTION = "mappedAction";
+
+ private static final String MAPPED_ACTION_LISTENER = "mappedActionListener";
+
+ public ActionMapperTagHandler(TagConfig config) {
+ super(config);
+ }
+
+ private MethodExpression remap(FaceletContext faceletContext, String varName,
+ Class<?> expectedReturnType, Class<?>[] expectedParamTypes) {
+
+ MethodExpression result = null;
+
+ VariableMapper mapper = faceletContext.getVariableMapper();
+ ValueExpression valueExpression = mapper.resolveVariable(varName);
+ if (valueExpression != null) {
+ ExpressionFactory ef = faceletContext.getExpressionFactory();
+ ELContext elContext = faceletContext.getFacesContext().getELContext();
+
+ result = ef.createMethodExpression(elContext, valueExpression.getExpressionString(),
+ expectedReturnType, expectedParamTypes);
+ }
+
+ return result;
+ }
+
+ public void apply(FaceletContext ctx, UIComponent parent)
+ throws IOException, FacesException, FaceletException, ELException {
+
+ MethodExpression actionExpression = remap(ctx, ACTION, String.class,
ACTION_PARAM_TYPES);
+ MethodExpression actionListenerExpression = remap(ctx, ACTION_LISTENER, null,
ACTION_LISTENER_PARAM_TYPES);
+
+ if (actionExpression != null || actionListenerExpression != null) {
+ VariableMapper initialVarMapper = ctx.getVariableMapper();
+ try {
+ VariableMapperWrapper varMapper = new VariableMapperWrapper(initialVarMapper);
+
+ if (actionExpression == null) {
+ actionExpression = NOOP_ACTION_EXPRESSION;
+ }
+
+ varMapper.setVariable(MAPPED_ACTION,
+ ctx.getExpressionFactory().createValueExpression(actionExpression,
+ MethodExpression.class));
+
+ if (actionListenerExpression == null) {
+ actionListenerExpression = NOOP_ACTION_LISTENER_EXPRESSION;
+ }
+
+ varMapper.setVariable(MAPPED_ACTION_LISTENER,
+ ctx.getExpressionFactory().createValueExpression(actionListenerExpression,
+ MethodExpression.class));
+
+ ctx.setVariableMapper(varMapper);
+
+ nextHandler.apply(ctx, parent);
+
+ } finally {
+ ctx.setVariableMapper(initialVarMapper);
+ }
+ } else {
+ nextHandler.apply(ctx, parent);
+ }
+ }
+}
+
+...]]></programlisting>
+ <para>
+ You can find more infromation about Facelets, custom tags, taglibs, Facelets tag
handlers and Facelets templates here.
+ </para>
+</section>
Added: trunk/docs/realworld_app_guide/en/src/main/docbook/includes/datascroller.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/includes/datascroller.xml
(rev 0)
+++
trunk/docs/realworld_app_guide/en/src/main/docbook/includes/datascroller.xml 2009-05-07
17:35:57 UTC (rev 14075)
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section id="CustomDataScroller">
+ <title>Custom Data Scroller</title>
+ <para>
+ The custom data scroller implementation in the Photo Album application is basically
<emphasis
role="bold"><property><a4j:repeat></property></emphasis>
with the value attribute bound to <code>#{model.selectedAlbum.images}</code>,
which is a collection of images of the selected album and the <emphasis
role="bold"><property><rich:dataScroller>></property></emphasis>
component tied to the <emphasis
role="bold"><property><a4j:repeat></property></emphasis>
.
+ </para>
+
+ <para>
+ The source code you can find in the includes/images/imageScroller.xhtml file.
+ Now let's go deeper into the details. The main component here is <emphasis
role="bold"><property><a4j:repeat></property></emphasis>:
+
+ </para>
+
+ <programlisting role="XML"><![CDATA[...
+<a4j:repeat value="#{model.selectedAlbum.images}" rows="5"
+ var="img" id="repeat" rowKeyVar="rk">
+
+ <a4j:outputPanel layout="block"
+ styleClass="preview_box_photo_nav #{model.selectedImage == img ?
'preview_box_photo_current' : 'preview_box_photo_default'}">
+ <h:panelGroup layout="block"
styleClass="preview_box_photo_80">
+ <h:graphicImage styleClass="pr_photo_bg"
+ value="/img/shell/frame_photo_80.png" />
+ <h:panelGrid cellpadding="0" cellspacing="2">
+ <h:panelGroup layout="block">
+ <a4j:mediaOutput element="img"
+ createContent="#{imageLoader.paintImage}"
+ value="#{fileManager.transformPath(img.fullPath,
'_small80')}">
+ </a4j:mediaOutput>
+ <br />
+ </h:panelGroup>
+ </h:panelGrid>
+ <h:panelGroup layout="block" styleClass="photo_name">
+ <h:outputText value="#{img.name}" />
+ </h:panelGroup>
+ <h:panelGroup layout="block" styleClass="photo_data">
+ <h:outputText value="#{rk + 1}" />
+ </h:panelGroup>
+ </h:panelGroup>
+
+ <a4j:support event="onclick" rendered="#{model.selectedImage !=
img}"
+ reRender="mainArea,treePanel, imagesTable"
action="#{controller.showImage(img)}" />
+ </a4j:outputPanel>
+</a4j:repeat>
+...]]></programlisting>
+
+ <para>
+ Each element of the
+
+ <emphasis
role="bold"><property><a4j:repeat></property></emphasis>
has a corresponding <emphasis
role="bold"><property><a4j:outputPanel></property></emphasis>
with the <emphasis
role="bold"><property><a4j:mediaOutput></property></emphasis>
as a nested element. <emphasis
role="bold"><property><a4j:mediaOutput></property></emphasis>
renders the thumbnail of the image. As the rows attribute is set to "5"
(<code>rows="5"</code>), only 5 images are displayed on the page at
a time.
+
+ </para>
+
+ <para>
+ As you've noticed, the currently selected image in the data scroller has
different style, namely: a red frame around thumbnail, which is implemented with this
code:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<a4j:outputPanel layout="block"
+styleClass="preview_box_photo_nav #{model.selectedImage == img ?
'preview_box_photo_current' : 'preview_box_photo_default'}">
+...]]></programlisting>
+ <para>
+ As you can see from the code snippet,
+ identification of whether the currently selected image is the same image displayed by
the <emphasis
role="bold"><property><a4j:repeat></property></emphasis>
is performed in the styleClass, if it returns "true", different style
is applied.
+ </para>
+ <para>
+ Each <emphasis
role="bold"><property><a4j:repeat></property></emphasis>
has a corresponding <emphasis
role="bold"><property><a4j:support></property></emphasis>
configured like this:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+ <a4j:support event="onclick"
+ rendered="#{model.selectedImage != img}"
+ reRender="mainArea,treePanel, imagesTable"
+ action="#{controller.showImage(img)}" />
+
+...]]></programlisting>
+
+ <para>
+ On every click <emphasis
role="bold"><property><a4j:support></property></emphasis>
calls <code> #{controller.showImage(img)}</code> method that sets the current
image, thumbnail of which has just been clicked on. For more details please see
Controller.java class.
+ </para>
+
+ <para>
+ To implement thumbnails scrolling effect the <emphasis
role="bold"><property><rich:datascroller></property></emphasis>
is attached to the <emphasis
role="bold"><property><a4j:repeat></property></emphasis>:
+ </para>
+
+ <programlisting role="XML"><![CDATA[...
+<rich:datascroller page="#{controller.getPage()}"
+ styleClass="image-scroller" lastPageMode="full"
for="repeat" reRender="imagesTable"
+ boundaryControls="hide" stepControls="hide">
+ <f:facet name="pages">
+ <h:outputText />
+ </f:facet>
+ <f:facet name="fastforward">
+ <h:graphicImage styleClass="image-scroller-right-arrow"
+ value="img/shell/arr_right.png" />
+ </f:facet>
+ <f:facet name="fastforward_disabled">
+ <h:graphicImage styleClass="image-scroller-right-arrow"
+ value="img/shell/arr_right_dis.png" />
+ </f:facet>
+ <f:facet name="fastrewind">
+ <h:graphicImage styleClass="image-scroller-left-arrow"
+ value="img/shell/arr_left.png" />
+ </f:facet>
+ <f:facet name="fastrewind_disabled">
+ <h:graphicImage styleClass="image-scroller-left-arrow"
+ value="img/shell/arr_left_dis.png" />
+ </f:facet>
+</rich:datascroller>
+
+...]]></programlisting>
+ <para>
+ The page attribute identifies which page should be displayed right now. For instance,
if you have only 20 images and the current image has the
12<superscript>th</superscript> index in the collection, then the
3<superscript>rd</superscript> page will be displayed:
+
+ </para>
+ <programlisting role="XML"><![CDATA[...
+public Integer getPage(){
+ final Integer index = model.getSelectedAlbum().getIndex(model.getSelectedImage());
+ return index / 5 + 1;
+ }
+
+...]]></programlisting>
+
+ <para>
+ The <code>lastPageMode="full" </code> attribute ensures
that 5 thumbnails are always shown on the page. If this attribute hadn't been
configured like this, in case the 19th thumbnail out of 20 had been selected then only 2
last thumbnails would have been displayed.
+ </para>
+
+ <para>
+ As you can see, <emphasis
role="bold"><property><rich:dataScroller></property></emphasis>
has a slightly different look-and-feel, the trick is in the redefinition of
<property>fastforward</property>,
<property>fastforward_disabled</property>,
<property>fastrewind</property> and
<property>fastrewind_disabled</property> facets on which places we display our
images. We didn't redefine other facets because they are not rendered to the page
which is achieved with <code>boundaryControls="hide"</code>
and <code>stepControls="hide</code> attributes of <emphasis
role="bold"><property><rich:dataSroller></property></emphasis>.
+ </para>
+ <para>
+ To get more details about the <emphasis
role="bold"><property><a4j:repeat></property></emphasis>
and <emphasis
role="bold"><property><rich:dataScroller></property></emphasis>
components please visit <ulink
url="http://livedemo.exadel.com/richfaces-demo/richfaces/dataTableSc...
Demo</ulink> web page and <ulink
url="http://www.jboss.org/file-access/default/members/jbossrichfaces...
>RichFaces Developer Guide</ulink>
+
+ </para>
+</section>
Modified: trunk/docs/realworld_app_guide/en/src/main/docbook/includes/validators.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/includes/validators.xml 2009-05-07
17:35:08 UTC (rev 14074)
+++ trunk/docs/realworld_app_guide/en/src/main/docbook/includes/validators.xml 2009-05-07
17:35:57 UTC (rev 14075)
@@ -3,9 +3,9 @@
<title>User Input Data Validation</title>
<para>
Validation of user input is a very frequent situation for a developer. RichFaces
library offers 3 component to get this job done:
- <emphasis
role="bold"><property><rich:beanValidator/></property></emphasis>,
<emphasis
role="bold"><property><rich:graphValidator/></property></emphasis>,
+ <emphasis
role="bold"><property><rich:beanValidator></property></emphasis>,
<emphasis
role="bold"><property><rich:graphValidator></property></emphasis>,
- and <emphasis
role="bold"><property><rich:ajaxValidator/></property></emphasis>.
The latter two components are used in the Photo Album application. <emphasis
role="bold"><property><rich:graphValidator/></property></emphasis>
is intended to validate the whole object or the graph of interrelated objects and the
validation occurs when the whole form is submitted. While <emphasis
role="bold"><property><rich:ajaxValidator/></property></emphasis>
validates only one input field or a value at a time, validation is activated upon some
event and adds interactivity to the application.
+ and <emphasis
role="bold"><property><rich:ajaxValidator></property></emphasis>.
The latter two components are used in the Photo Album application. <emphasis
role="bold"><property><rich:graphValidator></property></emphasis>
is intended to validate the whole object or the graph of interrelated objects and the
validation occurs when the whole form is submitted. While <emphasis
role="bold"><property><rich:ajaxValidator></property></emphasis>
validates only one input field or a value at a time, validation is activated upon some
event and adds interactivity to the application.
Both components use Hibernate validators which helps to locate validation logic in
one place, such approach is really helpful given that usually data validation logic is
stored in multiple places including UI pages and in Java code that interacts with a
database.
</para>
<para>
@@ -54,16 +54,16 @@
<para>
- <emphasis
role="bold"><property><rich:graphValidator/></property></emphasis>
validates the entity User object, in which restrictions are set with the help of
Hibernate annotations.
+ <emphasis
role="bold"><property><rich:graphValidator></property></emphasis>
validates the entity User object, in which restrictions are set with the help of
Hibernate annotations.
When the <emphasis role="bold" >Register</emphasis>
button is clicked on the <property>name, password, sex</property> etc. fields
are validated sequentially. In case of an error (for example, if a
<property>loginName</property> contains only on character and the annotation
restricts it to at least 3 characters to be typed in) a error message in red color is
displayed next to the input field and the request is aborted. If all values are valid
the <code>authenticator.register(user)</code> method will be invoked and the
user will be saved to the database.
</para>
<para>
- <emphasis
role="bold"><property><rich:ajaxValidator/></property></emphasis>
acts in a slightly different way, in our case it is attached to the
<code>user.birthDate</code> field. When the value of the field is changed and
the field loses focus it is immediately validated. If the input data is incorrect and
error message will displayed, which is a quick way to respond to user input errors and
avoid sending incorrect data to the server.
+ <emphasis
role="bold"><property><rich:ajaxValidator></property></emphasis>
acts in a slightly different way, in our case it is attached to the
<code>user.birthDate</code> field. When the value of the field is changed and
the field loses focus it is immediately validated. If the input data is incorrect and
error message will displayed, which is a quick way to respond to user input errors and
avoid sending incorrect data to the server.
</para>
<para>
- If you would like to get more details about the validators that RichFaces library
provides please visit <link
url="http://livedemo.exadel.com/richfaces-demo/richfaces/ajaxValidat...
Demo</link> web page and <link
url="http://www.jboss.org/file-access/default/members/jbossrichfaces...
>RichFaces Developer Guide</link>.
+ If you would like to get more details about the validators that RichFaces library
provides please visit <ulink
url="http://livedemo.exadel.com/richfaces-demo/richfaces/ajaxValidat...
Demo</ulink> web page and <ulink
url="http://www.jboss.org/file-access/default/members/jbossrichfaces...
>RichFaces Developer Guide</ulink>.
</para>
</section>