1

here you see a working example for a wicket DropDownChoice, but this is not what I would like to have. The returned value of the dropdownchoice should be an integer matching the value. The return value of the dropdownchoice is:

returnedLabel=123 (String)
returnedDDCValue=LabelValue [label=TestB, value=3] (LabelValue)

For production returnedDDCValue should be an integer, filled with (integer) 3. I think that there must be a conversion done inside the ddc. I tried with IChoiceRenderer, but did not succeed. Plz help :)

Cheers

chris

public class DDCTest extends Panel {

    private List<LabelValue> list4ddc;

    public DDCTest(String id) {
        super(id);
        Result result = new Result();

        final FeedbackPanel feedback = new FeedbackPanel("feedback");
        feedback.setOutputMarkupId(true);
        add(feedback);

        this.list4ddc = new ArrayList<LabelValue>();
        this.list4ddc.add(new LabelValue("TestA", 1));
        this.list4ddc.add(new LabelValue("TestB", 3));
        this.list4ddc.add(new LabelValue("TestC", 5));
        this.list4ddc.add(new LabelValue("TestD", 7));

        Form form = new Form("form");
        add(form);

        form.add(new TextField<String>("returnedLabel", new PropertyModel<String>(result,"returnedLabel")));

        form.add( new DropDownChoice("returnedDDCValue", new PropertyModel(result,"returnedDDCValue"), Model.of(list4ddc), new ChoiceRenderer("label", "value")));

        form.add(new AjaxButton("submit", form) {
            @Override
            protected void onSubmit(AjaxRequestTarget target) {
                info("["+result.toString()+"]");
                target.add(feedback);
            }
        });

    }

    public class Result implements Serializable {
        private String returnedLabel;
        private String returnedDDCValue;

        public Result() {
            super();
            this.returnedLabel = "";
            this.returnedDDCValue = null;
        }

        [ ... Getters and setters ... ]

    }

    public class LabelValue implements Serializable {
        private String label;
        private Integer value;

        public LabelValue(String label, Integer value) {
            super();
            this.label = label;
            this.value = value;
        }

        [ ... Getters and setters ... ]
    }
}
thg
  • 1,209
  • 1
  • 14
  • 26
chris222
  • 11
  • 2
  • Do you mean you want to render the choices in the dropdown in a specific way or you want to change the form input value of the dropdown? – thg Mar 27 '18 at 09:03
  • My goal is that the property returnedDDCValue in the underlying object Result has the type Integer with the value from the selection. The DDC returns LabelValue. I found here: https://cwiki.apache.org/confluence/display/WICKET/DropDownChoice+Examples The ChoiceRenderer will use the value of the 'key' property of SelectOption object in the 'value' attribute in the rendered HTML (e. g. 'key' property value will be used as the option id). The 'value' property will be used as a display value for the given option. Your backing model must use SelectOption as compared to String in the simple example. – chris222 Mar 27 '18 at 09:49
  • "You give a DDC a model and a list of possible values. The type of object returned by the model and the type of objects in the list must be the same. If your model returns an Integer, so you must pass a list of Integers, not IntegerSelectChoice or anything else. As workaround I used one list with Integers for the DDC and got the labels from a hashmap. I thougt it could be more easy and integrated without the List and HashMap. – chris222 Mar 27 '18 at 09:58
  • The property returnedDDCValue is of type String, how does this conform to the desired Integer assignment? – Imperative Mar 27 '18 at 16:08
  • As I wrote is this a working example. Having it defined as Integer would not work. My goal is having it as Integer. See my last to posts. I found a workaround but I'm not happy with it. But you're right. In the productive version the DDC and ModelObject have it declared as Integer and the DDC Labels are resolved via a HashMap. It seems to me as a not so elegant solution... – chris222 Mar 27 '18 at 18:36

1 Answers1

1

I think I've did something very similar to what you need. It's a custom DDC which uses choice's value to set a third model:

public class DropDownChoiceForString<T> extends DropDownChoice<T> {

private IModel<String> targetModel;

public DropDownChoiceForString(String id, IModel<T> model, IModel<String> targetModel, 
        List<? extends T> choices,
        IChoiceRenderer<? super T> renderer) {
    super(id, model, choices, renderer);
    this.targetModel = targetModel;
}

protected DropDownChoiceForString(String id, IModel<T> model, IModel<String> targetModel) {
    this(id, model, targetModel, Collections.<T> emptyList(), null);
}

@Override
protected void onInitialize() {
    super.onInitialize();
    // load the initial choice.
    setModelObject(convertChoiceIdToChoice(targetModel.getObject()));
}

@Override
protected void onDetach() {
    super.onDetach();

    targetModel.detach();
}

@Override
protected void onModelChanged() {
    super.onModelChanged();

    T newSelection = getModelObject();

    int choiceIndex = getChoices().indexOf(newSelection);
    // update the string source with the selected value.
    targetModel.setObject(getChoiceRenderer().getIdValue(newSelection, choiceIndex));
}}

It works like a standard DDC but when its model is changed a target model is updated with the value of the new choice.

Andrea Del Bene
  • 2,521
  • 1
  • 15
  • 20