September 28, 2004

HTML labels in struts multibox

I'm blogging about this in the hope that this will help other people and save them the time that I have wasted tracking this down.

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. ;-)

Posted by jim at September 28, 2004 11:10 AM
Comments

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").

So, 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.

Posted by: Jim at September 29, 2004 06:31 PM

Thanks for the tip, it got me on the right track.
One 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>

Posted by: Mike at October 18, 2004 01:14 PM

That is an excellent point Mike. I never liked the cast at all.

Posted by: Jim at October 20, 2004 01:04 PM

Pls send m the detail example of
with iterator ,which briefs the multiple check boxes with dropdown list

Posted by: Vikas g at February 22, 2005 04:54 AM

Vikas, just look at Mike's post for a detailed example of using multiple check boxes.

The 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

Posted by: Jim at February 22, 2005 09:25 AM

Hi,
A very good example on indexId attribute of logic:iterate. Thanks a lot...

Posted by: Rajasekhar Cherukuri at July 8, 2005 11:02 AM

I am currently struggling to include the HTML:MULTIBOX code into a JSP file.

without 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

Posted by: Christos at April 1, 2006 06:13 PM

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.

If you still can't figure it out, post the code you've got trouble with and I can see what I can do. ;-)

Posted by: Jim at April 1, 2006 10:55 PM

First, thank you for the fast reply!

This 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.

Posted by: christos at April 2, 2006 07:37 AM

Hi again.

I 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!

Posted by: Christos at April 2, 2006 08:11 AM

Yes, you'd have to make sure that the multibox is contained within a form. ;-)

I'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. ;-)

Posted by: Jim at April 2, 2006 08:39 AM

The reason I am doing that is because I associate this action with an from a previous jsp.

Posted by: Christos at April 2, 2006 08:42 AM
Due to the proliferation of comment spam, I’ve had to close comments on this entry. If you would like to leave comment, please use one of my recent entries. Thank you and sorry for any inconvience caused.