You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Mark <st...@webpit.com> on 2003/03/06 06:06:54 UTC

Html taglib indexed+mapactionform bug?

I wanted to post this here before opening a case so that I could foster some discussion beforehand. 

Ok, This is a bit hard for me to describe, please be patient.  I have indeed tried to find this in the archives but to no avail.

I will also admit that there are probably a miniscule number of people who might be affected by this, but here goes nonetheless

This problem occurs when you use an index html: field with a map based form.

In my application, I have to show a series of "forms" on one screen that essentially enable the user to configure more than one similar items at a time.  So, if they add 7 "cars" to their order form, they can configure each car on one screen (color, make, model, etc).  This is hypotethical of course, but the analogy is good.  So instead of going through 7 screens, they can do it all on one.  For this, I use indexed fields and a Hashmap/MapActionForm which I borrowed from the Struts user guides.

In the instructions, we are told to use this style of property fetching for MapActionForms:

<html:text property="value(color)"/>

Adding to the mix Indexed fields, 

<html:text indexed="true" property="value(color)"/>

Our desirable html output should be:

<input type="text" name="value(color_0)">

However, using the combination above, our actual html html field is rendered like so:

<input type="text" name="org.apache.struts.taglib.html.BEAN[0].value(color)">
<input type="text" name="org.apache.struts.taglib.html.BEAN[1].value(color)">
... and so on, incrementing the BEAN[x] for each iteration

Thus, this is incorrect.  The MapActionForm gets no values. 

I have remedied this problem with a hack, and submit it to you guys for review and possibly "doing it better" since my way probably isnt optimal.  

The problem we need to solve is, the property="value(firstname)" needs to have a counter appended to whats inside the () rather than prepending something on the left.

Since whats inside the parens is our "fieldname" and to accomplish an indexed field, we need to append the index value, what we really want is

value(color_0)
value(color_1)

etc
etc

I've had to fix several files to remedy this:

BaseFieldTag.java
BaseHandlerTag.java
CheckboxTag.java
RadioTag.java
SelectTag.java
TextareaTag.java


However, I think all the html tags are affected, and should be fixed if the dev team determines this is indeed a bug.
I had to fix BaseHandlerTag like so:

previous:
  // this code builds the name org.apache.struts.taglib.html.BEAN[0].
        if (name != null)
            handlers.append(name);
        handlers.append("[");
        handlers.append(iterateTag.getIndex());
        handlers.append("]");
        if (name != null)
            handlers.append(".");


new:


        if (name != null)
        {
           handlers.append(name);
           handlers.append("_");
        }
        handlers.append("_");
        handlers.append(iterateTag.getIndex());




A diff from BaseFieldTag should give you the fix:

E:\jakarta-struts-1.1-b3-src\src\share\org\apache\struts\taglib\html>diff BaseFieldTag.java ../html-prev/BaseFieldTag.java
142,160c142,145
<       // if we are using an indexed field, we need to do something
<       // special for map based properties
<       if( indexed )
<       {
<             // are we using a map based property?
<             if(this.property.indexOf("(")>0)
<           {
<                 // figure out our prefix and suffix based on where the first ( is found.
<                 // the goal here is to render our field like value(firstname_0) .. value(firstname_1) etc
<                 // rather than the original struts way of org.apache.struts.taglib.html.BEAN[0].value(firstname)
<               String prefix=this.property.substring(0,this.property.indexOf(")"));
<               results.append(prefix);
<               prepareIndex(results,null);
<               results.append(")");
<             } else // otherwise just proceed as normal
<                 prepareIndex( results, name );
<       } else
<               results.append(this.property);
<
---
>         // * @since Struts 1.1
>         if (indexed)
>             prepareIndex(results, name);
>         results.append(property);

Regards,
Mark Williamson



---------------------------------------------------------------------
To unsubscribe, e-mail: struts-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-dev-help@jakarta.apache.org