File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Struts and the fly likes Iterator and multibox Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Frameworks » Struts
Bookmark "Iterator and multibox" Watch "Iterator and multibox" New topic
Author

Iterator and multibox

Colin Pace
Greenhorn

Joined: Sep 25, 2003
Posts: 9
how can i populate the value attribuites of a multibox using an iterator to loop through a collection of beans?
and how to pass the bean's properties to javascript?
Code showing a list of bank names with a checkbox and an edit button for
each name:


thanks,
gava-follower
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4444
    
    5

"gava follower"
Welcome to JavaRanch! Please edit your publicly displayed name to comply with the JavaRanch Naming Policy. Thanks!
As for your question, there are a few things I think you need to change:
1. If your Collection of banks is in the request attributes under the key "banks", then you need to change your iterate tag:
collection="<%= request.getAttribute("banks") %>"
to
collection="banks"
2. It's easier to have your ActionForm back the multibox with an array type property. So you would have
// in your ActionForm
private String[] selectedBanks;
public void reset(..) {
selectedBanks = new String[0];
}
public String[] getSelectedBanks() {
return selectedBanks;
}
public void setSelectedBanks(String[] newSelectedBanks) {
selectedBanks = newSelectedBanks;
}
// in your JSP
<html:multibox property="selectedBanks" value="<%= bank.getId() %>" />
----
Code showing a list of bank names with a checkbox and an edit button for
each name:


thanks,
gava-follower[/QB]


Junilu - [How to Ask Questions] [How to Answer Questions]
Colin Pace
Greenhorn

Joined: Sep 25, 2003
Posts: 9
Junilu Lacar, thanks for your help.
i have changed my display name according to the JavaRanch Naming Policy.
However I still have problems with the code I mentioned in my first posting.
1. I tried to get the collection by using the name "banks" directly in the iterate tag, however the following error cropped up:
org.apache.jasper.JasperException: Cannot create iterator for this
collection
Before calling the JSP I am calling an action that prepares the collection in a request attribute named banks - in fact using <%= request.getAttribute("banks") %> - I cannot understand why "banks" is not working.
2. I have added a String[] in the ActionForm and used the multibox successfully using the following code:
<html:multibox property="selectedBankIds">
<bean:write name="bank" property="id"/>
</html:multibox>
your code:
<html:multibox property="selectedBankIds" value="<%= bank.getId() %>" />
Maybe this problem is related to the fact that "banks" is not working in 1.
3.my last question is related to integrating struts tags with javascript:
<html:submit value="Edit" on*="return callEdit('<%= ((com.fase.ims.logic.admin.Bank)bank).getId() %>')"/>
* in this case click
I am trying to pass the bank id to a javascript method. However this is not working - the scriplet is not being compiled and interpreted.
NOTE: I am using this messy approach since in my JSP I am generating a number of buttons dynamically, with each button's Action requiring the id (the bank id) corresponding to the clicked button. This was the only way I could think of going aroung this problem. Does anyone has a better solution?
thanks for all your help,
colin pace
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4444
    
    5

i have changed my display name according to the JavaRanch Naming Policy.
Thanks!
However I still have problems
1. Hard to tell -- post the code that's creating the collection and putting it into the request.
2. Maybe this problem is related to the fact that "banks" is not working in 1. My bad. The bean:write works because it uses reflection. The JSP expression using bank.getId() is wrong now that I think about it because bank is not a scripting variable.
3. my last question is related to integrating struts tags with javascript:
<html:submit value="Edit" on*="return callEdit('<%= ((com.fase.ims.logic.admin.Bank)bank).getId() %>')"/>

do this instead:
<html:submit value="Edit" on*='<%= "return callEdit(" + ((com.fase.ims.logic.admin.Bank)bank).getId() + ")" %>' />
[ September 26, 2003: Message edited by: Junilu Lacar ]
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4444
    
    5

OK, did some tests to clear my own understanding of how this tag works :roll:
collection - needs to be a runtime expression. Your original code should work as long as request.getAttribute("banks") returns a collection. Looking at your tag, you should use single quotes instead of double quotes around your attribute value:
collection='<%= request.getAttribute("banks") %>'
if you use the name attribute instead (which must be what I was thinking of), you can use "banks", i.e.
name="banks"
Colin Pace
Greenhorn

Joined: Sep 25, 2003
Posts: 9
It seems that I have solved all 3 problems.
1. I used name="banks" and this works fine.
2. I have added a String[] in the ActionForm and used the multibox successfully using the following code:
<html:multibox property="selectedBankIds">
<bean:write name="bank" property="id"/>
</html:multibox>
3. As you told me I used the following code:
<html:submit value="Edit" on*='<%= "return callEdit(" + ((com.fase.ims.logic.admin.Bank)bank).getId() + ")" %>' />
Thanks a lot.
vidya mahavadi
Ranch Hand

Joined: Nov 24, 2004
Posts: 34
Hi,

I have a similar problem with struts <html:check box and html:mutlibox.
I am using <logic:iterate to loop through a collection of beans and populate the records in a table. 4 of the bean properties are boolean, and I want to show checkboxes. But if I use <html:checkbox>, when the page displays the check boxes reflect the properties set in the bean. This is perfect. But if I change their state(checked or unchecked) it does not save in the bean. I tried using multibox also, but had no luck. It had the same problem.

This is a bit urgent for me, so I would really appriciate if anyone can help me to fix it.

Many thanks,
Vidya
vidya mahavadi
Ranch Hand

Joined: Nov 24, 2004
Posts: 34
Hi,

The status of the check boxes needs to be the same as in database (as I populate the bean). I tried to fix the problem by implementing reset method where I made the bean properties(for the check boxes) as false. But this not going to work, as it always shows them unchecked.

Can anyone please suggest any work arounds if you know. Please help!!!
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
This problem is most likely caused by not specifyingthe property attribute of the html:checkbox tag correctly. If you're iterating over a collection of beans, each of which has boolean properties, it's essential that the property be named correctly including the index. Here is some valuable information on how to name your fields when iterating over collections.

http://struts.apache.org/struts-doc-1.2.8/faqs/indexedprops.html

If you are still unable to get it working after reading this, show us the structure your form bean including all classes in the graph, and we'll help you write the code to get the correct names for the property attribute.


Merrill
Consultant, Sima Solutions
vidya mahavadi
Ranch Hand

Joined: Nov 24, 2004
Posts: 34
Hi Merril,

Thanks for your response. I am attaching some code snippets to explain how I am doing.

public class SearchNotificationsForm extends ActionForm {

private Collection notifications= new ArrayList();//collection of Notification beans


public ArrayList getNotifications(){
return notifications;
}

public void setNotifications(Arraylist notifications){
this.notifications = notificaitons;
}
}

//Notification bean

public class NotificationDisplayObject
{
private CreditControlStatus creditControlStatus;
private long statHistId;
private String brokerName;
private String brokerEntityNo;
private String brokerCellNo;
private String brokerEmail;
private long policyNo;
private String typeOfLetter;
private boolean print;
private boolean email;
private boolean sms;
private boolean sendAll;
// all getter setter methods }

in JSP

<table>
<logic:iterate id="notification" name="searchNotifForm" property="notifications" type="NotificationDisplayObject" indexId="ctr">
<tr>
<td class="bodyCopy" width="10%" align="center">
<disclife:text styleClass="button" name="notification" property="policyNo" readonly="true"/>
</td>
<td class="bodyCopy" width="10%" align="center">
<html:checkbox property'<%= "notification[" + ctr + "].email" %>'/>
</td>
</tr>


I tried this way and did not work. Please tell me how I should change the checkbox tag property.

Thanks,
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
The code in your JSP looks good. What you are missing is an indexed getter on your SearchNotificationsForm bean. Something like this:

public NotificationDisplayObject getNotification(int index) {
return (NotificationDisplayObject) notifications.get(index);
}
vidya mahavadi
Ranch Hand

Joined: Nov 24, 2004
Posts: 34
Hi Merril,

I added the indexed getter to the action form as you suggested. But the check boxes can remember the changes from false to true. But not from true to false.
i.e. if the check box was not checked initially and we check it, it reflects as true in the bean. But if the check box was checked and we uncheck it, bean still has the variable as true.

Can You please tell me what could be the reason for this strange behaviour..

Thnaks,
vidya mahavadi
Ranch Hand

Joined: Nov 24, 2004
Posts: 34
Searching in this forum is a bit fussy, unless we know the subject exactly.. May be it should cater for the topic number also.. Just a suggestion!
vidya mahavadi
Ranch Hand

Joined: Nov 24, 2004
Posts: 34
Hi,

Can anyone please help me to fix this.

Thanks,
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
Sorry, Vidya. I just didn't see your last post on this thread.

With radio buttons and checkboxes there is a problem in that the value of the button is submitted only if it's checked. If it's unchecked, nothing is submitted, and therefore the setter is not called.

What you need to do is override ActionForm's reset(mapping, request) method on your SearchNotificationsForm bean.

In this method, add code to iterate through the notifications List, setting the email property of each object in the list to false.

When the form is submitted, Struts calls the reset() method prior to calling the setter methods on the form. If you add the code I suggested to the reset() method, you will insure that all values are false before the setters are called. Then, when the ActionForm is passed to the Action, only those items that are checked will be set to true.
vidya mahavadi
Ranch Hand

Joined: Nov 24, 2004
Posts: 34
Thanks Merril! It works!! You are a star!
Vetri Thiru
Greenhorn

Joined: Feb 07, 2006
Posts: 3
Hi Merrill/Others,

I am facing the exact same problem as the folks above. I am displaying checkboxes using "nested" tags. However each checkbox displays the value that is set from the application; it does not take the values user sets/unsets. I have tried all that has been suggested above (adding a reset method and providing the indexed getter to get an object from the ArrayList). I have even tried to not use the "nested" tags but still the values are not taken from user's inputs (system set boolean values are properly checked in the checkbox). I have put debug statements in the getter/setter methods to see if those are indeed invoked when user clicks on the checkbox; they dont get invoked when user clicks on checkboxes! I am going nuts trying to figure out why

Code structure is just the same as Vidya's (see previous posting above). I have a Form which contains an ArrayList of results; each of the result object in that ArrayList has a boolean member variable and its corresponding setter/getter. (Please let me know if actual code snippets would be needed).

Would be greatful if you could let me know what I might be doing wrong/what I might not be doing.

Thanks,
T. Vetri

[ February 07, 2006: Message edited by: Vetri Thiru ]
[ February 07, 2006: Message edited by: Vetri Thiru ]
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
Vetri,

It's hard to say what's going wrong without seeing your code. Could you please show us:

1-The relevant portions of your ActionForm
2-The relevant portions of the javaBean that is in your List
3-The relevant portions of the JSP (<html:form tag, and the iterate portion)
4-The relevant portion of your struts-config.xml file
Vetri Thiru
Greenhorn

Joined: Feb 07, 2006
Posts: 3
First of all, thanks much Merrill for helping out.

Here are the code snippets:
1-The relevant portions of your ActionForm

public class MyActionForm extends ActionForm {

// Other beans/EJBs fetch and populate results and bkupResults ArrayList in this form;
//then this form is displayed (upon "success" mapping from there)
private ArrayList results = null, bkupResults = null;

...
public ArrayList getResults() {
return results;
}
public void setResults(ArrayList results) {
this.results = results;
}
public void setResult(int index, MYBean o) {
this.results.set(index, o);
}
public MYBean getResult(int index) {
return (MYBean)this.results.get(index);
}
...
/*
Currently I am not sure how I can unset the checkboxes to the original state - for now I just want to get the checkboxes to work based on user clicks - then I will figure out the contents of this reset method (to make checkbox change from checked to to unchecked). However this is what I have now. If I remove the if check I get a null pointer exception!!
*/
public void reset(ActionMapping mapping, HttpServletRequest request)
{
if (results != null) { //hmmm...why do I need this check?
results = (ArrayList)bkupResults.clone();
logger.severe("Results after reset:"+results);
}
}

}


2-The relevant portions of the javaBean that is in your List

public class MYBean {

...other private fields...
private boolean flag = false;
...
public boolean isFlag() {
return flag;
}
public void setFlag(boolean val) {
this.flag = val;
}
...other setters/getters and toString()
}


3-The relevant portions of the JSP (<html:form tag, and the iterate portion)

<logic:iterate id="result" name="MyActionForm" property="results"
indexId="index" type="MYBean">

<html:form action="/MyAction.do">

<!-- showing other properties here -->
<html:checkbox value="true" property='<%= "result[" + index + "].flag" %>'/>
<!-- showing some other properties here -->

<html:submit property="action">
<bean:message key="delete.submit"/>
</html:submit>

</html:form>
</logic:iterate>

<html:form action="/MyAction.do">
<html:submit property="action">
<!-- In this commit() method I am processing the checkboxes -->
<bean:message key="commit.submit"/>
</html:submit>
...
</html:form>

4-The relevant portion of your struts-config.xml file
<form-bean name="MyActionForm" type="form.MyActionForm"/>

<action path="/MyAction"
name="MyActionForm"
parameter="action"
type="action.MyAction"
input="/mypage_tiledef.jsp"
validate="true">
<!-- Am not yet validating; the form's validate() just returns null -->
<forward name="success" path="/mypage_tiledef.jsp"/>
</action>


Thanks,
T. Vetri
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
From what I can tell,the problem seems to be in your use of the <html:form> tag. Because you have an <html:form> tag inside the iterate loop, the generated html is going to have one form for each checkbox and delete button and a separate form for the submit button at the bottom of the page. When a submit button is pressed, only the inputs on the same form as the submit button are processed. That's why the user input for your checkboxes isn't getting processed when you press the submit button at the bottom of the page-- it's in a different form.

Since I don't know your application, I can't tell you specifically what to do, but here's one option:

Eliminate the <html:form> tag inside the iterate loop and turn the the delete button into a <html:button> input. You can then use the javascript onclick event to identify which item is to be deleted, change the form action to the delete action, and submit the form. That way you only have one form in the document and all inputs on the page are available to that form.
[ February 08, 2006: Message edited by: Merrill Higginson ]
Vetri Thiru
Greenhorn

Joined: Feb 07, 2006
Posts: 3
Thanks a lot Merrill - That is the problem.

I can't think of a better way to fix it than the one you have suggested (by using html:button with JavaScript instead of html:submit).

Thanks again!
T. Vetri
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: Iterator and multibox
 
Similar Threads
Problem with CheckBox and MultiBox
multibox - nullPointerException
Using checkbox/multibox to delete items from a list
Multibox Not Populating as Checked!!!
multibox query