Last week, we had the author of TDD for a Shopping Website LiveProject. Friday at 11am Ranch time, Steven Solomon will be hosting a live TDD session just for us. See for the agenda and registration link
I am using Struts 1.1. My requirement is as follows:
1. I have 2 multi select drop down box S1 and S2 next to each other with a left button and a right button between the 2 select boxes. 2. The labels displayed should be different from the values within the option tag for both select boxes S1 and S2. 3. Now only the first select box S1 is populated with predefined values from the database. The right select box S2 is initially empty. 4. On selecting one or more values from the left select box (S1) and click of the left button, the selected values should move to the right select box S2. 5. Similiarly, when the values on the right select box S2 are selected and on click of the right button, the values from the right select box S2 should move to the left select box S1. 6. Also on struts validation errors, when my page with the select boxes is displayed, it should display the correct values in both the select boxes S1 and S2. i.e S1 should be displayed with all data except those present on the right select box S2. Similiarly, right select box S2 should display the earlier selected values which were moved into this box before the submit. 7. Both select boxes S1 and S2 should maintain different values and labels (i.e option tag - value and label are not same). I do not want the values and labels to be the same data.
e.g This is what i want the select box to look like select box S1 - pre-populated with values from the database
and now S1 will only have <select name="S1"> <option value="GG">Gretta Garbo</option> <option value="JR">Julia Roberts</option> <option value="MR">Meg Ryan</option> </select>
Issues: I am able to implement almost all the points except point 6 and point 7.
For S1: I have done the following- 1. On ActionForm, corresponding to S1, i have a List S1List (setS1List and getS1List methods) which will contain the values from the database. This pre-population is done in the Action class using struts class LabelValueBean i.e LabelValueBean l1 = new LabelValueBean("Tom Cruise", "TC"); LabelValueBean l2 = new LabelValueBean("John Travolta", "TJ");
and so on.. these are added to the List and set on the ActionForm via setS1List method.
in my jsp i am able to get the select box S1 like this:
Question 1: What do i need to do to implement the select box for S2 ? Note that S2 which actually holds the value to be saved in the database, is a String array (String) on the ActionForm. I tried different ways since 2 days, but i was not able to implement different value and labels for S2.
Question 2: On validation errors, when my page is displayed with the select boxes, in order to achive point 6, i was thinking of using the body onload event to remove the values from S1 which are already present on S2. Is there any other better way to achieve this ??
Any help for the above 2 points would be greatly appreciated..
Your ActionForm should actually have two lists of options: One list of all possible options, and another list of selected options. This is apart from the String array of selected options that only contains the codes selected.
It's important to understand that there's really no way to do this if you forward to a JSP after validation failure. You must forward to an action class so that you can construct the lists of available and selected options before re-displaying the JSP. See question 18 of our FAQ for information on how to forward to an action after validation failure.
In this action class, you would look at the String array of selected codes and do the following:
From the database, construct a list of all available options
Search this list for options associated with the codes selected
Copy each option that was selected from the available to the selected list
Remove each option that was selected from the available list.
Forward to the JSP
Once you have done this, in your JSP both the available and selected select boxes can be constructed using a combination of html:select and html:optionsCollection tags. [ July 17, 2008: Message edited by: Merrill Higginson ]
I would like to give more details, that i missed giving earlier.
1. I am implementing multi-page form (5 pages) and therefore my ActionForm is in the session scope in struts-config (under action tag).
2. For S1 select box - i have S1List (java.util.List) on my ActionForm. For S2 select box (whose values should actually be saved in the databse), i have S2 String array (String S2) since only String and String are valid for Http Request . In addition to these 2, should i also have something called S2List which is of type List (like S1List). Please confirm and if yes, how can i use it for my requirements (also see point 5 and 6 below).
3. The select boxes are on the 2nd page. Therefore when i call the *.do on submit of my first page, it validates the fields of the first page and then if validation is successful, calls the execute method of my Action Class. Here i have checks which ensure that depending upon the page, the specific doPage is invoked (and i pass the required parameters - ActionMapping, ActionForm, HttpServletRequest and HttpsServletResponse). Now in doPage1 of my Action class, i am prepopulating the list of all values retrieved from the database and setting this list on the ActionForm, so that when page 2 is displayed, this prepopulated list is picked from the ActionForm and displayed.
4. The all values List (for S1) contains LabelValueBean object (provided by struts), and i am using the above code (shown in my first post) in Action class as well as jsp (using html:select and html ptionsCollection) - This is the S1 select box (left select box)
5. Question - What struts tags (html:select and html ptions or html ptionsCollection?) should i use for the S2 Select box (right select box)?
6. Now.. on Page 2, i have other fields in addition to the select box. When i leave the other text fields empty and only transfer the values from S1 select box to S2 select box, and then click on Submit button, first validation takes place (ActionForm). Since fields are empty, Struts forwards back to page 2 jsp displaying the error messages. Question - Here, how can i display the values in S2 select box (these were selected prior to Submit). Right now, i have a crud implementation of html select for S2 . I want to use struts html select tags. Unless validation passes on 2nd submit, it will not even go to my Action class where you suggested i manipulate the list for both S1 and S2.
Please let me know if you need any other information..
Before we can continue, I have one question for you: Did you thoroughly read and understand question 18 of the FAQ? I know it may not seem like it applies, but it does. The technique described there is the technique I'm suggesting you use.
should i also have something called S2List which is of type List (like S1List)
What struts tags (html:select and html:options or html:optionsCollection?) should i use for the S2 Select box
You create the s2 select box exactly the same way you created the s1 select box, except using the s2 list.
Obviously none of this will work unless you have an action class that is called when validation fails that will populate these lists prior to displaying the JSP. Refer to my last post for a list of tasks you would need to perform in this action. [ July 17, 2008: Message edited by: Merrill Higginson ]
Thanks again Merrill for your response. Since i hadn't got your reply for some time, i decided to continue trying various things and this is a slight variation of what was recommended in FAQ 18. This is working fine with submit with all fields filled in as well as struts validation errors, but it would be great if you could review it and let me know if you foresee any issues. Also, i have to use the same jsps for presentation of add as well as modify functionality. Because its a multi-page form functionality, my formbean is in session scope (specified as scope=session) in action tag.
1. In struts-config, in the action tag, for the input attribute, instead of *.do, i continued to use the jsp for the 2nd page.
2. I have kept everything else the same - S1List (prepopulated values done in Action on submit of page 1 and before page 2 is called) on the ActionForm, actual select box property(Sting  sel) on the ActionForm and S2List (on the ActionForm) is populated in the validate method of the ActionForm on the condition that sel (String array holding the actual values to be stored in the database) is not null and size greater than 0. Now S2List has also been created here using Struts object LabelValueBean.
3. Through the onload event of the body tag of page 2 JSP, i have taken care that only those values not present in S2List are displayed in S1List (prepopulated list)
4. S1List (for S1 left select box) has been implemented in the jsp as:
Hi - There is a slight correction in the last post. In point 5 of the last post, S2List select box refers to the right select box (populated in the validate method of the ActionForm). My mistake i mentioned left select box.