Like I have blogged about before, using labels in html forms is a good thing. It makes the form easier to use, and over all is much nicer. I think that this is especially true for checkboxes and radio buttons.
Now, we are using struts for our app, and as recomended we are using a multibox to manage a group of related check boxes. Now the trouble is that I could not figure out how to add a html label. The spec says that you don't have to use the "for" attribute, but I found that it didn't seem to work this way in IE (works in Firefox of course). And the example that everyone points to didn't use labels.
Now, using the example, for it to work I had to add in a cast and use some java code (not tags!) to get it to work. Here is the modified example:
<logic:iterate id="item" property="items"> <label for="selectedItems.<bean:write name="item" property="label"/>"> <html:multibox property="selectedItems" styleId='<%="selectedItems." + ((org.apache.struts.util.LabelValueBean)item).getLabel()%>'> <bean:write name="item" property="value"/> </html:multibox> <bean:write name="item" property="label"/> </label> </logic:iterate>
The changes are the styleId and the label tags. Not the best experience, but I hope that this will save someone else the time that it has cost me.
Update: I changed the id to point to the label and not the value. The label is more likely to be unique on the page. My bad.
Update 2: I made the changes that I mentioned in the post to ensure that the label is unique in the form. ;-)
One thing that I thought of, you would probably want your label unique in the whole form, so it's probably not the best to just tie it to the text in the check box (like if you had two sets of check boxes with "N/A").
ReplyDeleteSo, it's better to tie in the property ("selectedItems" in this case) as well. I'll change the posted example when I can try it out and make sure that it works.
Thanks for the tip, it got me on the right track.
ReplyDeleteOne possible change is to use the indexId property
of the iterate tag to simplify the naming and not
worry about any funky characters in the labels.
Just substitute some logical name for the control
for "xx" in the snippet below. This also removes
the need for the cast.
<logic:iterate id="item" property="items"
indexId="count">
<label for="xx<bean:write name='count'/>">
<bean:write name="item" property="label"/>
</label>
<html:multibox property="item"
styleId="<%="xx"+count%>">
<bean:write name="item" property="value"/>
</html:multibox>
</logic:iterate>
That is an excellent point Mike. I never liked the cast at all.
ReplyDeletePls send m the detail example of
ReplyDeletewith iterator ,which briefs the multiple check boxes with dropdown list
Vikas, just look at Mike's post for a detailed example of using multiple check boxes.
ReplyDeleteThe only thing that you would have to do is load the correct collection into the jsp.
As for using a dropdown list, if you load your info into a LabelValueBean you can just display them with the <html:options> tag. ;-)
http://struts.apache.org/api/org/apache/struts/util/LabelValueBean.html
Hi,
ReplyDeleteA very good example on indexId attribute of logic:iterate. Thanks a lot...
I am currently struggling to include the HTML:MULTIBOX code into a JSP file.
ReplyDeletewithout the tag I can successfully get both the label and the value of the LabelValueBean created.
as soon as it is there, I get a nasty
"Cannot find bean under name org.apache.struts.taglib.html.BEAN"
Any ideas?
Thank you
Ya, I hate that error. I usually find that's when I am calling something with the property tag or the "name" tag when I should be using the other.
ReplyDeleteIf you still can't figure it out, post the code you've got trouble with and I can see what I can do. ;-)
First, thank you for the fast reply!
ReplyDeleteThis is the code in my JSP file, which works:
<td>
<logic:iterate name="CourseReportForm"
id="annumOption" property="annumOptions" >
<bean:write name="annumOption"
property="label"/>
<bean:write name="annumOption"
property="value"/><br>
</logic:iterate>
</td>
As soon as it is changed to:
<td>
<logic:iterate name="CourseReportForm"
id="annumOption" property="annumOptions" >
<html:multibox property="selectedAnnums">
<bean:write name="annumOption"
property="label"/>
</html:multibox>
<bean:write name="annumOption"
property="value"/><br>
</logic:iterate>
</td>
it replies (upon runtime) with a
javax.servlet.ServletException: Cannot find bean under name org.apache.struts.taglib.html.BEAN
I am using:
<%@taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
<%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
The CourseReportForm has a getter method for selectedAnnums.
Thank you.
Hi again.
ReplyDeleteI would like to finally share the solution to my html:multibox problem...
here it is:
<logic:iterate name="CourseReportForm" id="annumOption" property="annumOptions" >
<html:form action="courseReport.do"> <!-- THIS IS IMPORTANT -->
<html:multibox property="selectedAnnums">
<bean:write name="annumOption" property="label"/>
</html:multibox>
</html:form>
<bean:write name="annumOption" property="value"/><br>
</logic:iterate>
Action courseReport.do should be present in struts-config.jsp, as:
<global-forwards>
...
<forward name="courseReport" path="/courseReport.do"/>
</global-forwards>
AND (again in struts-config.xml)
<action-mappings>
...
<action
path="/courseReport"
type="uk.ac.port.viewpoint.control.CourseReportAction"
name="CourseReportForm"
scope="request">
<forward name="success" path="/courseReport.jsp"/>
</action>
</action-mappings>
Hope you find it useful!
Yes, you'd have to make sure that the multibox is contained within a form. ;-)
ReplyDeleteI'd move the form defination OUT of the iterate loop though... it would make more sense when you're reading the html.
I don't understand why you'd put the forward as a global forward... are you accessing it from different action classes? If you're just calling it from the CourseReportAction class then the local forward defination should be enough.
All the best. ;-)
The reason I am doing that is because I associate this action with an from a previous jsp.
ReplyDelete