Wednesday, October 3, 2007

Conditional rendering of JSF fields based on dynamic af:selectOneChoice

My friend in her recent project was implementing conditional rendering of JSF fields based on dynamic af:selectOneChoice component, and she was in trouble with this. There exists excellent Grant Ronald blog post - Conditional rendering of JSF fields depending on a drop down list (af:selectOneChoice). However, Grant in his post describes conditional rendering of JSF fields depending on fixed drop down list, not dynamic. Together with my friend we have developed needed solution and I have decided to post it.

Sample application - is based on standard HR schema and provides one JSPX page called main.jspx. This page contains form component with navigation controls and functionality that allows to create new data and save changes in existing one. Application is focused on two form elements - DepartmentId and PhoneNumber. Functional requirement is not to show PhoneNumber element if IT is selected in DepartmentId drop down list.

Probably you will ask, what is the difference between fixed and dynamic drop down lists in conditional rendering. In fact it is similar, however you will need to add some Java code. Steps are the same like described in Grant Ronald blog I have mentioned, however implementation of some steps differs. Here I will describe differences.

At first you need to create dynamic drop down list for DepartmentId, this step is simple. In developed sample application for List Iterator is used DepartmentsView1Iterator, this iterator binds to DepartmentsView1 data control. We will need to access created drop down list to get selected value, to make it possible we have created table definition and binded it to the same DepartmentsView1Iterator iterator. Don't forget to enable AutoSubmit and set PartialTriggers on parent UI item.

PhoneNumber element property Rendered we have binded to a method available in page backing bean, this method is called - isPhoneNumberRendered(). Method code:

Code is straightforward but it allows to use dynamic drop down list in conditional rendering. In this code, DepartmentName is retrieved for selected element in drop down list, and it is compared with IT department. Depending on comparison result, true or false is returned and based on returned value component is rendered or no.

Here PhoneNumber is shown:

And when IT is selected for department, PhoneNumber is not shown. It will not be shown even if you will just open a page with IT department selected.

When running sample application, don't forget to add adf-faces-impl.jar and jsf-impl.jar to application's WEB-INF\lib directory.


wael said...

hi Andrejus :
why we should get value from iterator ?
can we get value direct like


Dilini said...

I want to show/hide af:showItemDetail according to one load record field value(payment type). i write public boolean IsRendered() method in my backing bean class and af:showItemDetail rendered property set as follow
but when page run give bellow error

]] Root cause of ServletException.
javax.el.PropertyNotFoundException: The class 'view.backing.Pages.Client_Edit' does not have the property 'IsRendered'.

How i this resolve?

David said...

I found that i had to not subtract 1 from the getRowAtRangeIndex method call. When I did it gave me the entry before the one I selected.

This works great BTW. I was approaching it by using a valueChange listener but found that initialization was a problem. This is a much better solution.
Thanks Andrejus!