Trying my hand at creating a custom binding handler in knockout for Flatpickr has hit a snag. Upon attempting to use it, an error is thrown:
Uncaught TypeError: Unable to process binding "datetimepicker: function (){return startDate }"
Message: Flatpickr is not a constructor
at init (knockout.bindings.ts:16)
The custom binding handler in question looks like this:
import ko from 'knockout';
import $ from 'jquery';
import * as Flatpickr from 'flatpickr';
let bindingHandlers: any = ko.bindingHandlers;
bindingHandlers.datetimepicker = {
init: function (element: any, valueAccessor: any, allBindingsAccessor: any) {
var options = $.extend({
dateFormat: 'DD-MM-YYYY',
enableTime: true
}, allBindingsAccessor().datetimepickerOptions),
$el = $(element),
picker = new Flatpickr(element, options),
observable = valueAccessor();
//handle the field changing by registering datepicker's changeDate event
ko.utils.registerEventHandler(element, "change", function () {
observable(picker.parseDate(($<any>$el).val(), 'DD-MM-YYYY'));
});
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
($<any>$el).flatpickr("destroy");
});
observable.subscribe(function (newVal: any) {
($<any>$el).val(picker.formatDate(options.dateFormat, newVal));
});
picker.setDate(ko.unwrap(observable));
}
};
The associated Typescript definition file contains:
// Type definitions for flatpickr 3.0
// Project: https://github.com/chmln/flatpickr
// Definitions by: James Birtles <https://github.com/UnwrittenFun>
// Rowell Heria <https://github.com/rowellx68>
// Michael Wagner <https://github.com/wagich>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
(...)
export = Flatpickr;
View snippet using the custom binding:
<!-- ko with: assignment -->
<form>
<div class="form-group">
<label for="startDate" class="control-label">Start date</label>
<input data-bind="attr: { id: 'startDate' + $parent.selector() }, datetimepicker: startDate, datetimepickerOptions:{ enableTime: false }" type="text" class="form-control" />
</div>
<div class="form-group">
<label for="endDate" class="control-label">End date</label>
<input data-bind="attr: { id: 'endDate' + $parent.selector() }, datetimepicker: startDate, datetimepickerOptions:{ enableTime: false }" type="text" class="form-control" />
</div>
</form>
<!-- /ko -->
Model setup for the page:
class AssignmentModel {
(...)
}
class AssignmentGroupModel {
(...)
}
A puzzling issue arises when indicating that Flatpickr
is not recognized as a constructor. Despite Visual Studio displaying the constructor correctly upon hover.