开发者

Wicket children panels refresh

I'm just looking for extra pair of eyes to spot why children panels do not show up/change visibility on radio button selection/change that does call for their refresh


public class OptionsPanel extends Panel {
    private AutoCompleteSearchField departureField;
    private HiddenField departureCodeField;
    private CompoundPropertyModel model;
    private RadioGroup flightChoices;
    private RadioGroup dateChoices;
    private final TripSearchModel tripSearchModel;
    private WebMarkupContainer optionsContainer;
    private FlexibleDates flexibleDates;
    private FixedDates fixedDates;
    private PassengersAndClass passengersAndClass;
    private static List FIX_CONTAINER_VISIBLE = Lists.newArrayList(true, false, true);
    private static List FLEX_CONTAINER_VISIBLE = Lists.newArrayList(false, true, true);
    private static List HIDE_CONTAINERS = Lists.newArrayList(false, false, false);

    public OptionsPanel(String id, CompoundPropertyModel model) {
        super(id);
        this.model = model;
        this.tripSearchModel = (TripSearchModel) model.getObject();

        add(departureLabel());
        add(departureField());
        add(departureCodeField());

        add(flightType());
        add(travellingWhen());
        add(dateType());

        add(optionsContainer(HIDE_CONTAINERS));
    }

    private Component departureLabel() {
        return new WebMarkupContainer("departureLabel").setOutputMarkupId(true);
    }

    private AutoCompleteSearchField departureField() {
        departureField = new AutoCompleteSearchField("departureField", "From", "flightFromField", null, true, model.bind("departure"));
        departureField.setOutputMarkupId(true);
        departureField.add(new CityValidator(this, departureCodeField));
        return departureField;
    }

    private HiddenField departureCodeField() {
        departureCodeField = new HiddenField("departureCodeField", model.bind("departureCode"));
        departureCodeField.setMarkupId("departureFieldCode");
        return departureCodeField;
    }

    private Component flightType(){
        flightChoices = new RadioGroup("flightTypes");
        flightChoices.setModel(model.bind("tripType"));
        flightChoices.add(listOfRadio(flightsTypeList(), "flightType"));
        return flightChoices;
    }

    private List flightsTypeList() {
        return Arrays.asList(
                new RadioOptionObject("one way", new Model(TRIP_TYPE_ONE_WAY)),开发者_运维问答
                new RadioOptionObject("return", new Model(TRIP_TYPE_RETURN))
        );
    }

    private Component travellingWhen(){
        return new Label("travellingWhen", new StringResourceModel("travelling_when", this, new Model("")).getString());
    }

    private Component dateType(){
        dateChoices = new RadioGroup("dateTypes");
        dateChoices.setModel(model.bind("dateType"));
        dateChoices.add(listOfRadio(datesTypeList(), "dateType"));
        return dateChoices;
    }

    private List datesTypeList() {
        return Arrays.asList(
                new RadioOptionObject("Flexible dates", new Model(DATE_TYPE_FLEX)),
                new RadioOptionObject("Fixed dates", new Model(DATE_TYPE_FIX)));
    }

    private ListView listOfRadio(final List flightDateOptionValues, final String componentId) {
        ListView listView = new ListView(componentId + "sList", flightDateOptionValues) {
            @Override
            protected void populateItem(final ListItem listItem) {
                final Radio radio = new Radio(componentId + "Radio", ((RadioOptionObject) listItem.getModelObject()).getRadioModel()) {
                    @Override
                    public String getValue() {
                        return listItem.getDefaultModelObjectAsString();
                    }

                    @Override
                    protected boolean getStatelessHint() {
                        return true;
                    }
                };
                radio.add(new AjaxEventBehavior("onchange") {
                    @Override
                    protected void onEvent(AjaxRequestTarget target) {
                        tripSearchModel.setDateType(radio.getModelObject().toString());
                        refreshPanel(target);
                    }
                });
                listItem.add(radio);
                listItem.add(new Label(componentId + "Name", new StringResourceModel(radio.getModelObject().toString(), this, radio.getModel())));
            }
        };
        return listView;
    }

    private void refreshPanel(AjaxRequestTarget target) {
        this.remove(optionsContainer);
        target.addComponent(optionsContainer(visibility()));
    }

    private List visibility() {
        return visibilityMode(((TripSearchModel) model.getObject()).getDateType());
    }

    private Component optionsContainer(List visibility){
        optionsContainer = new WebMarkupContainer("optionsContainer");
        optionsContainer.add(flexibleDates(visibility.get(0)));
        optionsContainer.add(fixedDates(visibility.get(1)));
        optionsContainer.add(passengersAndClass(visibility.get(2)));
        optionsContainer.setOutputMarkupId(true);
        optionsContainer.setVisible(true);
        return optionsContainer;
    }

    private Component flexibleDates(Boolean visibility){
        flexibleDates = new FlexibleDates("flexibleDates", model);
        flexibleDates.setOutputMarkupId(true);
        flexibleDates.setVisible(visibility);
        return flexibleDates;
    }

    private Component fixedDates(Boolean visibility){
        fixedDates = new FixedDates("fixedDates", model);
        fixedDates.setOutputMarkupId(true);
        fixedDates.setVisible(visibility);
        return fixedDates;
    }

    private Component passengersAndClass(Boolean visibility){
        passengersAndClass = new PassengersAndClass("passengersAndClass", model);
        passengersAndClass.setOutputMarkupId(true);
        passengersAndClass.setVisible(visibility);
        return passengersAndClass;
    }

    private List visibilityMode(String dateType) {
        if(DATE_TYPE_FIX.equalsIgnoreCase(dateType)){
            return FIX_CONTAINER_VISIBLE;
        } else if(DATE_TYPE_FLEX.equalsIgnoreCase(dateType)){
            return FLEX_CONTAINER_VISIBLE;
        } else{
            return HIDE_CONTAINERS;
        }
    }
}


I think one potential issue you may have is that you listen for ajax-onchange events and you attempt to make changes to panels depending on the model supposedly having changed. In my experience with radio-type form components, you may need to use AjaxFormComponentUpdatingBehavior (instead of AjaxEventBehavior) in order to capture changes to a model of such form-components. Hope this helps!

Edit: Instead of listing caveats (you need to use another type of behavior for some form components), I'll just add a link to the documentation: Javadoc for AjaxFormComponentUpdatingBehavior


At the end of the day I find out that there was another Easter egg hidden for me.

radio.add(new AjaxEventBehavior("onchange") {
                    @Override
                    protected void onEvent(AjaxRequestTarget target) {
                        tripSearchModel.setDateType(radio.getModelObject().toString());
                        refreshPanel(target);
                    }

I was changing same date parameter on event of two different radio groups, which rendered form useless. That was one change, the second change was moving from WebMarkupContainer to EnclosureContainer that was suggested to use on Wicket mailing list for components changing their visibility status. Nevertheless I will give it a try with AjaxFormComponentUpdatingBehavior thank you @Martin Peters

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜