Sunday, 3 February 2013

Client Behavior functionality with JSF 2.x (part 1)

Introduction

One of the lesser know new features of JSF 2, is the ability to define some client behavior for a component in a reusable way. We all know the possibility to enhance a component with ajax, using the tag.  It is also based on the Client Behavior functionality but we can define our custom functionality.

Just as you can define a validator for an input field, you can define a behavior which results in some JavaScript code which can be executed in the browser.

These features shows that, although JSF is still mainly a server side framework, the importance and the popularity of the client side is acknowledged.

Confirm button

We start with a simple example where we like to make a button that first asks for a confirmation before it performs its action.  A classic example is the button that deletes some information but first we ask the user for a confirmation if he is sure to execute this irreversible action.

The key Java class for the Client Behavior is ClientBehaviorBase. It implements the ClientBehavior interface, common to all functionality related to client side behavior, and by implementing the getScript method, half of the work is already done.
For our confirm functionality, we have a method like this

    @Override
    public String getScript(ClientBehaviorContext behaviorContext) {
        return "return confirm('Are you sure ?');";
    }

The return string is the JavaScript we like to execute in the browser, here it is the confirm method which pops-up a javascript ‘window’ with an OK and Cancel button.

When the class is annotated with @FacesBehavior, The JSF system add our class to the list of implemented client behaviors.

@FacesBehavior(value = "confirmation")
public class ConfirmBehavior extends ClientBehaviorBase {

The content of the value member is the, unique, name we can use to refer to our custom client behavior.  This is needed when we define a tag for the behavior.

A tag is needed so that we can specify in the xhtml files which components receive our javascript. In the facelet tag library we can define it as follows.

    <namespace>http://www.rubus.be/jsf/tutorial</namespace>

    <tag>
        <tag-name>confirmation</tag-name>
        <behavior>
            <behavior-id>confirmation</behavior-id>
        </behavior>
    </tag>



The behavior-id must match the value member of the FacesBehaviour annotation.  The tag name can be freely chosen but here it happens to be the same as the behavior id.

Assigning to a commandButton is not different than using any other custom tag that you have defined in a facelet tag library.

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:r="http://www.rubus.be/jsf/tutorial"
        >
<h:head>
    ...
</h:head>
<h:body>
    ...
    <h:form>
        ...
        <h:commandButton value="with confirmation" actionListener="#{bean.performAction}">
            <r:confirmation/>
        </h:commandButton>
        ...
    >/h:form>
    ...
</h:body>
</html>

When the user clicks now on the button, a confirmation is asked with the text ‘Are you sure?’. And when he clicks on the cancel button, the action listener method isn’t performed. In the case he has pressed on the OK button, the post to the server is executed as usual.

Which components


To what components can we attach a custom client behaviour? This is determined by the ClientBehaviourHolder interface.  It has a few methods to handle the addition and retrieval of registered client behaviors and event names. More on event names in the next section.

Well almost all components implement that interface.  The most useful ones are of course all the input fields and the buttons. But also on the html body component we can attach a behaviour. More specifically, the load event can be used to attach some additional code to the page when rendered in the browser.

How to specify the event?


In our example with the confirmation question, the javascript method is attached to the onClick method of the button.  This is because the click event is the default event for the commandButton component. If we like to attach the code to some other event, then we have to specify the event name with the event attribute of the tag. We will see an example of it in the second part of this blog.

What are all the events which are supported? This differs from component to component. But the rule is that when you have the onXXX attribute on a component to attach some behaviour, the event XXX is available for creating a reusable client behaviour with the technique explained above.

Conclusion


It is very easy to specify some client behavior in a repeatable manner with JSF 2. And in the second part of this text I’ll explain some more advanced topics of the client behavior functionality.