The solution posted by user3169887 worked great for me until I switched from a template-driven form (uses ngModel) to a reactive form.
Looking further into the original problem, I learned that Angular is listening for the "input" event which these datepicker libraries don't fire. My solution was to tweak the directive to fire the "input" event rather than emit the ngModelChange event. I tested this directive with both a template-driven form and a reactive form and both seemed to work.
import { Directive, ElementRef, Renderer, Input, OnInit } from "@angular/core";
declare var $: any;
@Directive({
selector: "[datepicker]"
})
export class DatePickerDirective implements OnInit {
@Input("datepicker")
private datepickerOptions: any = {};
private $el: any;
constructor(private el: ElementRef, private renderer: Renderer) {
this.$el = $(el.nativeElement);
}
ngOnInit() {
// Initialize the date picker
this.$el.datepicker(this.datepickerOptions)
// Angular is watching for the "input" event which is not fired when choosing
// a date within the datepicker, so watch for the "changeDate" event and manually
// fire the "input" event so that Angular picks up the change
// See: angular/modules/@angular/forms/src/directives/default_value_accessor.ts
.on("changeDate", (event) => {
let inputEvent = new Event("input", { bubbles: true });
this.renderer.invokeElementMethod(this.el.nativeElement, "dispatchEvent", [inputEvent]);
});
};
ngOnDestroy() {
this.$el.datepicker("destroy");
};
};
Note that I'm using a different datepicker library, so I'm listening for the "changeDate" event and your library may fire a different event like "dp.change".