0

I am validating list of objects. In order to show users what they typed wrong, I need to repopulate fields on conversion error. I read that in order to repopulate fields value on page I need to do something like this:

<s:textfield name="user.name" value="%{user.name}"/>

For repopulating array, I must refer to them through indices. As mentioned here: update a list of value in textfield in struts2

I have a list of Users, that I need to validate. I have my own index counter on iterator for specific reason.

<s:set name="counter" value="0"/>
<s:iterator value="users" var="user">
   <s:textfield name="users[%{#counter}].birthdate" value="%{users[#counter].birthdate}"/>
   <s:set name="counter" value ="%{#counter + 1}"/>
</s:iterator>

I am using visitor validator for object User.

<field name="birthdate">
    <field-validator type="conversion">
        <param name="repopulateField">true</param>
            <message>${getText("E011", {"birthdate"})}</message>
    </field-validator>
</field>

As I said, I am not using iterator index counter for specific reason.

The problem is this value="%{users[#counter].birthdate}" part is not working. If I change counter to 0 it repopulates the value of users[0].birthdate right. Seems like it is not getting value of counter in OGNL expression.

I tried with:

value="%{users[counter].birthdate}"
value="%{users[%{#counter}].birthdate}"
...
and so on.

Can somebody help me to make this work?

UPDATE

It ended up that I should have mentioned my special case:

<s:iterator value="users" var="user" status="status">
  <s:if test="#status.index != removeIndex">

I found out that I don't need to specify value for field name for it to repopulate values. But I needed to use that because of this line:

<s:if test="#status.index != removeIndex">

It will take lots of my English effort to explain why you guys misunderstood me. Can we delete this post?. Thanks

Community
  • 1
  • 1
batbaatar
  • 5,448
  • 2
  • 20
  • 26
  • counter value will be work to point birthday property of the Object in your list like `users.get(0).getBirthDay();`, which means counter is not actually there. – Umesh Awasthi Feb 10 '12 at 11:28
  • What's the "specific reason" for not using what's already available? – Dave Newton Feb 10 '12 at 11:36
  • though we can use Prepare interceptor which take care of making values available even if there is any error but still i don't think your index value will be there.Why you using index?? may be there can be other alternate – Umesh Awasthi Feb 10 '12 at 11:36
  • Actually even I use #status.index, I cannot make this work. I am omitting some value on my list by filtering indexes. That is why I am using my alternate index counter – batbaatar Feb 10 '12 at 11:38

2 Answers2

0

Please try with the below code, it may work

<s:set name="counter" value="0"/>
<s:iterator value="users" var="user">
  <s:textfield name="users[#counter].birthdate" value="%{users[#counter].birthdate}"/>
  <s:set name="counter" value ="%{#counter + 1}"/>
</s:iterator>
mini
  • 545
  • 3
  • 8
  • I don't think so, my counter is working properly on other struts tags. When I change counter to 0, it gets the value of users[0].birthdate right. When I use the code above, it shows nothing on the field. – batbaatar Feb 10 '12 at 12:00
  • I don't have a variable called COUNTER on my JAVA, would it cause this problem? – batbaatar Feb 10 '12 at 12:01
  • What do you mean by "fixed the OGNL". What was wrong with my OGNL? – batbaatar Feb 10 '12 at 12:14
  • Ok. But that correct OGNL is not working on my project. As I told you, if I put constant value like this: value="%{users[0].birthdate}" it gets the value right. That is why I don't think there is something wrong with my List. – batbaatar Feb 10 '12 at 12:23
  • @DaveNewton I am sorry, I don't believe you tried it on your computer. Can you show me the whole code you used? Using pastebin or something. Maybe I can get my mistakes by seeing yours – batbaatar Feb 10 '12 at 12:30
0

It's better if you ask how to do something... rather than say you have a reason for doing it this way and of course this way isn't working. It gives me a headache...

I don't understand this...

<s:set name="counter" value="0"/>
<s:iterator value="users" var="user">
   <s:textfield name="users[%{#counter}].birthdate" value="{users[counter].birthdate}"/>
   <s:set name="counter" value ="%{#counter + 1}"/>
</s:iterator>

I'll rewrite (without testing) what I think you mean...

<s:iterator value="users">
   <s:textfield name="users.birthdate" value="birthdate"/>
</s:iterator>

The above requires that the following conditions be met... a) That "users" is a list of type "User" and b) that the struts2 conversion framework has been told that users is a list of type "User" which is as simple as adding an annotation like so: http://struts.apache.org/2.3.1.2/docs/keyproperty-annotation.html

With those conditions met... Send as many at one time without the mess of needing to use array notation and you can repopulate the fields.

Now, why would you expect the form values to repopulate after it failed to submit? That is how are you using validation? If for some reason you aren't you have created some action mapping on a value of INPUT or ERROR to direct back to the input page (kind of a waste of effort when the validation framework exists).

Quaternion
  • 10,380
  • 6
  • 51
  • 102
  • Sorry If I am being a stubborn here. Our company have some policies, we must avoid annotations as much as possible. So application can have a scalability. That is the reason why I am using array notations. According to the user specifications, form values must be repopulated if it fails on validation. I don't know why your revised code of mine is not working on my project. Maybe the annotation, I guess?. I am using Struts 2.2.3 and Hibernate 4.0. Sorry If I am being the only stubborn here – batbaatar Feb 11 '12 at 06:20
  • @batbaatar: what's the relation of scalability with annotation? – Umesh Awasthi Feb 11 '12 at 10:30
  • I guess, we don't want to type constant strings on java but rather on XMLs on properties files – batbaatar Feb 11 '12 at 10:40
  • Annotations make things far more readable, I like xml but for things that are more global settings. Setting struts2 constants or defining interceptor stacks makes the most sense to me in struts.xml, declaring my spring services with xml makes sense. But in the provided example struts2 will assume the value of the list is String or the value of a map is String. Because of erasure it can't know better so you need to tell it the type, an annotation makes the most sense. But you can, if you really want use a property file... you'll see how in the documentation. – Quaternion Feb 11 '12 at 20:35