Knockout.js Checkbox checked and click event

16,841

Solution 1

You need to use a computed to monitor the length of the observable array. This way when the length reaches zero you can react to it automatically.

    self.surnames = ko.computed(function() {
        var checked = true;
        if (self.PreviousSurnames().length === 0) {
            self.PreviousSurnames.push('');
            checked = false;
        }            
        return checked;
    });

Now you will have the blank text box when all of the names are cleared. If you update your binding on the checkbox it will function properly as well.

<input type="checkbox" data-bind="checked: surnames, click: PreviousSurnames_Click" />Previous Surname(s)?

FIDDLE

Solution 2

If you are using together the click and the checked then you need to return true from your click handler to allow the browser default click action which is in this case checking the checkbox:

self.PreviousSurnames_Click = function () {
    if (self.PreviousSurnames().length === 0) {
        self.PreviousSurnames.push('');
    }
    else {
        self.PreviousSurnames.removeAll();
    }
    return true;
}

Demo JSFiddle.

Share:
16,841
DavidReid
Author by

DavidReid

.Net Developer.

Updated on June 27, 2022

Comments

  • DavidReid
    DavidReid almost 2 years

    We're trying to implement a checkbox and list with the following functionality:

    • Clicking the checkbox will either clear the array if there are items in there, or add a new item if not.
    • Remove an item from the array when clicking the Remove button, once the last item is removed the checkbox automatically unchecks itself.

    The problem I am having is that if you click to remove each array item, then click the checkbox to add a blank entry, I'm expecting the checkbox to be checked again (as per the checked observable), however it is not?

    I have the following code:

    http://jsfiddle.net/UBsW5/3/

        <div>
            <input type="checkbox" data-bind="checked: PreviousSurnames().length > 0, click: $root.PreviousSurnames_Click" />Previous Surname(s)?
        </div>
        <div data-bind="foreach: PreviousSurnames">
            <div>
                <input type="text" data-bind="value: $data">
                <span data-bind="click: $root.removePreviousSurname">Remove</span>
            </div> 
        </div>
    
    
    var myViewModelExample = function () {
        var self = this;
    
        self.PreviousSurnames = ko.observableArray(['SURNAME1', 'SURNAME2', 'SURNAME3']);
    
        self.removePreviousSurname = function (surname) {
            self.PreviousSurnames.remove(surname);
        };
    
        self.PreviousSurnames_Click = function () {
            if (self.PreviousSurnames().length === 0) {
                self.PreviousSurnames.push('');
            }
            else {
                self.PreviousSurnames.removeAll();
            }
            alet(2)
        }
    
    }
    
    ko.applyBindings(new myViewModelExample());
    
  • nemesv
    nemesv over 10 years
    What is the point of the computed? In your sample the code is duplicated in the computed and the PreviousSurnames_Click and you also needed to add the return true; in your latest edit to make the checkbox "work"?
  • David East
    David East over 10 years
    The point of the computed is to react to when there are no items left in the array automatically. The code is duplicated because it's a fiddle. The refactoring of this example is an easy process. I updated it to remove the duplicate code, however. In your example the textbox doesn't appear when all of the items are cleared.