Tuesday, December 29, 2009

Tag checkboxes in Spring MVC


In jsp page with Spring MVC you can use form tags.


With tag checkboxes you can create elegant structure of code in form, for example if you have typical 1:N or M:N relation between model classes.


I show 1:N relation between SECTION and PRODUCT class. It example uses Spring MVC and form-tag checkboxes.


Class Section

Section class is common POJO. Class contains reference to Product class.


public class Section {
...
private List products;
...
}

Class Product

Correct designed method boolean equals:Obj is very important for useful usage checkboxes tag.



public class Product {

private Integer Id;
private String title;

...

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Product other = (Product) obj;
if (this.Id != other.Id && (this.Id == null || !this.Id.equals(other.Id))) {
return false;
}
if ((this.title == null) ? (other.title != null) : !this.title.equals(other.title)) {
return false;
}
return true;
}
}

Controller

It is important create Property editor for reference class (Product). Property editor is register in method initBinder. As you see the attribute allProducts in method getAllProducts is automatically putting to model. It is need in view section_edit.jsp.


@ModelAttribute("allProducts")
public List getAllProducts(){
return productDao.all();
}

@RequestMapping(value="/section_edit.htm", method=RequestMethod.GET)
public Section sectionEdit(Integer sectionId){
return sectionDao.findById(sectionId);
}

@RequestMapping(value="/section_edit.htm", method=RequestMethod.POST)
public String sectionEdit(Section section, Errors errors){
...
sectionDao.saveOrUpdate(section);
return "redirect:/sections.htm";
}

@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Product.class, new ProductPropertyEditor());
}

ProductPropertyEditor

In ProductProperty editor I override only method void setAsText:String. This method create Product instance from product.id represented as test in jsp form (section_edit.jsp).


public class ProductPropertyEditor extends PropertyEditorSupport{
...
@Override
public void setAsText(final String text) {
setValue(productDao.findById(Integer.parseInt(text)));
}

}

section_edit.jsp

Expression ${allProducts} read model attribute allProduct setting in controller. It contain List of all products. As value of checkboxes tag attribute itemValue I set id. It use product.id value and this value can read method void setAsText:String from ProductPropertyEditor, when user submit form.

When tag checkboxes iterate items allProducts, then every Product from allProducts List is compare with Product from Section.products List. When they are the same, then will be rendered checkbox with checked attribute.

Checkbox will bee checked when Product from List of Section.products equals Product from List of allProduct.

You must override toString method in reference object (Product). It is very important behaviour of checkboxes tag from Spring checkboxes tag documentation.

question_edit.jsp

Conclusion

Checkbox is checked when:


  • Property is Collection or array and contains the same Object as wrapped Collection.

1 comment: