Help

About RichFaces 4 Overview

This series of articles is intended to give you a short overview of all the work we've done in extending JSF 2 with advanced features and components.

Core Ajax components

The first part of the RichFaces components migration process contained mostly the a4j library core components, which provide enhanced Ajax functionality. I believe that most of the community knows the base RichFaces Ajax components well and has worked with them for a long time. So basically there is not much to cover in this area. It should be easy to use them in the same manner as it was in RichFaces 3.3.x, but considering the JSF 2 Ajax definitions standards. The first article is intended to provide a short usage overview for them and to describe the RichFaces 4 Ajax requests queuing mechanism, which is designed for easy optimizations of your page/server transactions.

Why do we need them?

So let's start from the beginning. Why we need our Ajax components in a JSF 2 world where Ajax is standardized and provided out of the box in implementations? The answer is simple: JSF is an open standard which provides basic functionality leaving much place for customizations and extensions. They have taken many implementation ideas from RichFaces 3.x and other frameworks and added common base functionality into the JSF 2 standard. However, there are still many use-cases with which implementation requires additional work from a JSF 2 developer. RichFaces intends to provide extensions which will cover most of the features that are absent in JSF but required for real-world web applications.

Simple Ajax usage

Let’s explore the simplest Ajax repeater example in order to start with queuing functionality:

<h:inputText id="myinput" value="#{queueBean.text}">
	<a4j:ajax event="keyup" render="outtext"/>
</h:inputText>  
<h:outputText value="#{queueBean.text}" id="outtext"/>

In this sample, as you can see from snippet, an Ajax request will be generated for every keyup event in the input text and the ''outtext'' will be updated with the new value. If you start typing fast and look at the firebug console, for example, you will see numerous requests rise every time you type a letter.

Good news: JSF 2 provides an Ajax requests queue out of the box! So the frequent requests will not became concurrent, and will be sent one by one and processed in the right order.

But hey, I still need to reduce the requests count. In order to do that I still need to work manually with the timer, and to send my requests using the Ajax API as in the example shown at this article .

Good news again: the RichFaces Ajax requests queue solves the problem, and you can just specify the requests combining rules and pre-sending waiting time declaratively with the page tags.

Let's queue them

The next code snippet defines queue for form or view (depending on where defined):

<a4j:queue requestDelay="1500"/>

requestDelay specifies the time interval in milliseconds before the next request can be sent to server.

So now if we type without delays (or with delays smaller that 1.5 seconds) and then check the requests console, we will see that there is only one request with the latest information that was sent. RichFaces Ajax requests are grouped by using the requestGroupingId option, which is equal to the client id of the component that initiated requests(by default). It’s pretty simple and highly useful for such cases.

A more complex case. How do you group requests from different sources?

Now let's imagine the registration form which contains a few inputs which are validated via Ajax immediately after any changes. Using queue as shown above, a single request appears per input. But what if I don't want to send them at all while the user is entering information and validate the form only when he stops to check the result? It's still simple to do. We just need to add attachQueue with additional parameter passed to the queue:

<h:form>

<a4j:queue requestDelay="1500"/>

<h:inputText id="myinput" value="#{queueBean.text}">
    <a4j:ajax event="keyup" render="fooMessages" execute="@form">
        <a4j:attachQueue requestGroupingId=”registrationForm”/>	
    </a4j:ajax>
</h:inputText>  
<h:inputText id="myinput2" value="#{queueBean.text2}">
    <a4j:ajax event="keyup" render="fooMessages" execute="@form">
        <a4j:attachQueue requestGroupingId="registrationForm"/>	
    </a4j:ajax>
</h:inputText>  
</h:form>
Note: In RichFaces 4 we moved all queue related attributes (requestDelay, requestGroupingId, ignoredupResponse and so on) to a special attachQueue tag in order to keep the components itself cleaner.

The previous code could be rewritten to become much simpler, as we could use wrapping behavior instead of nested:

<h:form>
<a4j:queue requestDelay="1500"/>

<a4j:ajax event="keyup" render="fooId1" execute="@form">
    <a4j:attachQueue requestGroupingId="registrationForm"/>	

    <h:inputText id="myinput" value="#{queueBean.text}"/>
    <h:inputText id="myinput2" value="#{queueBean.text2}"/>
</a4j:ajax
</h:form>

That's it. Now requests from those inputs are similar from the RichFaces queue's point of view. If the user types fast among different inputs, only a single validation request for form will be raised after 1.5 seconds of inactivity. So now optimizing requests sent to the server becomes as simple as defining them!

What's next on our way

In next releases we plan to add full support of named queues and possible implementation of the 3.3.x ignoreDupResponces feature(not ready for now as we rely at JSF script during updates and can't skip the update currently). Also we will discuss possible benefits and implementation ways of logical queues - which will not just pass the request to common queue with additional parameters but preprocess them in local logical queue before.

Get more information and try it on your own with:
7 comments:
 
25. Jun 2010, 15:04 CET | Link

Hi Ilya,

In Richfaces 4.0, can I forget f:ajax and use aj4:ajax directly as in Richfaces 3? As I understood, a4j:ajax extends f:ajax.

 
25. Jun 2010, 17:21 CET | Link

Some future features could be designed carying about a4j:ajax only. We do our best to design the features compatible with standard requests. Now our queue supports f:ajax in general. But attachQueue - do not works for f:ajax requests. So, it's better to use a4j:ajax as we can't guarantie that full compatibility will be possible to keep for all features.. And there are almost no difference between behaviors of this tags. Single and the main one - we still evaluate the execute and render for the ajax request at server side while JSF relies at params came from javascript call from client.

16. Jul 2010, 03:09 CET | Link
Prakash Shanmugam | shanerdprakash(AT)gmail.com

Hi

I am using A4J commandbutton as image and I want to uset he tooltip. Can u share views.

Regards Prakash Shanmugam

24. Jul 2010, 14:06 CET | Link
Amrit Pandey | pandey.amrit(AT)in.com
Click HELP for text formatting instructions. Then edit this text and check the preview.


 Hi Ilya,
    Actually we are shifting our project dependency from (JSF1.2 & Richfaces 3.x) to (JSF2.0 & richfaces 4.0). In few codes we have used *rich:modalPanel* which is not working with richfaces 4.0.
Please suggest what tag can we use on the place of *rich:modalPanel* to get the same result.

Thanks in advance.
Amrit pandey
26. Jul 2010, 10:48 CET | Link

Hi Prakash and Amrit! Sorry for the delay caused by my vacation :)

Amrit - modal panel already in 4.x - it's just called rich:popup. check readme-ui to get full list of components. Prakash - tooltip still not there unfortunatelly.

Actually I want to say to both of you that - we shifted the release process to use time boxed releases. And now the releases will came every month (maybe 5 weeks.). So you could continue RF 4 usage and get updates and new components every month.

 
06. Aug 2010, 06:11 CET | Link
Hi, Is there any way to delay only a particular request(ajax) for a4j component click; I don't want to delay all the request at the form level. Only particular commandLink/commandButton.
Why? B's I'm sending the first ajax request to the server which will process the data using EJB3.0; If I send the next ajax request immediately it throwing some muxer error (thread error), then weblogic server became like dead state.

So I need to delay the second request with 5sec. Is it possible? If anybody have some idea pls help me.

Thanks,
John
 
13. Aug 2010, 12:25 CET | Link
Jérôme JADOULLE
I suppose this is the kind of things that could be achieved with <a4j:region>. Don't know if it actually works (and I have no real knowledge of RichFaces 4 for now) but that may be a pointer...
Hope it helps.
Post Comment