icheck icon indicating copy to clipboard operation
icheck copied to clipboard

Knockout Integration

Open devmondo opened this issue 11 years ago • 28 comments

hi, beautiful beautiful plugin, thank you very much

is there a way to integrate with knockout, because knockout reacts only to normal input changes

thanks in advanced.

devmondo avatar Mar 26 '13 16:03 devmondo

I will try to provide a workaround.

drgullin avatar Mar 27 '13 22:03 drgullin

thank u very much

devmondo avatar Mar 28 '13 08:03 devmondo

Just curious if you have a workaround for this issue yet? Thanks for your wonderful module!

photostu avatar Apr 11 '13 15:04 photostu

Any news for this issue? Thanks for great plugin.

r4fx avatar Apr 21 '13 13:04 r4fx

This's not just about Knockout. iCheck should be integrated into other frameworks too, like Angular, Backbone and Ember.

drgullin avatar Jun 05 '13 22:06 drgullin

@fronteed +1 for other frame works specially Angular

devmondo avatar Jun 05 '13 23:06 devmondo

Hello,

Thank you for the great plug-in. Is there any workaround about the knockout issue ?

barbarosalp avatar Jul 23 '13 11:07 barbarosalp

I'm rewriting plugin nearly from scratch for a better performance, solution will come after I finish this task.

drgullin avatar Jul 23 '13 16:07 drgullin

:+1: for Angular integration

devmondo avatar Jul 23 '13 23:07 devmondo

Ember.js++

juarezpaf avatar Aug 03 '13 03:08 juarezpaf

for anyone who is struggling with integration with knockout, here is my solution and it worked for me. You may define a custom binding like below and handle the model inside oninit method,

ko.bindingHandlers.CustomBinding = { init: function (element, valueAccessor) {

        $(element).iCheck({ radioClass: 'iradio_square-blue' });

        $(element).on('ifChanged', function () {
            var observable = valueAccessor();
            observable.checked(this.checked);
        });
    },
    update: function (element, valueAccessor) {
        var observable = valueAccessor();
    }
}; 

chamweer avatar Jan 23 '14 17:01 chamweer

Thanks @chamweer.

Which version do you use in this code (1.x or 2.x)?

23.01.2014, â 21:48, chamweer [email protected] íàïèñàë(à):

for anyone who is struggling with integration with iCheck, here is my solution and it worked for me. You may define a custom binding like below and handle the model oninit,

ko.bindingHandlers.CustomBinding = { init: function (element, valueAccessor) {

    $(element).iCheck({ radioClass: 'iradio_square-blue' });

    $(element).on('ifChanged', function () {
        var observable = valueAccessor();
        observable.checked(this.checked);
    });
},
update: function (element, valueAccessor) {
    var observable = valueAccessor();
}

}; — Reply to this email directly or view it on GitHub.

drgullin avatar Jan 24 '14 01:01 drgullin

it's iCheck v1.0.1. Please note that i think there is no issue with iCheck plugin but what you need to know is how you integrate the same with knockout js. Hope the code i have submitted will help someone (y)

chamweer avatar Jan 24 '14 03:01 chamweer

Try to use 2.x version https://github.com/fronteed/iCheck/tree/2.x-beta It's already tested on desktop and mobile browsers.

24.01.2014, â 7:22, chamweer [email protected] íàïèñàë(à):

it's iCheck v1.0.1

— Reply to this email directly or view it on GitHub.

drgullin avatar Jan 24 '14 09:01 drgullin

thanks, will try it out (y)

chamweer avatar Jan 25 '14 05:01 chamweer

Version 2.0 (RC1 atm) is working great with Ember.js. Thank you!

staticdreams avatar Mar 30 '14 18:03 staticdreams

@staticdreams do you use any extra code for ember.js intergration?

drgullin avatar Mar 30 '14 18:03 drgullin

@fronteed , strangely none :) Just a basic Ember.View with a few methods.

Ember.RadioButton = Ember.View.extend({
    checked: false,
    templateName: 'radioButton',
    didInsertElement: function() {
        this.$().icheck({
            radioClass: 'iradio_square-blue'
        });
    },
    change: function() {
        Ember.run.once(this, this._updateElementValue);
    },
    _updateElementValue: function() {
        var input = this.$('input:radio');
        console.log(input.attr('value')) // <-- this outputs the actual input value (radio button)
    }
});

staticdreams avatar Mar 30 '14 18:03 staticdreams

I know this is an old issue, but using knockout 3.1.0 and icheck v1.0.2:

ko.bindingHandlers.iCheckBox = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var $el = $(element);
        var observable = valueAccessor();

        $el.iCheck({
            checkboxClass: 'icheckbox_square-red',
            inheritClass: true
        });

        var enabled = allBindingsAccessor().enable();
        if (enabled) {
            $el.iCheck('enable');
        }
        else {
            $el.iCheck('disable');
        }

        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $el.iCheck('destroy');
        });

        allBindingsAccessor().enable.subscribeChanged(function (newValue, oldValue) {
            if (newValue != oldValue) {
                $el.iCheck('update');
            }
        });

        // ifChecked handles tabs and clicks
        $el.on('ifChecked', function (e) {
            observable(true);
        });
        $el.on('ifUnchecked', function (e) {
            observable(false);
        });

        ko.bindingHandlers.iCheckBox.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        // This update handles both the reverting of values from cancelling edits, and the initial value setting.
        var $el = $(element);
        var value = ko.unwrap(valueAccessor());
        if (value == true) {
            $el.iCheck('check');
        } else if (value == false || value == null || value == "") { // Handle clearing the value on reverts.
            $el.iCheck('uncheck');
        }
    }
};

jonathancounihan avatar Aug 05 '14 12:08 jonathancounihan

@staticdreams can you share the template for the RadioButton view?

zyadsherif avatar Aug 14 '14 11:08 zyadsherif

@jccounihan can you show me the html example of this iCheckBox? I was trying to make it work, but I could not. It says "undefined is not a function". Probably because I am not passing the 'allBindingsAccessor' parameter. BTW I am using Icheck 1.0.2 and knockout 3.2.0

odiego avatar Sep 11 '14 18:09 odiego

Hi @odiego, sorry my bad! In my original snippet there was no check to see if you were using the enable binding as well. I have fixed it in the sample below.

      // Using ko 3.2.0 and iCheck 1.0.2
      ko.bindingHandlers.iCheckBox = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
          var $el = $(element);
          var observable = valueAccessor();
          $el.iCheck({
            checkboxClass: 'icheckbox_flat-blue',
            inheritClass: true
          });

          var enable = allBindingsAccessor().enable;
          if (enable != undefined) {
            if (enable()) {
              $el.iCheck('enable');
            }
            else {
              $el.iCheck('disable');
            }
            var enabledSubs = enable.subscribeChanged(function (newValue, oldValue) {
              if (newValue != oldValue) {
                $el.iCheck('update');
              }
            });
          }

          ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            if (enabledSubs != null) {
              enabledSubs.dispose();
              enabledSubs = null;
            }
            $el.iCheck('destroy');
          });

          // ifChecked handles tabs and clicks
          $el.on('ifChecked', function (e) {
            observable(true);
          });
          $el.on('ifUnchecked', function (e) {
            observable(false);
          });

          ko.bindingHandlers.iCheckBox.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
        },
        update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
          // This update handles both the reverting of values from cancelling edits, and the initial value setting.
          var $el = $(element);
          var value = ko.unwrap(valueAccessor());
          if (value == true) {
            $el.iCheck('check');
          } else if (value == false || value == null || value == "") { // Handle clearing the value on reverts.
            $el.iCheck('uncheck');
          }
        }
      };

The sample also includes a reference to my subscribeChanged function, which was not included in the original post.

ko.subscribable.fn.subscribeChanged = function (callback) {
    var that = this;

    if (!that.previousValueSubscription) {
        that.previousValueSubscription = this.subscribe(function (_oldValue) {
            that.oldValue = _oldValue;
        }, that, 'beforeChange');
    }
    var subscription = that.subscribe(function (latestValue) {
        callback(latestValue, that.oldValue);
    }, that);

    var protoDispose = subscription.dispose;
    subscription.dispose = function () {
        if (protoDispose) {
            protoDispose.call(this);
        }
        if (that.previousValueSubscription) {
            that.previousValueSubscription.dispose();
        }
        delete that.oldValue;
    }

    return subscription;
};

The Html for the this is pretty simple

<div>
    <label>
      <input type="checkbox" data-bind="iCheckBox: SmokerCheckBox" />
      <span class="icheck-label">&nbsp;Is Smoker</span>
    </label>
  </div>
  <div data-bind="text: ko.toJSON(vm)">
  </div>

I have created a fiddle with all the code to demo.

jonathancounihan avatar Sep 12 '14 08:09 jonathancounihan

Folks, I did two different versions for 'radios' and 'checkboxes'. Both are very simple to do and work flawlessly.

For radio: (it will put the value from radio into the observable)

JS:

radioCheckedValue: ko.observable(),

  ko.bindingHandlers.iCheckRadio = {
        init: function (element, valueAccessor) {
            $(element).iCheck({
                radioClass: 'iradio_flat-orange',
                increaseArea: '20%',
                cursor: true
            });
            $(element).on('ifChanged', function () {
                var observable = valueAccessor();
                observable($(element).val());
            });
        },
        update: function (element, valueAccessor) {
            var observable = valueAccessor();
        }
    };

HTML Code:

<input type="radio" name="iCheckRadio" data-bind="value: myValue, iCheckRadio: radioCheckedValue" /><span class="icheck-label" data-bind="text: myValue" />

For checkboxes (it will set true or false into the observable) JS:

 ko.bindingHandlers.iCheck = {
            init: function (element, valueAccessor) {
                $(element).iCheck({
                    checkboxClass: 'icheckbox_flat-orange',
                    increaseArea: '20%',
                    cursor: true
                });

                $(element).on('ifChanged', function () {
                    var observable = valueAccessor();
                    observable($(element)[0].checked);
                });
            },
            update: function (element, valueAccessor) {
                var observable = valueAccessor();
            }
        };

HTML:

<input type="checkbox" name="iCheck" data-bind="value: myValue, iCheck: checkedValue" /><span class="icheck-label" data-bind="text: myValue" />

odiego avatar Sep 24 '14 14:09 odiego

ko.bindingHandlers.iCheck = { init: function (element, valueAccessor) { $(element).iCheck({ checkboxClass: 'icheckbox_minimal-grey', increaseArea: '10%' });

    $(element).on('ifChanged', function () {
        var observable = valueAccessor();
        observable($(element)[0].checked);
    });
},
update: function (element, valueAccessor) {
    var value = ko.unwrap(valueAccessor());   
    if (value) {
        $(element).iCheck('check');            
    } else {
        $(element).iCheck('uncheck');
    }
}

};

balava88 avatar Sep 26 '14 04:09 balava88

i have a problem with update model, but i fix it this way


didInsertElement: function(){
        this.$().find('input').iCheck({
            checkboxClass: 'icheckbox_flat-red'
        });
        this.$().find('input').on('ifToggled', function(){
            $(this).trigger('change');
        });
    }

http://jsfiddle.net/bogdosarov/sctu1ds1/8/

bogdosarov avatar Jan 23 '15 07:01 bogdosarov

FWIW I've just tried the icheck 2.0RC1 js file instead and updated the js call to $().icheck() instead of $().iCheck(), and Knockout's checked binding just started working out of the box. Thanks!

stechnique avatar Feb 01 '15 22:02 stechnique

I am stuck ..trying to implement icheck with backbone ..but unable to listen to events. Is there a way to identify the chceked and unchecked event in backbone

MEVJ avatar Jan 15 '16 03:01 MEVJ

I'm getting TypeError: observable is not a function when trying to use ichecks and knockout the observable doesn't seem to match up right. In my case it's a dependent observable that is a bool called like so: iCheckBox: Thing().IsSomething

owlyowl avatar Apr 27 '16 07:04 owlyowl