Search code examples
javascriptknockout.jsconfirm

Knockout click binding with javascript confirm


I can't figure out how to create a knockout click binding that doesn't execute the valueAccessor unless a javascript confirm dialog returns true.

It's probably look something like this:

<a data-bind="confirmClick: { message: 'Are you sure?', click: someMethod }">Confirmable link</a>

Internally, the confirmClick binding would do something like:

if (confirm(message)) {
   click();
}

I know I could get around having to do this by putting the confirm(...) code in my viewModel, but that doesn't seem like the appropriate place to put that kind of code. I could probably also go as far as to do this kind of confirm dialog with jQueryUI or Bootstrap, but I want something I can just drop into any project.

I've scoured the internets with no luck.. I even looked at the source code for knockout's click event (https://github.com/knockout/knockout/blob/master/src/binding/defaultBindings/event.js), but it doesn't look friendly at all...

Any help at all would be greatly appreciated!


Solution

  • You need to create your custom confirmClick binding handler which takes your message and your click handler and wrap around the confirmation logic:

    ko.bindingHandlers.confirmClick = {
        init: function(element, valueAccessor, allBindings, viewModel) {
            var value = valueAccessor();
            var message = ko.unwrap(value.message);
            var click = value.click;
            ko.applyBindingsToNode(element, { click: function () {
                if (confirm(message))
                    return click.apply(this, Array.prototype.slice.apply(arguments));
            }}, viewModel);
        }
    }
    

    And you can you it like you have described:

    <a data-bind="confirmClick: { message: 'Are you sure?', click: someMethod }">
        Confirmable link</a>
    

    Demo JSFiddle.

    Note: You only need the click.apply magic if you want to preserve and pass over the original click event handler args to your own click event handler.