我正在尝试获取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。最后,我最大的问题是没有方法可以为分钟创建一个字段。因此,我无法首先覆盖它。 我怀疑我这么复杂,但我哪里错了?
非常感谢任何帮助。
答案 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);
这实际上会提交所有三个值而不是一个。一切都应该有效。