mercredi 21 octobre 2015

Spring MVC checkbox bound to List of Objects

I have an entity with a List of other entities. The List should be filled through selection of checkboxes. When selecting a checkbox and submitting the form, the List is filled correctly. But the checkboxes are not preallocated when opening the page again.

For the creation of checkboxes I'm using a Map with the ID as key and a String as value (for the label).

Here is a small example:

The entity class:

@Entity
public class Pizza {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @OneToMany
    private List<Topping> toppings;

    private String name;

    // getters and setters
}

the Controller method for the page:

@RequestMapping(value = "/edit/{pizzaid}", method = RequestMethod.GET)
    public ModelAndView editPizza(ModelAndView mav, @PathVariable long pizzaid) {
        mav.setViewName("pizza_edit");
        mav.addObject("toppings", getToppingMap());
        Pizza pizza = pizzaRepo.findOne(pizzaid);
        mav.addObject("pizza", pizza);
        return mav;
    }

private Map<Long,String> getToppingMap(){
    Map<Long, String> result = new LinkedHashMap<>();
    for (Topping topping : toppingRepo.findAll()) {
        result.put(topping.getId(), topping.getName());
    }
    return result;
}

in the template (velocity) I'm using the macro provided by spring:

#springFormCheckboxes("pizza.toppings" $toppings "<br/>" "")

When posting the form back to the server, the following method is called:

@RequestMapping(value = "/edit/{pizzaid}", method = RequestMethod.POST)
    public ModelAndView savePizza(ModelAndView mav, @Valid Pizza pizza, BindingResult bindingResult, @PathVariable long pizzaid) {
        pizza.setId(pizzaid);
        pizzaRepo.save(pizza);
        mav.setViewName("pizza_edit");
        mav.addObject("toppings", getToppingMap());
        mav.addObject("pizza", pizza);
        return mav;
    }

Here, the List is filled fine with the Topping-entities corresponding to the selected IDs.

Now in the generated page, no checkbox is selected. It seems that the conversion from ID to Entity (request to entity) is done automatically, but the other direction (entity to html) does not work?

I tried to add a method to the pizza which returns the IDs for the preallocation of the checkbox:

public List<Long> getToppingIds() {
    List<Long> res = new ArrayList<>();
    if (toppings != null){
        for (Topping t : toppings) {
            res.add(t.getId());
        }
    }
    return res;
}

And then call this one for the macro

#springFormCheckboxes("pizza.toppingIds" $toppings "<br/>" "")  

Now the checkboxes are checked, which is fine. But the input-name is changed to toppingIds, so after submitting the form the List is not filled.

What would be the correct way to work with checkboxes, that reflect a List of Objects? (most examples I found use only Strings)




Aucun commentaire:

Enregistrer un commentaire