Knockout - Cancel a Change Event?

I have a checkbox bound to an observable on a view model. I have a requirement to essentially pop up an "Are you sure?" confirmation prompt if the user changes it from true to false. I'm having a horrible time figuring out the best place to make the change "cancelable" . . .

1) jQuery handler for click event 2) Viewmodel internal subscribe "beforeChange" 3) Viewmodel internal subscribe (normal)

In any case, I'd vastly prefer to have the chance to cancel the change outright than react to the change, potentially reverting it back to its previous value if need be.

Does Knockout's subscribe event give you the chance to cancel a change? Any insight would be appreciated. Thanks!

Answers


Here is a simple option using jQuery's stopImmediatePropagation:

http://jsfiddle.net/rniemeyer/cBvXM/

<input type="checkbox" data-bind="click: confirmCheck, checked: myvalue" />

js:

var viewModel = {
    myvalue: ko.observable(false),
    confirmCheck: function(data, event) {
        if (!confirm("Are you sure?")) {
            event.stopImmediatePropagation();            
            return false;
        }
        return true;
    }
};

Because of the problems commented in @RP Niemeyer answer, I've just implemented this extender:

ko.extenders.confirmable = function(target, options) {
    var message = options.message;
    var unless = options.unless || function() { return false; }
    //create a writeable computed observable to intercept writes to our observable
    var result = ko.computed({
        read: target,  //always return the original observables value
        write: function(newValue) {
            var current = target();

            //ask for confirmation unless you don't have
            if (unless() || confirm(message)) {
                target(newValue);
            } else {
              target.notifySubscribers(current);
            }
        }
    }).extend({ notify: 'always' });

    //return the new computed observable
    return result;
};

You can then apply that to your model like this:

var viewModel = {
    myvalue: ko.observable(false).extend({confirmable: "Are you sure?"});
}

And, if there was a case in which not to ask for confirmation (in this silly example, we'll skip confirmation during March), you can do:

var viewModel = {
    myvalue: ko.observable(false).extend({confirmable: { message: "Are you sure?", unless: function() { return new Date().getMonth() == 2 }} });
}

Need Your Help

Spring list beans by type

java spring autowired

Is there a way in Spring that I can auto populate a list with all of beans of a type AND any of its subtypes? I have a setter method that looks like:

Add select value in form

php symfony doctrine-orm symfony-2.3 formbuilder

I have this Symfony form, it displays the values of the entity 'Manifestation' that has a many to many relationship.