zum Inhalt

Der lise Blog:
Einsichten, Ansichten, Aussichten

Validierung eines Kendo DateTimePicker mittels AngularJS

15. Januar 2018 von Avatar of NicoNico

Das Zusammenspiel von Kendo und AngularJS ist bei weitem nicht harmonisch. In manchen Fällen zeigen beide, dass sie nur über Umwege miteinander kommunizieren können. Im folgenden Beitrag lesen Sie einen kurzen Erfahrungsbericht, was im ungünstigsten Fall mit einer herkömmlichen Datumseingabe passieren kann.

Ausgangslage

Ausgangslage des ganzen Validierungs-Wirrwarrs ist ein MVC-Projekt, auf welchem Kendo und AngularJS verwendet wird. Okay, fairerweise sollte man dazu sagen, dass Bootstrap auch eine Mitschuld trägt. Ein Framework, welches es nun schon sechs Jahre auf dem Markt gibt und keine Standard-Komponente zur Datumseingabe hat, soll sich nicht wundern, wenn auf andere Methoden zurückgegriffen wird, um ein Datum einzugeben.

Problemstellung

  • Ein ngModel ließ sich nicht auf das Input-Field des DateTimePicker mappen.
  • Die Validierung war immer um einen Durchlauf zurück. Nach dem Auswählen des ersten Tages, wurde null angezeigt. Nach Auswählen des zweiten Tages wurde Tag 1 angezeigt.

Herausforderungen

Der Kendo DateTimePicker erzeugt einerseits ein dateObject und anderseits einen dateString. Der DateString ist jener, welcher dem Benutzer nach der Auswahl eines Datums angezeigt wird und kann mittels dem Attribut k-format angepasst werden. Ein schöner Zeit String, wie zum Beispiel "15.01.2018". Legen wir unser ngModel von Angular nun auf das Input-Field, erhalten wir ausschließlich den dateString in das Model. Da unser Webservice jedoch ein DateTime-Objekt erwartet, ist dieser String für uns wertlos.

Lösungsansatz

Wir mussten uns nun überlegen, wie wir es schaffen, den Benutzer den schönen dateString sehen zu lassen und den Webservice das „Oh, so komplexe“ DateObject übergeben bekommt. Nach unzähligen Versuchen dies ganz komplex mittels des k-ngModels und des ng-models in ein Feld zu mappen, haben wir eine andere, recht simple, Lösungsvariante gefunden: zwei Felder. Eines, womit der Nutzer das Datum eingeben kann, welches den dateString besitzt und ein weiteres, welches das DateObject besitzt.

Das JavaScript wird demnach angepasst, sodass der eingegebene Wert in das ngModel gemappt wird - und fertig. Dank Angular müssen wir uns auch gar nicht weiter darum kümmern, dass das ngModel in unser zweites Feld gelangt. Zu guter Letzt wird unser zweites Feld noch auf "hidden" gesetzt, damit der Nutzer dies nicht störenderweise in seinen Eingaben sieht.

Nachdem der Nutzer seine Eingaben tätigen konnte, kommen wir nun zur Validierung. Diese ist jedoch gar nicht so komplex, wie man vielleicht vermutet. Wir wussten mittlerweile, dass Kendo sehr merkwürdig mit seinen Feldern umgeht und haben die Validierung komplett mit unserem zweiten, mittlerweile Hidden-Input-Feld realisiert. Da wir davon ausgehen können, dass der Nutzer nur über den Kendo DateTimePicker den Wert des Feldes verändern kann und Kendo automatisch valide Werte erzeugt, reicht eine Validierung, ob dieses Feld befüllt ist. Dazu reicht es, das Required-Flag in unserem Feld zu setzen und Angular übernimmt bei der Validierung den Rest.

Als wir im JavaScript die Validierung des Formulares getriggert haben, ist uns aufgefallen, dass das Setzen des ngModels immer einen Wert zurückhängt. Wenn der Nutzer zwei Werte eingegeben hat, stand der Wert der ersten Eingabe in dem Feld. Dies wurde jedoch mit einem Time-out um das Mapping sehr schnell behoben. So konnte Kendo den eingegeben Wert zuerst in die internen DateObject- und DateString-Variablen schreiben.

Der fertige Code zu diesem kleinen Beispiel sieht, wie folgt aus:

JavaScript

 

var licenseDate = $('#LicenseDate').data('kendoDatePicker');


licenseDate.bind('change', function (val) {

     $timeout(function () {

          $scope.data.model.LicenseDate = licenseDate.value();

          $scope.$broadcast('show-errors-check-validity');

     })

})

 

HTML

 

<div class="form-group" ng-class="{'has-error': data.model.LicenseDate === null}">

    <label for="LicenseDate" class="…">Zulassungsdatum</label>

    <div class="col-md-8">

          <input id="LicenseDate" kendo-date-picker required />

          <input type="hidden" name="LicenseDate" ng-model="data.model.LicenseDate" required />

     </div>

</div>

 

Fazit

Rückblickend betrachtet, lässt sich zusammenfassen, dass es trotz dieser Komplikationen keine schlechte Entscheidung war mit Kendo und AngularJS zu arbeiten. Im Großen und Ganzen arbeiten die beiden auch ganz gut zusammen. Dieses Beispiel des DateTimePicker veranschaulicht jedoch, dass noch Potenzial vorhanden ist, die Interaktionen der Komponenten stärker miteinander zu verknüpfen. Einen Umweg über einen Hidden Input ist, salopp gesagt, lästig und macht die Idee von einer Kopplung der Komponenten zu den Models unsinnig, wenn diese schlussendlich doch manuell gesetzt werden müssen.

Rufen Sie uns an: 0221 222 812 - 12
Kommen Sie vorbei!
lise GmbH
Butzweilerhof-Allee 2
50829 Köln