Wesley De Keirsmaeker
Wesley De Keirsmaeker

Reputation: 1025

Wicket: Setting value of DropDownChoice with CompoundPropertyModel

I'm filling a form with data from a CompoundPropertyModel. My TextArea and DateTextField get their value by using the name of the field of the Model as the Id so it will look for a Model in it's parents and find the value through reflection, as described in https://ci.apache.org/projects/wicket/guide/6.x/guide/modelsforms.html. But I fail to get this working for my DropDownChoice. The value stays null.

Would love to hear if someone knows what I'm doing wrong. Currently have a workarround in place where I give a PropertyModel of the FotoGroep to my DropDownChoice constructor.

Class:

public class ImageControlForm<T extends Foto> extends StatelessForm<Foto> {

    private TextArea<String> beschrijving;
    private DateTextField datum;
    private DropDownChoice<FotoGroep> groep;

    public ImageControlForm(String id, CompoundPropertyModel<Foto> fotoModel) {
        super(id, fotoModel);

        setMultiPart(true);
        setDefaultModel(fotoModel);

        add(maakBeschrijvingField());
        add(maakDatumField());
        add(maakGroepField());
    }

    private TextArea<?> maakBeschrijvingField() {
        beschrijving = new TextArea<>("beschrijving");
        return beschrijving;
    }

    private DateTextField maakDatumField() {
        datum = new DateTextField("datum", "d/M/yy");
        datum.add(new DatumPicker());
        return datum;
    }

    private DropDownChoice<FotoGroep> maakGroepField() {
        Order sortOrder = Helper.createOrder("naam", SortOrder.ASC);
        List<FotoGroep> fotoGroepen = databaseService.getPictureGroups(sortOrder);
        groep = new DropDownChoice<>("fotoGroep", fotoGroepen, new ChoiceRenderer<FotoGroep>("naam", "fotoGroepId"));
        groep.isRequired();
        return groep;
    }

Foto:

@Entity
@Table(name = "XS_FOTO")
public class Foto extends BasisModel implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "FOTO_ID")
    private Long fotoId;

    @Column(name = "BESCHRIJVING", nullable = true)
    private String beschrijving;

    @Column(name = "DATUM", nullable = true)
    @Temporal(TemporalType.DATE)
    private Date datum;

    @ManyToOne
    @JoinColumn(name = "FOTO_GROEP_ID", nullable = false)
    private FotoGroep fotoGroep = new FotoGroep(Long.valueOf(12));

    (getters and setters)

FotoGroep:

@Entity
@Table(name = "XS_FOTO_GROEP")
public class FotoGroep extends BasisModel implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "FOTO_GROEP_ID")
    private Long fotoGroepId;

    @Column(name = "NAAM", nullable = false)
    private String naam;

    @Override
    public boolean equals(Object object) {
        return (this.getFotoGroepId().equals(((FotoGroep)object).getFotoGroepId()));
    }

    @Override
    public int hashCode() {
        return Objects.hash(fotoGroepId, naam, beschrijving, datum);
    }

    (getters and setters)

As requested, I tried overriding equals and hashCode but without succes. I debugged and the foto.fotoGroep.fotoGroepId is the same as the only fotoGroep.fotoGroepId in the List<FotoGroepen>. Both FotoGroep even are the same bean at runtime. My unit test put's the same FotoGroep in the list as in the Model.

Edit, possible bad unit test(?): I was testing the value of my DropDownChoice with:

assertEquals("456", formTester.getTextComponentValue("fotoGroep"));

The value kept returning Null. BUT when I check the HTML, I can see that the right option is selected:

<select wicket:id="fotoGroep" name="fotoGroep" disabled="disabled">
    <option value="123">naam</option>
    <option value="123">naam</option>
    <option value="123">naam</option>
    <option value="123">naam</option>
    <option value="123">naam</option>
    <option value="123">naam</option>
    <option selected="selected" value="456">naam</option>
</select>

Could someone explain this behavior? When using a PropertyModel inside my DropDownChoice it also sets the value, but not when using the Model inheritance.

Upvotes: 0

Views: 783

Answers (1)

Wesley De Keirsmaeker
Wesley De Keirsmaeker

Reputation: 1025

I was testing DropDownChoice wrong.

I was testing the value of the DropDownChoice:

assertEquals("456", formTester.getTextComponentValue("fotoGroep"));

But in my case, this value was never set, BUT the right option was selected! I've changed my test to:

DropDownChoice<FotoGroep> dropDownChoice = (DropDownChoice)tester.getComponentFromLastRenderedPage("imageControlPanel:imageControlForm:fotoGroep");
dropDownChoice.setModelObject(createFotoGroep);
tester.assertModelValue("imageControlPanel:imageControlForm:fotoGroep", dropDownChoice.getModelObject());

The test will take the DropDownChoice, set the value you are expecting and then compare the Models of both.

Upvotes: 2

Related Questions