Zach M.
Zach M.

Reputation: 1194

Allowing checkbox update only on JS confirm using Knockout

I have blocked out in this fiddle http://jsfiddle.net/2vNBB/5/ the scenario I am trying to achieve.

User clicks a check box and is prompted whether or not they want to alter that setting, however in the fiddle you can see that the checkbox remains checked no matter the action taken but the observable reflects the change.

The check box should have the correct value displayed but it does not.

HTML

<div class="checkbox-inline">
    <label>
        <input type="checkbox" data-bind="checked: IsAggregate, click: updateAggregate" />
    </label>
</div>
<br/>
<span>This is the observable value: </span><span data-bind="text: IsAggregate"></span>

JS

 var ViewModel = function () {
    var self = this;
    self.IsAggregate = ko.observable(true);

    self.updateAggregate = function () {
        if (confirm("Are you sure you want to click that?")) {
            self.IsAggregate(self.IsAggregate());      
        } else {
             self.IsAggregate(!self.IsAggregate());  
        }
    };
};

var vm = new ViewModel();
ko.applyBindings(vm);

UPDATE This has the functionality I am looking for however I want to wire this into just the checkbox. http://jsfiddle.net/2vNBB/10/

Upvotes: 1

Views: 578

Answers (5)

Jordan W. Cobb
Jordan W. Cobb

Reputation: 11

You can do this without making any custom binding by using an anonymous function which calls the confirm, then the removal function if the confirm is true.

<input type="button" data-bind="click: function () { var confirmed = 
confirm('Are you sure you want to remove this?');  if(confirmed) 
UpdateCheckbox(this); }">

Upvotes: 0

jaybeeuu
jaybeeuu

Reputation: 1123

I know htis is a bit old, but my pennies worth is tht mark b. nearly had it - return the result of your confirm box from the update:

self.updateAggregate = function () {
    var confirmResult;
    
    if ( confirmResult = confirm("Are you sure you want to click that?")) {
        self.IsAggregate(self.IsAggregate());      
    } else {
        self.IsAggregate(!self.IsAggregate());  
    }
    
    return confirmResult;
};

Fiddle

By default knockout returns false to event hanlders which prevents the default action running. see note 3. also this is explained in this answer here on stackoverflow...

If you return tru then the default is allowed and the action will continue - your box will be checked. If you return false then it is prevented. So all you need to do is return the result of your confirm.

No custom bindings required.

Upvotes: 0

milagvoniduak
milagvoniduak

Reputation: 3254

I had to solve this checkbox problem before, you will need to create a custom binding for yur checkbox. This solution will work as you expect and will not check/uncheck the chebox.

here is the fiddle FIDDLE

ko.bindingHandlers.customChecked = {
     init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
         element.addEventListener('mousedown', function(e) {
            if (confirm('Are you sure you want to click that?'))
            {
               element.checked = !element.checked;
               valueAccessor()(element.checked);          
            }
         });
         element.checked = valueAccessor()();
    }
}

Upvotes: 4

beauXjames
beauXjames

Reputation: 8418

You can also replace the immediate click binding with a custom handler and only change the value of your observable when the option to change has been confirmed. This gives you a little more control over the order in which the bindings are happening. Currently, you actually change the value of your property, then ask to confirm, then either change it back or set it to the same value...

http://jsfiddle.net/2vNBB/11/

ko.bindingHandlers.ConfirmCheck = {
    init: function (element, valueAccessor) {        
         var isAggregateObservable = valueAccessor();
        element.checked = isAggregateObservable();

        element.onclick = function() {
            if (confirm("Are you sure you want to click that?")) {
                isAggregateObservable(element.checked);
            } else {
                 element.checked = !element.checked;   
            }
        }
    }
}

Upvotes: 0

Mark B
Mark B

Reputation: 1186

Return true from your function

var ViewModel = function () {
    var self = this;
    self.IsAggregate = ko.observable(true);

    self.updateAggregate = function () {
        if (confirm("Are you sure you want to click that?")) {
            self.IsAggregate(self.IsAggregate());      
        } else {
             self.IsAggregate(!self.IsAggregate());  
        }
        return true;
    };
};

Here's an updated fiddle: http://jsfiddle.net/Mq8hj/1

Upvotes: 2

Related Questions