What I wonder is if there\'s a easier/better way to handle dynamic forms (adding form items to the dom via js) when using SpringMVC and Spring forms?
Imaging having
You could use the following
public class InvoiceController extends SimpleFormController {
protected void initBinder(HttpServletRequest request, ServletRequetDataBinder binder) throws Exception {
binder.registerCustomEditor(List.class, "lineItems", new CustomCollectionEditor(List.class)() {
protected Object convertElement(Object lineItem) {
LineItem li = (LineItem) lineItem;
// StringUtils is a jakarta Commons lang static class
return (StringUtils.isBlank(li.getProductName())) ? null : li;
}
});
}
}
Then in onBind method, you remove null references according to:
protected void onBind(HttpServletRequest request, Object command, BindException bindException) throws Exception {
Invoice invoice = (Invoice) command;
invoice.getLineItems().removeAll(Collections.singletonList(null));
}
Regards,
I've implemented a tutorial that might help you solve this using jQuery on the client side and Springs AutoPopulating list for you form backing objects.
http://eggsylife.co.uk/2009/11/30/spring-forms-dynamic-lists-and-ajax/
EDIT Link from Webarchive https://web.archive.org/web/20160729163958/http://eggsylife.co.uk/2009/11/30/spring-forms-dynamic-lists-and-ajax/
I've been struggling with this problem today and figured out some solution described here.
I've found that also decorating with a GrowthList is necessary to avoid some errors when adding/setting items in JSP. (Also created a custom SpringList impl. that basically does the double decoration.)
lineItems = GrowthList.decorate(ListUtils.lazyList(new ArrayList<LineItem>(), FactoryUtils.instantiateFactory(LineItem.class)));
I agree. The problem is certainly removing items.
What you can do is use the spring marker syntax in the html. So if you remove an item (at index 2 for example) from the list using javascript, you would then mark that index with:
<input type="hidden" name="_lineItems[2]">
Then when the form is submitted spring will see the marker and put in an empty item (based on the lazylist factory) for lineItems2 instead of ignoring it.