2016-09-12 10 views
0

Ich versuche, den vom Benutzer ausgewählten Wert eines DateTimeField zu erhalten, aber bin fehlgeschlagen. Im Moment habe ich den folgenden Code, die sich perfekt für meine DropDownChoice Objekte funktioniert:Holen Sie sich Benutzereingabe in Wicket DateTimeField

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; 
    } 
} 

Das Problem ist, dass das Modell nicht aus irgendeinem Grund ein Objekt hat, so getObject() gibt den Wert null. Was mache ich falsch? Warum funktioniert das für DropDownChoicePanel, aber nicht für DateTimeField?

Vielen Dank!

Update: ich nun dieses Chaos haben:

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; 
     } 
    }; 

Im Grunde habe ich herausgefunden, dass die Datetimefield besteht aus drei Textfeldern, eine für den Tag, Stunde und Minuten. Ich muss den Feldern das ajax-Verhalten einzeln hinzufügen, indem ich die Methoden überschreibe, die sie erstellen, und dann processInput() aufrufen, damit das ModelObject für das DateTimeField aktualisiert wird. Dies funktioniert für den Datumsteil. Für die Stunden kann ich die Methode überschreiben, die das Feld erstellt, aber das Aufrufen von ProcessInput() scheint das ModelObject für mein DateTimeField nicht zu aktualisieren. Schließlich ist mein größtes Problem, dass es keine Methode gibt, die ein Feld für die Minuten erstellt. Daher kann ich es nicht von Anfang an überschreiben. Ich vermute, ich mache diesen Weg zu kompliziert, aber wo liege ich falsch?

Jede Hilfe würde sehr geschätzt werden.

Antwort

0

Ich bin nicht sicher, warum die Dokumentation Sie auf eine AjaxFormComponentUpdatingBehavior verweisen würde.

Das Problem hier ist, dass es nur den Inhalt jedes Feldes aktualisiert, wenn sich das ändert. Wenn sich das Minutenfeld ändert, wird nur die minuteField-Eingabe gesendet. Daher wird jedes Mal, wenn Sie versuchen, die Eingabe nach einer Minute/Stunde Update zu konvertieren, ein Datum nicht gefunden und daher fehlschlagen.

See 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; 
     } 

Ich würde empfehlen, die Datetimefield in einem Formular Einwickeln und einfach die ganze Form während des Änderungsereignis einreichen, wie:

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); 

Dies einreichen tatsächlich alle drei Werte statt nur einer. Und alles sollte funktionieren.

+0

Hallo Thorsten, danke, dass du dir die Zeit genommen hast, meine Frage zu beantworten. Ich habe aber noch 2 Fragen. Am wichtigsten: Wie bereits erwähnt, existiert die Methode newMinutesTextField() nicht und kann daher nicht überschrieben werden. Zweitens (aber nicht so wichtig): Diese Lösung scheint immer noch alle Werte separat zu übermitteln. Jedes Mal nach dem Aktualisieren eines der Felder (Datum, Stunden oder Minuten) wird das Senden des Formulars ausgelöst. Wenn ich also anfange, ein Datum einzugeben und die Stunden einzugeben, wird das Datum bereits übermittelt. Dies ist jedoch etwas, das ich programmieren kann, so dass es kein großes Problem ist. –

+0

Entschuldigung, ich habe gerade herausgefunden, dass ich den Teil übersehen habe, wo Sie nach Nullwerten suchen. Das größte Problem bleibt jedoch bestehen. Außerdem bin ich mir nicht sicher, ob ich alles zu einem Formular hinzufügen könnte, da ich auch nach NULL-Werten suchen könnte, selbst wenn das DateTimeField nicht Teil eines Formulars war. –

+0

Der Hauptgrund, warum ich das Formular hinzugefügt habe, war, dass ich nur diese 3 Werte (Datum, Stunden, Minuten) einreicht - Sie haben vielleicht ein größeres Formular und wollen nicht, dass alles eingereicht wird (oder Sie wollen das). Sie werden sowieso ein Formular um die FormComponent benötigen. Welche Wicket Version benutzt du? Ich habe den Code mit dem letzten Wicket 7 getestet.x Version und ich hatte die newMinutesTextField() -Methode –