As described in earlier postings in this series, the ADF Faces 11g RichFaces library has several facilities for client side logic to complement the already pretty rich client functionality. Among these facilities are the JavaScript API that allows client side manipulation of the components in the page, the clientTrigger mechanism that provides a rich alternative to the classic JS Event triggers such as onclick and onmouseover and the option to add JavaScript to PPR responses.
In this article, we will see how to respond to a valueChange event on an inputText item – that fires when the user has changed the value in a field and navigates out of the field. In this simple example, we use to clientListeners on the valueChange event.
The first one will turn the value the user has entered and turns to uppercase:
<af:panelFormLayout> <af:inputText label="Name" id="inputText1" shortDesc="The Name of the Entity" > <af:clientListener method="processChange" type="valueChange" /> <af:clientListener method="processChange2" type="valueChange" /> </af:inputText> </af:panelFormLayout>
and after leaving the item, pressing a button, alt-tabbing to another application or navigating to another browser window, the valueChange event fires and the processChange function invoked.
The function processChange is implemented like this:
<trh:script rendered="true" text=" function processChange(event) { var inputField = event.getSource(); inputField.setValue(event.getNewValue().toUpperCase()); } "/>
The second clientTrigger will perform a validation on the value.
If the value includes an X, Y or Z, the validation in processChange2 kicks in.
The client side logic for performing the validation and marking the field as invalid looks like this:
<trh:script rendered="true" text=" function validateNoXYZ( value) { return (value.indexOf('X') + value.indexOf('Y') + value.indexOf('Z'))==-3; } function remove(s, t) { /* ** Remove all occurrences of a token in a string ** s string to be processed ** t token to be removed ** returns new string */ i = s.indexOf(t); r = ''; if (i == -1) return s; r += s.substring(0,i) + remove(s.substring(i + t.length), t); return r; } function processChange2(event) { var inputField = event.getSource(); if (validateNoXYZ(event.getNewValue())) { inputField.setStyleClass(remove( inputField.getStyleClass(), 'p_AFError')); inputField.setShortDesc(remove(inputField.getShortDesc(), 'Please, no X, Y or Z in this item!')); } else { /* set styleclass x1p on item! (for red box) */ inputField.setStyleClass(inputField.getStyleClass()+ ' p_AFError'); inputField.setShortDesc('Please, no X, Y or Z in this item! '+ inputField.getShortDesc()); } } "/>
Note: when the valueChange event fires and the logic in processChange makes another change to the value – turning it to uppercase for example – a second valueChange event is fired and processChange2 will be invoked twice in a row! The order in which the clientListeners fire is the order in which they are defined within the parent element.
<af:panelFormLayout> <af:inputText label="Name" id="inputText1" shortDesc="The Name of the Entity" > <af:clientListener method="processChange" type="valueChange" /> <af:clientListener method="processChange2" type="valueChange" /> </af:inputText> </af:panelFormLayout>
I have tried to show a popup window with an appropriate error message. However, I ran into issues.
Client Side display/hide of ShowDetail
Just another simple example, to see what we can do:
When the value in the Name field is changed, a client side event listener is invoked to show some details (in a ShowDetail container):
The code required for this consists of three elements: the ShowDetail
<af:showDetail disclosed="false" id="infoPanel"> <af:panelHeader text="Important Information" inlineStyle="width:200px;height:300px;"> <af:inputText label="ID " id="inputText2" clientComponent="true"></af:inputText> <af:image source="http://www.oracle.com/admin/images/ocom/hp/oralogo_small.gif"/> </af:panelHeader> </af:showDetail>
, the Name inputText with the clientListener
<af:inputText label="Name" id="inputText1" autoSubmit="true" value="#{someBean.value}" shortDesc="The Name of the Entity"> <af:clientListener type="valueChange" method="showInfo"/> </af:inputText>
and the JavaScript function that make the ShowDetail display itself:
<trh:script text=" function showInfo() { var info = AdfPage.PAGE.findComponent('infoPanel' ); info.setDisclosed(true); } "/>
Resources
The ADF 11g Rich Faces JavaScript API.
The ADF Faces 11g Web UI Developer Guide
Part 1 in this series: Client Side programming in ADF Faces Rich Client Components
Hi Lucas,
Nice post . We were trying to implement some js on af:richTextEditor(wysiwyg) by adding af:clientListner .
The js gets called only for the event onMouseOver . All other events like blur , keyPress are not working .
Any suggestions would be welcome.
Â
Â
Thank you very much for that very useful article ! i am following you.
Nice series,
for the validation, I think it may be better to create a custom JSF-validator (+ client-side validator)
that ensures there is no X, Y or Z on the server as well (due to security running validation on the server as well is better)
See Trinidad docs for the client validators:
http://myfaces.apache.org/trinidad/devguide/clientValidation.html
Pretty cool tool.
You may also want to read this:
http://jroller.com/mwessendorf/entry/ajax_client_side_convertion_with