Joined: 10/01/2008 08:20:15
One recurrent problem is when you want to display a dynamic list, in other words, a list that depends on other field. One standard example is State and City where each State has its own list of Cities.
One possible approach to this problem is to add all 50 lists to ListManager, but that would not be a good solution because you would have to have a bunch of IFs in your JSP, like below:
This is awkward and will introduce other problems. For example when we first show the page and no state is selected, we must show an empty list.
Luckily there is a much better solution by using a Mentawai filter to create a dynamic list on the fly and place it in the action output. Remember that the mtw:select tag is smart enough to pick up lists straight from the action output, if it finds one.
Let's define the problem before we dive into the code. Below are the situations where we need to take action:
1) Empty form is being displayed to insert a new bean => List should be empty
2) Form is being redisplayed probably because of a validation error => List should be the same one when the used submitted the form, in other words, it should not lose its state when a validation error occurs.
3) Form is being used to EDIT a bean, in other words, a bean object was placed in the action output and a forward was performed to the JSP with the form => List should display the appropriate list corresponding to the bean State.
4) The user selected another State => List should be changed through Ajax (out of the scope of this recipe)
Here are the conditions for 1), 2) and 3):
1) Nothing is in the action input and nothing is in the action output => Form is being used to insert a bean and an empty list should be displayed.
2) The current State id is in the action input => A validation error occurred and you should use the State id to show the appropriate City list.
3) There is an object in the action output with a State id property => The object (bean) is being edited, so show the appropriate City list corresponding to this bean State id.
Below is a simple filter that I coded to address all these scenarios:
So now you can use a single mtw:select tag and your list will be filled appropriately according to the situation and the State id.
One last catch when setting the filter in the application manager: This filter should be executed *before* the ValidatorFilter which is a global filter that performs validation. That's because the ValidatorFilter aborts the execution chain if it finds an error and as we know global filters are executed before any action specific filter.
Luckily there is an easy way to place an action specific filter before all global filters. Just use the addFilterFirst() or filterFirst() method from ActionConfig.
In a web application project, you will probably have to code a filter like that for every dynamic list. To make this job easier, Mentawai 1.14 includes the org.mentawai.filter.DynamicListFilter that you can use to fast code these filters. See how we could have coded the filter above with this new abstract class: