在wicket DateTimeField中获取用户输入

时间:2016-09-12 14:19:48

标签: java wicket

我正在尝试获取DateTimeField的用户选择值,但是失败了。我目前有以下代码,它适用于我的DropDownChoice对象:

public class DateTimeFieldPanel extends Panel {

    private final Date date;
    private String value;

    public DateTimeFieldPanel(Date date) {
        super("component");
        this.date = date;

        final DateTimeField dateTimeField = new DateTimeField("dateTimeField", new PropertyModel<Date>(this, "date"));

        dateTimeField.add(new AjaxFormComponentUpdatingBehavior("onchange") {

            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                value = dateTimeField.getModel().getObject().toString();
            }
        });

        add(dateTimeField);
    }

    public Date getDate() {
        return date;
    }
}

问题是模型由于某种原因没有对象,因此getObject()返回null。 我究竟做错了什么?为什么这适用于DropDownChoicePanel而不适用于DateTimeField?

非常感谢!

更新: 我现在有这个烂摊子:

dateTimeField = new DateTimeField("dateTimeField", new PropertyModel<Date>(this, "date")) {

        @Override
        protected DateTextField newDateTextField(String id, PropertyModel dateFieldModel) {
            final DateTextField dateField = super.newDateTextField(id, dateFieldModel);
            dateField.add(new AjaxFormComponentUpdatingBehavior("change") {

                @Override
                protected void onUpdate(AjaxRequestTarget target) {
                    processInput();
                }
            });
            return dateField;

        }

        @Override
        protected TextField<Integer> newHoursTextField(final String id, IModel<Integer> model, Class<Integer> type) {
            final TextField<Integer> hoursTextField = new TextField<Integer>(id, model, type);
            hoursTextField.add(new AjaxFormComponentUpdatingBehavior("change") {

                @Override
                protected void onUpdate(AjaxRequestTarget target) {
                    processInput();
                }
            });

            hoursTextField.add(getMaximumHours() == 24 ? RangeValidator.range(0, 23) : RangeValidator.range(1, 12));
            hoursTextField.setLabel(new Model<String>(HOURS));
            return hoursTextField;
        }

        private int getMaximumHours() {
            return getMaximumHours(use12HourFormat());
        }

        private int getMaximumHours(boolean use12HourFormat) {
            return use12HourFormat ? 12 : 24;
        }

        @Override
        protected boolean use12HourFormat() {
            String pattern = DateTimeFormat.patternForStyle("-S", getLocale());
            return pattern.indexOf('a') != -1 || pattern.indexOf('h') != -1 || pattern.indexOf('K') != -1;
        }
    };

基本上我发现DateTimeField包含三个TextFields,一个用于日期,小时和分钟。我必须通过覆盖创建它们的方法单独向这些字段添加ajax行为,然后调用processInput()以便更新DateTimeField的ModelObject。这适用于日期部分。对于小时,我可以覆盖创建字段的方法,但调用processInput()似乎不会为我的DateTimeField更新ModelObject。最后,我最大的问题是没有方法可以为分钟创建一个字段。因此,我无法首先覆盖它。 我怀疑我这么复杂,但我哪里错了?

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

我不确定文档为什么会指向AjaxFormComponentUpdatingBehavior

这里的问题是它只会更新每个字段的内容。因此,如果分钟字段更改,它将只发布minuteField输入。因此,每次尝试在进行一分钟/小时更新后转换输入时,都不会找到日期,因此会失败。

请参阅DateTimeField.convertInput

            // Get the converted input values
        Date dateFieldInput = dateField.getConvertedInput();
        Integer hoursInput = hoursField.getConvertedInput();
        Integer minutesInput = minutesField.getConvertedInput();
        AM_PM amOrPmInput = amOrPmChoice.getConvertedInput();

        if (dateFieldInput == null)
        {
            return;
        }

我建议在表单中包装DateTimeField,并在更改事件期间提交整个表单,如:

    final Form<?> form = new Form("form");
    add(form);

    IModel<Date> dateModel = Model.of();
    DateTimeField dateTimeField = new DateTimeField("dateTimeField", dateModel) {

        @Override
        protected DateTextField newDateTextField(String id, PropertyModel dateFieldModel) {
            DateTextField dateField = super.newDateTextField(id, dateFieldModel);
            dateField.add(new AjaxFormSubmitBehavior(form, "change") {
            });
            return dateField;

        }

        @Override
        protected TextField<Integer> newMinutesTextField(String id, IModel<Integer> model, Class<Integer> type) {
            TextField<Integer> textField = super.newMinutesTextField(id, model, type);
            textField.add(new AjaxFormSubmitBehavior(form, "change") {
            });

            return textField;
        }

        @Override
        protected TextField<Integer> newHoursTextField(final String id, IModel<Integer> model, Class<Integer> type) {
            TextField<Integer> textField = super.newHoursTextField(id, model, type);
            textField.add(new AjaxFormSubmitBehavior(form, "change") {
            });
            return textField;
        }
    };
    form.add(dateTimeField);

这实际上会提交所有三个值而不是一个。一切都应该有效。