Stripes

stripes:text caches values for indexed properties

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Not a Bug
  • Affects Version/s: Release 1.4.3
  • Fix Version/s: Release 1.5
  • Component/s: Tag Library
  • Labels:
    None
  • Environment:
    Tomcat 6.0.13, Safari + Firefox on Mac OSX 10.5.1

Description

I have a form that dynamically creates controls so that multiple values for the same field can be entered. In the action bean after binding and validation is done, I remove null values from the list so that empty inputs aren't presented to the user. After this is done and the page is rendered again (say after validation of other fields), the values in the indexed text boxes are not rendered properly.

I have built a simple application to replicate the problem.
1) Deploy the attached WAR file
2) Access it under the context /StripesBug
3) Click on the + button 4 times. You will see 4 text fields each containing a value from names[0] through names[3].
4) Click the test button. The page will be redrawn with the same values in all 4 input fields, and then next to the in static text.
5) Click on the - button next to names[1], leaving names[0], names[2] and names[3]
6) Click the test link - you will now see 3 text boxes with names[0], names[2], names[2] in the input fields, but their real values from the iterator next to them in bold - names[0], names[2], names[3]. What has happened here is the action bean has removed the null value from position 1 in the index list and moved 2 & 3 back. When the page re-draws, it is getting the old value for position 2 (names[2]) not the new value (names[3]).

As a control, I have included a page /StripesBug/index_1.jsp which doesn't use the stripes:text control, just a normal html input with the attributes set the way stripes generates them. Follow the same steps as above on this page and in step 6 you will see the input fields contain names[0], names[2], names[3] - matching the static text printed next to them.

Activity

Hide
Chris Cheshire added a comment - 15/Jan/08 5:23 PM

Can be deployed to show the bug. Contains Stripes 1.4.3, and JSTL 1.1 libraries.

Show
Chris Cheshire added a comment - 15/Jan/08 5:23 PM Can be deployed to show the bug. Contains Stripes 1.4.3, and JSTL 1.1 libraries.
Hide
Chris Cheshire added a comment - 15/Jan/08 5:26 PM

Source for the attached bug.

Show
Chris Cheshire added a comment - 15/Jan/08 5:26 PM Source for the attached bug.
Hide
Chris Cheshire added a comment - 15/Jan/08 5:31 PM

Screenshot showing valid results (I tried using the attach screenshot applet but it didn't want to grab the clipboard contents on my Mac)

Show
Chris Cheshire added a comment - 15/Jan/08 5:31 PM Screenshot showing valid results (I tried using the attach screenshot applet but it didn't want to grab the clipboard contents on my Mac)
Hide
Chris Cheshire added a comment - 15/Jan/08 5:32 PM

Screenshot showing invalid results.

Show
Chris Cheshire added a comment - 15/Jan/08 5:32 PM Screenshot showing invalid results.
Hide
Chris Cheshire added a comment - 15/Jan/08 5:35 PM

Uploaded wrong snapshot first sorry. This one shows the expected results.

Show
Chris Cheshire added a comment - 15/Jan/08 5:35 PM Uploaded wrong snapshot first sorry. This one shows the expected results.
Hide
Chris Cheshire added a comment - 15/Jan/08 5:37 PM

Please ignore the second StripesBug-Valid.jpg file (15k). It is the wrong one.

Show
Chris Cheshire added a comment - 15/Jan/08 5:37 PM Please ignore the second StripesBug-Valid.jpg file (15k). It is the wrong one.
Hide
Chris Cheshire added a comment - 16/Jan/08 4:58 PM

Ben, you actually deleted the valid StripesBug-Valid.jpg. Delete the other one, and I'll reupload the right one

Show
Chris Cheshire added a comment - 16/Jan/08 4:58 PM Ben, you actually deleted the valid StripesBug-Valid.jpg. Delete the other one, and I'll reupload the right one
Hide
Ben Gunter added a comment - 16/Jan/08 10:04 PM

Doh. Sorry about that. I'll delete the remaining StripesBug-Valid.jpg.

Show
Ben Gunter added a comment - 16/Jan/08 10:04 PM Doh. Sorry about that. I'll delete the remaining StripesBug-Valid.jpg.
Hide
Ben Gunter added a comment - 20/Jan/08 12:21 AM

I just ran your test app and saw what you're talking about. This is not actually a bug. It is the result of the way Stripes populates form inputs. By default, Stripes will search for an input's value in the following order: a request parameter with the same name, a property of the form's ActionBean with the same name, the input tag's "value" attribute. The first non-null value found is used. The idea is to allow a page to show a default value in an input on the first load and then display the value the user entered on validation error.

In the case of your example app, the following occurs. You create four inputs named name[0-3] and submit them. After submit the inputs are rendered again using the values from the request parameters, which are what you expect: the matching name[0-3] strings. Then you remove the name[1] input, leaving you with name[0,2-3] with values matching the names. You submit those, and the list created from those inputs is modified to remove the element at index 1 leaving a list with values 0=name[0], 1=name[2], 2=name[3]. When Stripes renders the page again you're iterating over that list. The name[0] input finds its value name[0] in the request parameter. The name[1] input does not find a request parameter (since it had been removed before submit) and looks at the bean for the value, finding name[2]. So far, so good. Then it renders input name[2] and finds the name[2] parameter that was submitted and renders its value: name[2].

I changed the population strategy to BeanFirstPopulationStrategy, and that made it behave like you expected. You'll see the init-param you need to change the population strategy below. Keep in mind that this is a global setting and may adversely affect other areas of your site so you should test thoroughly. You might have to roll your own PopulationStrategy to suit your needs. I'm closing this issue as Not a Bug.

Add to StripesFilter config:

<init-param>
<param-name>PopulationStrategy.Class</param-name>
<param-value>net.sourceforge.stripes.tag.BeanFirstPopulationStrategy</param-value>
</init-param>

Show
Ben Gunter added a comment - 20/Jan/08 12:21 AM I just ran your test app and saw what you're talking about. This is not actually a bug. It is the result of the way Stripes populates form inputs. By default, Stripes will search for an input's value in the following order: a request parameter with the same name, a property of the form's ActionBean with the same name, the input tag's "value" attribute. The first non-null value found is used. The idea is to allow a page to show a default value in an input on the first load and then display the value the user entered on validation error. In the case of your example app, the following occurs. You create four inputs named name[0-3] and submit them. After submit the inputs are rendered again using the values from the request parameters, which are what you expect: the matching name[0-3] strings. Then you remove the name[1] input, leaving you with name[0,2-3] with values matching the names. You submit those, and the list created from those inputs is modified to remove the element at index 1 leaving a list with values 0=name[0], 1=name[2], 2=name[3]. When Stripes renders the page again you're iterating over that list. The name[0] input finds its value name[0] in the request parameter. The name[1] input does not find a request parameter (since it had been removed before submit) and looks at the bean for the value, finding name[2]. So far, so good. Then it renders input name[2] and finds the name[2] parameter that was submitted and renders its value: name[2]. I changed the population strategy to BeanFirstPopulationStrategy, and that made it behave like you expected. You'll see the init-param you need to change the population strategy below. Keep in mind that this is a global setting and may adversely affect other areas of your site so you should test thoroughly. You might have to roll your own PopulationStrategy to suit your needs. I'm closing this issue as Not a Bug. Add to StripesFilter config: <init-param> <param-name>PopulationStrategy.Class</param-name> <param-value>net.sourceforge.stripes.tag.BeanFirstPopulationStrategy</param-value> </init-param>
Hide
Ben Gunter added a comment - 20/Jan/08 12:25 AM

Correction. It is not the first non-null value that is used. It is the first one that exists. That is, if there is a request parameter with the same name then that parameter value is used, null or not. Likewise for the ActionBean property.

Show
Ben Gunter added a comment - 20/Jan/08 12:25 AM Correction. It is not the first non-null value that is used. It is the first one that exists. That is, if there is a request parameter with the same name then that parameter value is used, null or not. Likewise for the ActionBean property.
Hide
Chris Cheshire added a comment - 20/Jan/08 7:24 PM

Ben, thanks for looking into this. I am still a little confused over why it happens like this. Is this because it is a forward and there is still something stored in the request? Is this where the stripes:text tag is getting the values from to populate the form?

If so, can I replace the the values in the request when I "compress" the list? How would I got about doing this?

Show
Chris Cheshire added a comment - 20/Jan/08 7:24 PM Ben, thanks for looking into this. I am still a little confused over why it happens like this. Is this because it is a forward and there is still something stored in the request? Is this where the stripes:text tag is getting the values from to populate the form? If so, can I replace the the values in the request when I "compress" the list? How would I got about doing this?

People

Vote (1)
Watch (1)

Dates

  • Created:
    15/Jan/08 5:22 PM
    Updated:
    04/Jan/11 2:49 PM
    Resolved:
    20/Jan/08 12:21 AM