What You May Need to Know About Using the Immediate Attribute and the Optimized Lifecycle

4-12 Web User Interface Developers Guide for Oracle Application Development Framework valueChangeListener={validateLOV.immediateValueChange} validator={validateLOV.validate} af:inputText label=Empno value={validateLOV.empno} required=true id=lovDependent01 partialTriggers=lov0 As with the radio button and input component example in Section 4.3.1, What You May Need to Know About Using the Immediate Attribute and the Optimized Lifecycle, once the user clicks the search icon, the inputText component will be validated because the lifecycle runs on both the root the inputListOfValues component and the target the inputText component. Validation will fail because the inputText component is marked as required and there is no value, so an error will be thrown, as shown in Figure 4–8 . Figure 4–8 Validation Error is Thrown Because a Value is Required However, the solution recommended in Section 4.3.1, What You May Need to Know About Using the Immediate Attribute and the Optimized Lifecycle, of setting the LOV component’s immediate attribute to true and using a ValueChangeListener on the LOV will not fix the validation error. For LOV components, the ValueChangeEvent is queued only when the value of the LOV component changes. For this reason, setting the immediate attribute to true has no effect when the user clicks the search icon, because at that point the ADF LaunchPopupEvent is queued for the Invoke Application phase always, regardless of the value of the immediate attribute. In other words, the optimized lifecycle is run as normal on both the root and target components and therefore the input component throws a validation error. When the user selects a new value from the LOV popup, the LOV component queues two events. One is a ValueChangeEvent to signal a change in value for the component. The second is a ReturnPopupEvent queued for the Invoke Application phase, which gives application methods a chance to handle the selection. Both these events need to occur in order for the LOV to behave as expected. As mentioned, the LOV component queues a ValueChangeEvent only when the user selects a new value. If you were to set the immediate attribute to true on the LOV component, this event would be queued for the Apply Request Values phase and the new value would be validated. In addition if you were to create a ValueChangeListener method for the LOV component, and in its implementation jump to the Render Response phase to avoid validation of the input component, the selected value would never get pushed to the model, the ReturnPopupListener would never get called during the Invoke Application phase, and the target input component would not get updated with new value, as shown in Figure 4–9 . Figure 4–9 Model is Not Updated To resolve this issue of needing both the ValueChangeEvent and the ReturnPopupEvent to be queued as part of the same request and to have any target fields refreshed with newly selected values, instead of declaratively setting the LOV Using the JSF Lifecycle with ADF Faces 4-13 component as a partial trigger for the input component and creating a method for the ValueChangeListener, you need to create a listener for the ReturnPopupEvent. This listener must programmatically set the input components as partial targets for the LOV. You do not need to set the LOV’s immediate attribute to true because the input component is no longer a target for the LOV until the ReturnPopupListener method is executed, and so it will not fail validation because the lifecycle will not be run on it. And because a listener method is used for the ReturnPopupEvent instead of for the ValueChangeEvent, both events can be queued and the model updated appropriately. Example 4–8 shows the needed page code for the LOV and input components. Example 4–8 af:inputListOfValues label=Ename id=lov1 value={validateLOV.ename} autoSubmit=true returnPopupListener={validate.processReturnPopup} Title=Search and Select: Ename searchDesc=Choose a name model={validateLOV.listOfValuesModel} validator={validateLOV.validate} af:inputText label=Empno value={validateLOV.empno} required=true id=lovDependent1 binding={validate.lovDependent1} The input component uses its binding attribute to store the instance on a backing bean, allowing the instance to be accessed by the listener method. The listener method then accesses the input component and sets it as a partial target for the LOV, as shown in Example 4–9 . Example 4–9 AdfFacesContext.getCurrentInstance.addPartialTarget_lovDependent1 For more information about programmatically setting partial page rendering, see Section 7.3, Enabling Partial Page Rendering Programmatically.

4.4 Using the Client-Side Lifecycle

The ADF Faces framework provides client-side conversion and validation. You can create your own JavaScript-based converters and validators that run on the page without a trip to the server. You can use client-side validation so that when a specific client event is queued, it triggers client validation of the appropriate form or subform for more information about subforms, see Section 4.5, Using Subforms to Create Regions on a Page . If this client validation fails, meaning there are known errors, then the events that typically propagate to the server for example, a command buttons actionEvent when a form is submitted do not go to the server. Having the event not delivered also means that nothing is submitted and therefore, none of the client listeners is called. This is similar to server-side validation in that when validation fails on the server, the lifecycle jumps to the Render Response phase; the action event, though queued, will never be delivered; and the actionListener handler method will never be called. For example, ADF Faces provides the required attribute for input components, and this validation runs on the client. When you set this attribute to true, the framework will show an error on the page if the value of the component is null, without requiring a trip to the server. Example 4–10 shows code that has an inputText component’s required attribute set to true, and a command button whose actionListener attribute is bound to a method on a managed bean.