drgullin / icheck

Highly customizable checkboxes and radio buttons (jQuery & Zepto)
http://fronteed.com/iCheck
7.39k stars 1.63k forks source link

Knockout Integration #4

Open devmondo opened 11 years ago

devmondo commented 11 years ago

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.

drgullin commented 11 years ago

I will try to provide a workaround.

devmondo commented 11 years ago

thank u very much

photostu commented 11 years ago

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

r4fx commented 11 years ago

Any news for this issue? Thanks for great plugin.

drgullin commented 11 years ago

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

devmondo commented 11 years ago

@fronteed +1 for other frame works specially Angular

barbarosalp commented 10 years ago

Hello,

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

drgullin commented 10 years ago

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

devmondo commented 10 years ago

:+1: for Angular integration

juarezpaf commented 10 years ago

Ember.js++

chamweer commented 10 years ago

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();
    }
}; 
drgullin commented 10 years ago

Thanks @chamweer.

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

23.01.2014, â 21:48, chamweer notifications@github.com íàïèñàë(à):

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.

chamweer commented 10 years ago

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)

drgullin commented 10 years ago

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 notifications@github.com íàïèñàë(à):

it's iCheck v1.0.1

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

chamweer commented 10 years ago

thanks, will try it out (y)

staticdreams commented 10 years ago

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

drgullin commented 10 years ago

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

staticdreams commented 10 years ago

@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)
    }
});
jonathancounihan commented 9 years ago

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');
        }
    }
};
zyadsherif commented 9 years ago

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

odiego commented 9 years ago

@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

jonathancounihan commented 9 years ago

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.

odiego commented 9 years ago

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" />
balava88 commented 9 years ago

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');
    }
}

};

bogdosarov commented 9 years ago

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/

stechnique commented 9 years ago

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!

MEVJ commented 8 years ago

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

owlyowl commented 8 years ago

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