In this recipe, we will modify the recipe Building a spinner composite component in JSF 2.0 from Chapter 5, Custom Components, to offer the possibility to use more than one spinner on the same page. Practically, you will see how to use multiple AJAX-aware components in a JSF page.
First we modify the spinner.xhtml
page as following:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" spinner.xhtmlmodifying"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:composite="http://java.sun.com/jsf/composite"> <h:head> <title>Creating a rusable AJAX spinner composite component </title> </h:head> <h:body> <composite:interface> <composite:attribute name="value" required="true" /> <composite:attribute name="step" required="false" /> </composite:interface> <composite:implementation> <h:outputScript name="ajax.js" library="javax.faces" target="head"/> <h:outputScript name="spinner/spinnerJS.js" target="head" /> <script type="text/javascript"> initSpinner("#{cc.clientId}","#{cc.attrs.step}"); </script> <h:inputText id="nrID" value="#{cc.attrs.value}"/> <h:commandButton id="leftID" value="Plus step" onclick="return goDirection('#{cc.clientId}',1);"/> <h:commandButton id="rightID" value="Minus step" onclick="return goDirection('#{cc.clientId}',-1);"/> </composite:implementation> </h:body> </html>
As you can see there are two main modifications here. First, the JavaScript code was moved to a separate file, named spinnerJS.js
, and each spinner was initialized by calling the initSpinner
function. spinnerJS.js
looks as following:
var steps = {}; function initSpinner(comp_id, step) { if (isNaN(step)) { steps[comp_id]= 1; }else{ steps[comp_id] = Number(step); } } function goDirection(comp_id,s) { var obj = document.getElementById(comp_id+":"+"nrID"); var cv = Number(obj.value); if ((isNaN(cv)) || (cv == 0)) { cv = 0; } obj.value = cv + (s * steps[comp_id]); return false; }
Now, you can test a set of three spinners, as shown next:
… <h:outputText value="Spinner I - initial value = 10, step = 10"/> <br /> <e:spinner value="10" step="10" id="spinnerI"/><br /> <h:outputText value="Spinner II - initial value = 5, step = 1"/> <br /> <e:spinner value="5" step="1" id="spinnerII"/><br /> <h:outputText value="Spinner III - initial value = 0, step = 2"/> <br /> <e:spinner value="0" step="2" id="spinnerIII"/><br /> …
A possible output is shown in the following screenshot:
In this case, the main idea is that we have to manage an array of components instead of a single component. We switch between components (or we identify them)—for maintaining their state—using their corresponding ids. The initSpiner
function is responsible for creating an initial state for each new component, while the goDirection
function implements the component behavior after it identifies it using the component id.
The code bundled with this book contains a complete example of this recipe. The project can be opened with NetBeans 6.8 and it is named: Write_reusable_AJAX_components_in_JSF20.
You also may want to see Jim Driscoll's blog at http://weblogs.java.net/blog/driscoll/. This recipe was inspired by his idea.