Ajax |
||||
Developer’s Guide Home
Installation and Configuration Common Concepts Components Index Border Layout Panel Calendar Chart Command Button Command Link Confirmation Data Table Date Chooser Day Table Drop Down Field Dynamic Image Folding Panel For Each Graphic Text Hint Label Input Text Input Textarea Layered Pane Popup Layer Popup Menu Select Boolean Checkbox Select Many Checkbox Select One Radio Spinner Suggestion Field Tabbed Pane Tab Set Tree Table Two List Selection Window Focus Load Bundle Scroll Position Ajax Framework Validation Framework Tag Reference API Reference |
Key Features
Attaching to a ComponentThe common use-case for implementing interactive Ajax features is when there's a component on a page that triggers some action that requires an Ajax call to the server. For this purpose, the Ajax component has a feature of attaching it to the "invoker" component, or a component that initiates the Ajax action. For example it is possible to attach the Ajax component to a button component, and even more, it is possible to attach to arbitrary HTML tags that are not JSF components. There are two ways of attaching to a component:
In both cases you can use the event attribute to specify the attached component's event that will determine when Ajax request should be executed. The default value for this attribute is "click", which means that Ajax request will be initiated when a user clicks on the attached component. Note that the event string should be without the "on" prefix, for example you should use "dblclick" instead of "ondblclick". The render attribute should specify ids for all components that should be reloaded during the Ajax request. A value expression should evaluate to a Iterable of String, if a literal is specified the identifiers must be space delimited. The for attribute mentioned in the second point should be assigned with the id of a JSF component or id of any HTML element, whose event should be listened to:
Note Note that it is not possible to change the rendered attribute of the reloaded component(s) since that change cannot not be applied during the Ajax request. This limitation is applicable only to the components specified for reloading directly and not to their child components. So this issue can be solved by wrapping the component whose rendered attribute is being changed into any container (for example the <h:panelGroup> component) and reloading that container instead. Invoking Server Action During an Ajax RequestThere is a possibility of invoking a server action during an Ajax request. This can be made using the listener attribute. This attribute should be specified as a method binding expression pointing at an action listener to be invoked. The phase when the action is invoked depends on the value of the immediate attribute (see the Controlling Phase of Action Execution section below). The referred method should receive one parameter of type javax.faces.event.ActionEvent. Controlling Phase of Action ExecutionPhase of action listener notification is controlling by the immediate attribute. If attribute is equal to true, than action will be invoke during Apply Request Values phase. If attribute equals false (the default value), than action will be invoked in Invoke Application phase. Submitting Components DataAny Ajax action performed using the Ajax component will usually need some data entered on the page to be submitted to the server for processing. Here are the rules that are used to determine the components whose data should be submitted and processed on the server:
Here is an example where a button reloads an <h:outputText> component with the text entered in an <h:inputText> component without reloading the input component. <h:inputText id="input1" value="#{requestScope['text1']}"> <o:ajax event="keypress" render="ot1" execute="it1"/> </h:inputText> <h:commandButton value="Test"> <o:ajax render="input1" execute="output1"/> </h:inputText> <h:outputText id="output1" value="#{requestScope['text1']}"/> Avoiding Frequent RequestsIn some cases the Ajax component event can be attached to an event that might occur quite frequently, and it becomes reasonable to make fewer requests in such cases. For example consider an input field that triggers Ajax reload when the user types a key. It is possible to configure the Ajax component to send a request once the user stops typing in a text field for a while. The delay attribute specifies a delay in milliseconds that should elapse after an event before starting an actual request. Subsequent request during this delay will make the request to be postponed until the specified delay elapses after the last such event. Below is an example of using the delay attribute to send a request every time the user stops typing in a text field for one second. <h:inputText> <o:ajax event="keypress" render="reloadedComponent" delay="1000"/> </h:inputText> Attaching to Any Component-Specific EventsTag supports all events of components – the standard ones, such as onclick, onmouseup etc., and component-specific, such as onadd for TwoListSelection or onchange for DataTable's selection. The usage is the same in both cases, though please note that attaching to custom component events are not supported when Ajax component is attached to the "invoker" component with the for attribute. Therefore you should either attach a component by embedding it into the appropriate tag, or use client-side API (see below) if you need to use Ajax reloading for component-specific events. Here's an example: <o:twoListSelection> <f:selectItems value="#{SomeExampleBean.items}"/> <o:ajax event="add" render="selectedOutput"/> </o:twoListSelection> Ajax State EventsThere is a possibility to receive notifications of various conditions of the Ajax request using the following event attributes of the <o:ajax> tag:
Standalone ModeThere are use cases when Ajax component shouldn't be bound to a component explicitly, but should be available for explicit invocation from a JavaScript code. This can for example be needed when the same Ajax request should be executed when receiving events from several components on a page, or when it should be executed upon a specific condition that can only be detected with JavaScript. Such use cases can be addressed by adding the standalone attribute with a value of true to the <o:ajax> tag, and specifying its id attribute to be able to refer this component from a JavaScript code. The <o:ajax> tag itself in this case can reside in any part of the page like any other JSF component, though as a non-visual component it won't affect page rendering and will just be available through the JavaScript code. The functionality of the Ajax component in this case can be activated by invoking the run() JavaScript function on the Ajax component instance. Here's an example that invokes the same Ajax component upon different events of several components: <h:form id="form"> <h:inputText id="textField" onkeypress="O$('form:updateImage').run()" .../> <h:selectOneMenu id="colorField" onchange="O$('form:updateImage').run()" ...> ... </h:selectOneMenu> <o:dropDownField id="fontSizeField" onchange="O$('form:updateImage').run()" ...> ... </o:dropDownField> <o:ajax id="updateImage" standalone="true" render="dynamicImage" execute="textField colorField fontSizeField" requestDelay="500"/> <o:dynamicImage id="dynamicImage" .../> </h:form> Pure JavaScript APIThe standalone mode described in the previous section allows invoking Ajax component functionality explicitly from the JavaScript, though it requires the ?? Ajax?? component to be present and configured on the page. In addition to this facility, it is possible to invoke the functionality of the ?? Ajax?? component purely with JavaScript code, without declaring the component on a page. This can be achieved using the O$.ajax.request(source, event, options) JavaScript function, which provides a functionality identical to the <o:ajax> tag right from JavaScript. The function receives the following arguments:
Here's an example: <h:outputText id="ajaxOutput1" value="#{SomeBean.outputText1}"/> <h:outputText id="ajaxOutput2" value="#{SomeBean.outputText2}"/> <h:inputText id="ajaxInput" onkeypress="O$.ajax.request(this, event, { render: 'form1:ajaxOutput1 form1:ajaxOutput2', execute: 'form1:ajaxInput', listener: 'SomeBean.someAction', onajaxend: function() {alert('Success!')} })"/> Note that all components should be located in the same form. If you're using the O$.ajax.request function and there are no other Ajax-capable OpenFaces components on the page, you'll need to place the <o:ajaxSettings/> component on the page for JavaScript library where the O$.ajax.request function is defined to be available on the page. |
|||
© 2009 TeamDev Ltd. | ![]() |