Tuesday, August 06, 2013

JSF 2.x Tip of the Day: jsf.js AJAX onEvent() and onError() Examples

I was looking for some information on what I could do with the jsf.js AJAX scripts in JSF. Specifically, I was wondering if I could do some event handling, and how it should be accomplished. I was surprised that there really was not a complete example that I could find. I did find some blog posts from Jim Driscoll and some comments on stackoverflow by +Bauke Scholtz which show a partial solution, but nothing complete.

I decided to combine the good parts of Jim's blog post with some of the goodies from +Bauke Scholtz to create a complete example. In this example, I use a solution from Jim to demonstrate the events that are returned from the onEvent() and onError() listeners.  Along with a common request... A spinner for AJAX requests.

Once you download, and run the code. You will see a spinner while the AJAX request is processing. In my case, I use a Thread.sleep(2000); to cause the spinner to display for a little while.

The code for project can be found here: jsf-ajax-demo

index.xhtml


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>jsf.js AJAX Example</title>
        <h:outputScript library="javax.faces" name="jsf.js"/>
        <h:outputStylesheet library="css" name="default.css"/>
        <script type="text/javascript">
            var statusUpdate = function statusUpdate(data) {
                var statusArea = document.getElementById("statusArea");
                var text = statusArea.value;
                text = text + "Name: " + data.source.id;
                if (data.type === "event") {
                    text = text + " Event: " + data.type + "\n";
                    text = text + " Status: " + data.status + "\n";
                    if (data.status !== 'begin') {
                        text = text + " Response Code: " + data.responseCode + "\n";
                    }
                } else {  // otherwise, it's an error
                    text = text + " Error: " + data.name + "\n";
                }
                statusArea.value = text;
            };
 
            function handleAjax(data) {
                var status = data.status;
 
                switch (status) {
                    case "begin":
                        // This is the start of the AJAX request.
                        document.getElementById("statusArea").value = '';
                        document.getElementsByTagName('body')[0].className = 'loading';
                        break;
 
                    case "complete":
                        // This is invoked right after ajax response is returned.
                        break;
 
                    case "success":
                        // This is invoked right after successful processing of ajax response and update of HTML DOM.
                        document.getElementsByTagName('body')[0].className = '';
                        break;
                }
            }
 
            // Setup the statusUpdate function to hear all events on the page
            jsf.ajax.addOnEvent(handleAjax);
            jsf.ajax.addOnEvent(statusUpdate);
            jsf.ajax.addOnError(statusUpdate);
        </script>
    </h:head>
    <h:body>
        <h:inputTextarea id="statusArea" cols="40" rows="10" readonly="true" disabled="true" style="resize: none;"/>
        <h:form id="form1">
            <h:panelGrid id="panelGrid1" columns="2">
                <h:outputText id="uuid" value="#{indexBean.uuid}" style="font-size: 18px; font-weight: bold; color: salmon;"/>
                <h:message for="uuid"/>
                <h:panelGroup id="panelGroup1">
                    <h:commandButton id="submitButton" value="Generate UUID" actionListener="#{indexBean.generateUUID()}">
                        <f:ajax execute="@form" render="panelGrid1"/>
                    </h:commandButton>
                </h:panelGroup>
            </h:panelGrid>
            <div class="modal">
<!-- Place at bottom of page --></div>
</h:form>
    </h:body>
</html>

IndexBean.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.bluelotussoftware.example.jsf.ajax;
 
import java.util.UUID;
import javax.enterprise.context.RequestScoped;
import javax.faces.event.ActionListener;
import javax.inject.Named;
 
/**
 * Page backing bean for
 * <code>index.xhtml</code>.
 *
 * @author John Yeary
 * @version 1.0
 */
@Named
@RequestScoped
public class IndexBean {
 
    private String uuid;
 
    /**
     * {@link ActionListener} implementation that generates a random UUID and
     * sets the value in the bean. The returned value can be found by calling
     * {@link #getUuid()}.
     */
    public void generateUUID() {
        try {
            // Add this so that we have a delay for the AJAX spinner.
            Thread.sleep(2000);
            uuid = UUID.randomUUID().toString();
        } catch (InterruptedException ignore) {
        }
    }
 
    /**
     * Getter for UUID.
     *
     * @return return {@link UUID#toString()}.
     */
    public String getUuid() {
        return uuid;
    }
}

References

This is based on the primarily on the work published by Jim Driscoll and Bauke Scholz. This is just a more complete example  of what they mentioned in their articles.

0 comments :

Popular Posts