JBoss Rich Faces SVN: r1853 - trunk/samples/richfaces-demo/src/main/webapp/richfaces/ajaxAttributes.
by richfaces-svn-commits@lists.jboss.org
Author: SergeySmirnov
Date: 2007-07-25 18:32:25 -0400 (Wed, 25 Jul 2007)
New Revision: 1853
Modified:
trunk/samples/richfaces-demo/src/main/webapp/richfaces/ajaxAttributes/usage.xhtml
Log:
demo left panel look-n-feel updated
Modified: trunk/samples/richfaces-demo/src/main/webapp/richfaces/ajaxAttributes/usage.xhtml
===================================================================
--- trunk/samples/richfaces-demo/src/main/webapp/richfaces/ajaxAttributes/usage.xhtml 2007-07-25 22:24:02 UTC (rev 1852)
+++ trunk/samples/richfaces-demo/src/main/webapp/richfaces/ajaxAttributes/usage.xhtml 2007-07-25 22:32:25 UTC (rev 1853)
@@ -24,6 +24,7 @@
<b>reRender</b> is a key attribute. It allows to point to the area(s) on the page that
should be updated as a response on Ajax interaction. The value of the reRender
attribute is an id of the the JSF component or the id list. This is a simple example:
+ </p>
<div class="esample">
<pre>
@@ -36,7 +37,6 @@
.....
</pre>
</div>
- </p>
<p>
reRender uses <a target="_blank" href="http://java.sun.com/javaee/javaserverfaces/1.2_MR1/docs/api/javax/faces/c...">
UIComponent.findComponent()</a> algorithm (with some additional exceptions)
@@ -45,7 +45,8 @@
Therefore, from your side, you can shortcut the way how fast the component is
found if you mentioned it more precisely. The following example show the difference
in approaches (both buttons will work successfully):
- <div class="esample">
+ </p>
+ <div class="esample">
<pre>
.....
<h:form id="form1">
@@ -66,13 +67,21 @@
</f:subview>
</pre>
</div>
- </p>
+
<p>
You can use JSF EL expression as a value of the reRender attribute. It might be property of
types Set, Collection, Array or simple String. The EL for reRender is resolved right before the
Render Response phase. So, you can calculate what should be re-rendered on any previous
phase during the Ajax request processing.
</p>
+ <p>Most common problem with using reRender is pointing it to the component that has a
+ 'rendered' attribute. Note, that JSF does not mark the place in the browser DOM where the outcome
+ of the component should be placed in case the 'rendered' condition returns false. Therefore,
+ after the component becomes rendered during the Ajax request, RichFaces deliveres the rendered
+ code to the client, but does not update the page, because the place for update is inknown.
+ You need to point to one of the parent component that has no 'rendered' attribute. As an
+ alternative, you can wrap the component with a4j:outputPanel layout="none".
+ </p>
<p>
<b>ajaxRendered</b> attribute of the a4j:outputPanel set to true allows to define the
area of the page that will be re-rendered even it is not pointed in the reRender attribute
@@ -82,7 +91,7 @@
</p>
<div class="esample">
<pre>
-<a4j:outputPanel ajaxRendered="true">
+<a4j:outputPanel <b>ajaxRendered="true"</b>>
<h:messages />
</a4j:outputPanel>
</pre>
@@ -92,16 +101,116 @@
attribute. limitToList = "false" means to update only the area(s) that mentioned in the
reRender attribute explicitly. All output panels with ajaxRendered="true" will be ignored.
</p>
+ <h1 class="hsample">Queue and Traffic Flood Protection</h1>
+ <p>
+ <b>eventsQueue</b> attribute defines the name of the queue that will be used to order upcomming Ajax
+ requests. By default, RichFaces does not queue Ajax requests. If events are produced
+ simultaneously, they will come to the server simultaniously. JSF implementations
+ (especially, the very first ones) doe not guaranty that the request comes first will be
+ served or pass the JSF lifecycle first. The order how the server side data
+ will be modified in case of simultanious request might be unpredictable.
+ Using eventsQueue attribute allows to avoid possible mess. Define the queue name explicitly,
+ if you expect an intensive Ajax traffic in your application.
+ </p>
+ <p>
+ The next request posted in the same queue will wait until the previos one is not
+ processed and Ajax response returns back if the eventsQueue attribute is defined. In
+ addition, Richfaces starts to remove from the queue the 'similar' requests. 'Similar' are
+ the requests that produced by the same event. For example, you have the following code,
+ only the newest request will be sent to the server if user types very fast and typed
+ the several characters already before the previous Ajax response is back.
+ </p>
+<div class="esample">
+ <pre>
+<h:inputText value="<span>#</span>{userBean.name}">
+ <a4j:support event="onkeyup" <b>eventsQueue="foo"</b> reRender="bar" />
+</h:inputText>
+ </pre>
+ </div>
+ <p><b>requestDelay</b> attribute defines the time (in ms.) that request will be wait in
+ the queue before it is ready to be sent. When the delay time is over, the request will be
+ sent to the server or removed if the newest 'similar' request is in queue already .
+ </p>
+ <p><b>ignoreDupResponses</b> attributes orders to ignore the Ajax response produced by the
+ request if the newest 'similar' request is in the queue already. ignoreDupResponses="true"
+ does not cancel the request while it is processed on the server, but just allows to
+ avoid unnssesary updates on the client side if the response loses the actuality.
+ </p>
+ <p>Defining the eventsQueue along with requestDelay allows to protect against unnssesary
+ traffic flood and syncronizes the order of Ajax requests. If you have several source of
+ Ajax requests, you can define the same queue name there. This might be very helpful if
+ you have Ajax components that invoke request asynchronously from the ones produced by
+ events from users. For example a4j:poll or a4j:push. In case the requests from such
+ components modify the same data, the syncronization might be very helpful.</p>
+ <h1 class="hsample">Data Processing Options</h1>
+ <p>RichFaces uses form based appoach for sending Ajax request. This means each time, when
+ user click an Ajax button or a4j:poll produces asynchronous request, the data from the closest
+ JSF form is submitted behalf of XMLHTTPRequest object. The form data contains the values
+ from the form input element and auxiliary information such as state saving data</p>
+ <p>
+ <b>ajaxSingle</b> attribute when it equals true directs to include only the value of
+ current component (along with f:param or a4j:action param values if any) to the request
+ map. In case of a4j:support, it will be the value of the parent component.
+ </p>
+ <p> Note, that ajaxSingle="true" reduces the upcomming traffic, but does not
+ prevent decoding other input components on the server side. Some JSF component,
+ such as h:selectOneMenu do recognize the missing in the request map value as
+ a null value and try to pass the validation process with failed result. So,
+ use a4j:region to limit the part of the component tree that will be processed
+ on the server side when it needs.
+ </p>
+ <p><b>immediate</b> attribute has the same purpose as for any other non-JSF component.
+ The default ActionListener should be executed immediately (i.e. during Apply Request
+ Values phase of the request processing lifecycle), rather than waiting until the
+ Invoke Application phase. Using immediate="true" is one of the way how to have the one
+ data model values updated when the other cannot be updated because of problem with
+ passing the Validation phase successfully. This might be important inside the
+ h:dataTable like components where using a4j:region is impossible due to the
+ h:dataTable component architecture.
+ </p>
+ <p><b>bypassUpdates</b> attribute allows to bypass the Update Model phase. It
+ might be useful if you need to check the user input against the available validator,
+ but not to update the model with those data. Note, that the a action will be invoked
+ at the end of the Validation phase only if the Validation phase is passed successfully.
+ The listeners of the Application phase will not be invoked in any case.
+ </p>
+ <h1 class="hsample">Action and Navigation</h1>
+ <p>Ajax component is similar to any other non-Ajax JSF component like h:commandButton. It
+ allows to submit the form. You can use action and actionListener attribute to invoke
+ the action method and define the action event.
+ </p>
+ <p>
+ <b>action</b> method must return null if you want to have an Ajax response with partual page
+ update. This is regular mode that names: "Ajax Request generates Ajax Response". In case of
+ action does not return null, but the action outcome that match one of the navigation rule, RichFaces
+ starts to work in "Ajax Request generates Non-Ajax Response" mode.
+ This mode might be helpful in two major cases:
+ </p>
+ <ol>
+ <li>RichFaces allows to organize a page flow inside the a4j:include component. This is a typical
+ scenario for Wizard like behavior. The new content is rendered inside the a4j:include area. The
+ content is taken from the navigation rule of the faces configuration file (usually, the faces-config.xml).
+ Note, that the content of the "wizard" is not isolated from the rest of the page. The included
+ page should not have own f:view (it does not matter if you use facelets). You need to have an
+ Ajax component inside the a4j:include to navigate between the wizard pages. Otherwize, the whole
+ page update will be performed.
+ </li>
+ <li>If you want to involve the server side validators and navigate to the next page only if
+ the Validation phase is passed succesefully, you can replace h:commandButton with a4j:commandButton
+ and point to the action method that navigate to the next page. In case of Validation process failed,
+ the partial page update will occure and user will see the error message. Otherwize, the application
+ proceeds to the next page. Be sure, you define <redirect /%gt; option for the navigation rule to
+ avoid the memory leaks.
+ </li>
+ </ol>
+
- <div class="sample-container" >
- </div>
</ui:define>
<ui:define name="sources">
- Here is a fragment of page sources for the given example:
- <iframe src="${facesContext.externalContext.requestContextPath}/richfaces/ajaxAttributes/source/usage.html" class="source_frame"/>
+ <span style="display:none"/>
</ui:define>
</ui:composition>
</html>