user3174746
user3174746

Reputation:

Knockout observables: Manually apply extenders

I have written an extender that formats a date when a user blurs a date input field (in other words, valueUpdate is not 'afterkeydown').

The trouble is, though, that I need the value to update after each key down for certain other reasons, but I don't want the formatting applied until the user blurs.

Is there a way to set extender(s) to "manual", so to speak, and then manually invoke the extender(s) with something like this:

someObservable.applyExtenders(); //applies all extenders

or

someObservable.applyExtenders(['formatDate']);  //applies a list of extenders

Upvotes: 1

Views: 208

Answers (1)

David East
David East

Reputation: 32624

You don't have to do something so complex as manually applying extenders.

An easier solution would be to create a custom binding that validates the date as the user types it in, and then formats the date when the change event is fired off.

Fiddle.

(function(ko) {

    ko.bindingHandlers.dateValid = {
        // set up bindings on the init function
        // you can use afterkeydown to get the value as the user types it in
        // then you can use the change event to do the formatting
        init: function(elem, valueAccessor, allBindings, vm, context) {
            function formatDate() {
                alert('Im getting formatted!');   
            }
            // add the other bindings to the node
            ko.applyBindingsToNode(elem, { 
                value: valueAccessor(), // the observable
                valueUpdate: 'afterkeydown', 
                event: { change: formatDate } // this will format on change not keydown
            });
        },
        update: function(elem, valueAccessor, allBindings, vm, context) {
            var val = ko.unwrap(valueAccessor());
            // do validation or whatever needs to be done as the value updates here
        }
    };    

    function ViewModel() {
        this.date = ko.observable('11/22/63');
    }

    ko.applyBindings(new ViewModel());

}(ko));

Upvotes: 1

Related Questions