I am using a SimpleFormController to help create an object using an HTTP form. Obviously, if my form object is a Vendor, that object has a setName(String) method, and my HTTP form has a field named "name", the Controller will try call Vendor.setName(String) and pass in the value from the form. This also goes for nested properties: address.setCity -> vendor.getAddress().setCity(String).
My question is, is there any support for *indexed* properties? By that, I mean purchaseOrder[0].number -> ( (PurchaseOrder) vendor.getPurchaseOrders().get(0)).setNumber(). I know that some expression languages support something like this. IIRC, Struts has something like this, but it has a little kludgy.
From what I can tell, nested porperies are supported by the Spring BeanWrapperImpl, but that is it. If this is correct and I want to implement nested properties, any suggestion as to the best route.
Thanks.
Ryan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Unfortunately there isn't proper support for indexed or mapped properties yet. The getIndexedPropertyValue method in BeanWrapper is misleading; effectively, that method shouldn't even be there.
Regarding Struts, I know that Jakarta Commons BeanUtils supports indexed and mapped properties, so I suppose that Struts' form binding does too.
I've just raised the topic on the developer list. We definitely need to look into this. For the time being, I'm afraid that we support sophisticated property type conversion and type mismatch handling on form binding but no indexed or mapped properties.
Juergen
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm wondering what's the status on this feature request. Did anything get committed to RC2? If not, what is a good workaround for handling a collection of items submitted from a web form?
Thanks very much!
Seth
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
We have support for setting properties of indexed and mapped sub-beans, already since November. For example, assuming that you hold beans with a "name" property in collections:
Thanks for the very helpful reply. Any advice on handling an array of Strings? I'm trying to port our Struts applications over to Spring MVC, and a lot of our form beans have String[] as members (to handle multiple check boxes or multiple select boxes).
If it is inadvisable to handle multiple selects that way, is there another good way? I don't want to create a java bean wrapper for a String (or another primitive) if we can avoid it.
Thanks again!
Seth
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
<snip>Note that you cannot set the collection elements themselves, just properties of collection elements. This is the typical usage of such data binding.</snip>
So what is the typical way of adding new elements to a collection and setting properties on them ? if I try to bind to an element of a set that doesn't exist yet I get an error.. would I have to prepopulate the Collection with 'empty' objects ready to be populated, or is there a better way ?
many thanks,
..Camilla
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I just saw that you replied to another user with the same question as me ;-)
You seem to indicate that this would be a useful feature. How much effort do you think would be involved in adding this feature? If you point me in the right direction, I could help put this together.
BTW - I came across this the same way the other poster did. I have a form that is creating a parent-children set of objects (think PO + line items). Without this feature, there is no elegant way to auto-populate the form objects. I think this would be a great enhancement.
Ryan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2003-10-25
Juergen, Ryan
Interesing coincidence. I also noticed recently that BeanWrapperImpl doesn't fully support indexed properties and I had a form that needed bindings to indexed properties, so last night I hacked in some changes to BeanWrapperImpl to support getting and setting with expressions like foo[2].bar or foo.bar[3] etc. You're welcome to this code if it's of any use to you as a starting point.
It's not at all polished (there's a lot of nasty "if(indexed) dothis else dothat" style hackery which could do with some refactoring. There's no support for mapped properties. It also doesn't support property change events correctly at the moment.
Another issue which you might want to bear in mind is that it's probably a good idea to try to avoid ending up with raw expressions being used as form element names. What I mean is you probably don't really want to have stuff like this in your html:
<input type="text" name="foo[2].baz"/>
This is legal html (element names are CDATA), but it's not a valid javascript identifier, which might trip someone up at some stage.
I'm planning to have my forms have something like:
<input type="text" name="foo_2_baz"/>
The DataBinder would then intecept this and tranform it to foo[2].baz to pass to the BeanWrapper. (Probably there should be a tag that will let you write foo[2].baz in your jsp and transform this to foo_2_baz in the html)
Cheers
David
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am using a SimpleFormController to help create an object using an HTTP form. Obviously, if my form object is a Vendor, that object has a setName(String) method, and my HTTP form has a field named "name", the Controller will try call Vendor.setName(String) and pass in the value from the form. This also goes for nested properties: address.setCity -> vendor.getAddress().setCity(String).
My question is, is there any support for *indexed* properties? By that, I mean purchaseOrder[0].number -> ( (PurchaseOrder) vendor.getPurchaseOrders().get(0)).setNumber(). I know that some expression languages support something like this. IIRC, Struts has something like this, but it has a little kludgy.
From what I can tell, nested porperies are supported by the Spring BeanWrapperImpl, but that is it. If this is correct and I want to implement nested properties, any suggestion as to the best route.
Thanks.
Ryan
Hi Ryan,
Unfortunately there isn't proper support for indexed or mapped properties yet. The getIndexedPropertyValue method in BeanWrapper is misleading; effectively, that method shouldn't even be there.
Regarding Struts, I know that Jakarta Commons BeanUtils supports indexed and mapped properties, so I suppose that Struts' form binding does too.
I've just raised the topic on the developer list. We definitely need to look into this. For the time being, I'm afraid that we support sophisticated property type conversion and type mismatch handling on form binding but no indexed or mapped properties.
Juergen
Hello,
I'm wondering what's the status on this feature request. Did anything get committed to RC2? If not, what is a good workaround for handling a collection of items submitted from a web form?
Thanks very much!
Seth
We have support for setting properties of indexed and mapped sub-beans, already since November. For example, assuming that you hold beans with a "name" property in collections:
- "myBean.myArray[0].name"
- "myBean.myList[1].name"
- "myBean.myMap[myKey].name"
Note that you cannot set the collection elements themselves, just properties of collection elements. This is the typical usage of such data binding.
This is most useful for web form fields but also works for plain DataBinder or BeanWrapper usage.
Juergen
Juergen,
Thanks for the very helpful reply. Any advice on handling an array of Strings? I'm trying to port our Struts applications over to Spring MVC, and a lot of our form beans have String[] as members (to handle multiple check boxes or multiple select boxes).
If it is inadvisable to handle multiple selects that way, is there another good way? I don't want to create a java bean wrapper for a String (or another primitive) if we can avoid it.
Thanks again!
Seth
Hi,
<snip>Note that you cannot set the collection elements themselves, just properties of collection elements. This is the typical usage of such data binding.</snip>
So what is the typical way of adding new elements to a collection and setting properties on them ? if I try to bind to an element of a set that doesn't exist yet I get an error.. would I have to prepopulate the Collection with 'empty' objects ready to be populated, or is there a better way ?
many thanks,
..Camilla
Juergen,
I just saw that you replied to another user with the same question as me ;-)
You seem to indicate that this would be a useful feature. How much effort do you think would be involved in adding this feature? If you point me in the right direction, I could help put this together.
BTW - I came across this the same way the other poster did. I have a form that is creating a parent-children set of objects (think PO + line items). Without this feature, there is no elegant way to auto-populate the form objects. I think this would be a great enhancement.
Ryan
Juergen, Ryan
Interesing coincidence. I also noticed recently that BeanWrapperImpl doesn't fully support indexed properties and I had a form that needed bindings to indexed properties, so last night I hacked in some changes to BeanWrapperImpl to support getting and setting with expressions like foo[2].bar or foo.bar[3] etc. You're welcome to this code if it's of any use to you as a starting point.
It's not at all polished (there's a lot of nasty "if(indexed) dothis else dothat" style hackery which could do with some refactoring. There's no support for mapped properties. It also doesn't support property change events correctly at the moment.
Another issue which you might want to bear in mind is that it's probably a good idea to try to avoid ending up with raw expressions being used as form element names. What I mean is you probably don't really want to have stuff like this in your html:
<input type="text" name="foo[2].baz"/>
This is legal html (element names are CDATA), but it's not a valid javascript identifier, which might trip someone up at some stage.
I'm planning to have my forms have something like:
<input type="text" name="foo_2_baz"/>
The DataBinder would then intecept this and tranform it to foo[2].baz to pass to the BeanWrapper. (Probably there should be a tag that will let you write foo[2].baz in your jsp and transform this to foo_2_baz in the html)
Cheers
David
David,
I would be interested in taking a look at this code. You can reach me at ryan_breidenbach at hotmail.com.
Thanks.
Ryan