Knockout Two Way Binding Checkbox List to ObservableArray

In my last article "Two way binding radio button to observable" I suggested an approach for creating a two way binding for a pair of yes/no radio buttons using JQuery's "Custom Handler", this article deals with another binding problem, two way binding of an ObservableArray to a Checkbox List. Again jQuery's "Custom Handler" comes to the rescue.

Assume a custom handler as in the following:

/// ---------------------------- /// This binding is used to bind arrays of integer values to checkboxes
ko.bindingHandlers.checkedIntValues =
{
  init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext)
  {
    var currentValues;    // event handler for the element click event
    var updateHandler = function ()
    {
      var boundItemIndex;
      var currentValues = ko.utils.unwrapObservable(valueAccessor());
      var boundValue = ko.utils.unwrapObservable(allBindingsAccessor().value);      
// get the index of the bound value in the array of current values
      boundItemIndex = ko.utils.arrayIndexOf(currentValues,                                              boundValue);       if ((element.checked) &&           (boundItemIndex < 0))       {         // bound value is not in current values and checkbox is checked so add it         currentValues.push(boundValue);       }       else       {         if ((!element.checked) &&             (boundItemIndex >= 0))         {           // bound value is in current values and checkbox is not checked so remove it           currentValues.splice(boundItemIndex,                                1);         }       }     };    // make sure the data being bound is an array     currentValues = ko.utils.unwrapObservable(valueAccessor());     if (!(currentValues instanceof Array))     {       throw "checkedIntValues binding can only be used with array data";     }    // register click handler for element     ko.utils.registerEventHandler(element,                                   "click",                                   updateHandler);   },   update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext)   {     var value = ko.utils.unwrapObservable(valueAccessor());     var boundValue = ko.utils.unwrapObservable(allBindingsAccessor().value);   
element.checked = ko.utils.arrayIndexOf(value, boundValue) >= 0;   } };

In HTML do following:
<div class="selections" data-bind="foreach: YourObservableArray">
    <input class="contactType" 
type
="checkbox" data-bind="checkedIntValues: $root.YourSelectedValuesObservableArray,value: YourIdProperty" />&nbsp;
<
label data-bind="  text: YourTextProperty"></label><br /> </div>

Where
YourObservableArray: is the the observable array for all available items
YourSelectedValuesObservableArray: is the observable array for all selected values, that you may want to preselect,
keep it blank if you do not want any checkbox in the list to be checked.
YourItemIdProperty: is the Item's property to be selected.
YourItemTextProperty: is the item's property to be displayed.
For example:
YourObservableArrayName  = [{YourItemIdProperty:1,YourItemTextProperty:"ankur"},{YourItemIdProperty:
2,YourItemTextProperty:"malik"},{YourItemIdProperty:3,YourItemTextProperty:"shikhar"}]
YourSelectedValuesObservableArray =[1,2]
Then the checkbox list will have 3 checkboxes with the first two checkboxes checked and the last one unchecked.
Now if you uncheck the first two checkboxes and check the last checkbox then "YourSelectedValuesObservableArray" will be [3].
Hope that would help somebody.
Thanks...
 


Similar Articles