Using RichFaces a4j:jsFunction – sending an Ajax request from any JavaScript

There are four components in the a4j: tag library which enable you to send an Ajax request. They are a4j:commandButton, a4j:commandLink, a4j:support, and a4j:poll. All provide rather specific functionality. For example, a4j:commandButton will generate an HTML button that fires an Ajax request. a4j:commandLink will do the same but generates a link. a4j:support is always attached to another JSF component to enable sending an Ajax request based on some event supported by the parent component. a4j:poll which allows sending Ajax requests periodically. There is one more tag called a4j:jsFunction. This tags gives you a lot of power and flexibility. a4j:jsFunction lets you send an Ajax request from any user-defined JavaScript function. It can be a custom function or from any component-event as well. The good news is that it works just like any other tags I listed above, it has all the same attributes such as reRender, action, actionListener, bypassUpdates, ajaxSingle and so on.

Suppose you would like to send an Ajax request when the mouse moves over some plain HTML content on the page, in other words, when mouseover event occurs. We can’t use a4j:support because it can only be attached to another JSF component. One option is to write a custom JavaScript function that would fire an Ajax request, include any parameters from the page and of course participate in JSF life cycle. It’s probably not something we want to, right? We don’t do it with a4j:commandButton, so why would be suddenly write such JavaScript function? Well, as it turns out we don’t need to do it because a4j:jsFunction provides exactly what we need.

When we place a4j:jsFunction on a page, a JavaScript function will be rendered that fires a regular Ajax request, not much different than we use a4j:commandButton or a4j:support tags. All we need to do is just call this function.


   
Espresso Cappuccino Tea

In above code we call what appears to be a regular JavaScript function named setdrink(..). In fact it is a regular JavaScript function. It’s defined via a4j:jsFunction tag. This is what the tag rendered on the page:


//

Notice that setdrink(..) takes two parameters. These parameters are passed to the server using a4j:actionparam tag. The name in a4j:actionparam is not important but should be set to something. The order is important. In other wordds, the value of the first parameters to the JavaScript function will be set into #{drink.bean} property in backing bean. Finally reRender attribute is used in the same way as with any other tag.

The managed bean looks like this:

public class Bean {
   private String drink;
   private String bgColor;
   // getters and setters
}

Here is one more example:


   
   
   
   

Nothing is stopping us from doing something like this:


function sendAjaxForm(){
   // custom code here
   fireAjax();
}


   
   
   
   

If there was an action you wanted to invoke, then a4j:jsFunction would look like this:


Let’s look at another example.


   
      
	
	
	
      
      
	
      
   


In above example, when the list changes an Ajax request is fired and rich:dataList component is updated to show the new list. This is just an example to illustrate how a4j:jsFunction works. I’m guessing that most developers would just nest a4j:support tag to achieve the same result:


	
	
	
           

If you were not sure how a4j:jsFunction tag works, I hope this posts makes it all clear. The tag is actually very simple, it works just like all other tags that fire an Ajax request but also provides a lot of flexibility. It’ s now possible to fire an Ajax request from any custom JavaScript function or client event without having to write a single line of JavaScr

11 thoughts on “Using RichFaces a4j:jsFunction – sending an Ajax request from any JavaScript

  1. Hi Max,
    any idea why

    would be throwing
    javax.faces.FacesException: java.lang.IllegalArgumentException: ValueBinding for UISelectMany must be of type List or Array at org.ajax4jsf.component.UIDataAdaptor.iterate(UIDataAdaptor.java:1027)

    it renders the page fine, but when you try to copy a value from left to right it throws exception.

    Map<String, List> mySelects = new HashMap<String, List>();
    Map<String, List> myResults = new HashMap<String, List>();

    classConverter is a no op

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
    return value;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
    return value.toString();
    }

    on top of that it works fine on Tomact but not on Weblogic 10.3. I know I should chase up the Weblogic support:), but thought to try you first

  2. Hi Max,

    In the above tag for event attribute i wanna give another event also based

    on two events i should call the one java method and so do some task

    here my question is: How i need to pass more than one event for one

    component???

    can i give like this ????

    Thanks

  3. I’ve been trying to do something similar, with no luck. My goal is to have a RichFaces menu item which will open up another browser window. The trick is that, first, I want to dynamically construct the URL in my bean. Here are the main pieces of my code:

    (in MyBean) :
    public String getUrl() {
    String url = xxxx;
    return url;
    }

    This code, as is, doesn’t do anything. The bean method never gets called, and no new window appears. If I change menuItem to use onclick=”openUrl()”, then I do get a new window right away… and then myBean is called (too late for my new window, which is empty.)

  4. @Tom: I don’t think you need to use a4j:jsFunction as it will fire another Ajax request to the server. From the menu, re-render the dynamically created URL and then in oncomplete to open it. Hope this helps.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s