nb.define('checkbox', {
    events: {
        'click': '_onclick'
    },

    /**
     * Init a checkbox
     * @fires 'nb-inited'
     */

    oninit: function() {
        this.$control = this.$node.find('input[type]');
        this._isChecked = this.$control.prop('checked');

        if (!this._isChecked) {
            this.$control.prop('indeterminate', true);
        }

        this.trigger('nb-inited', this);
    },

    /**
     * Override base getType()
     * @returns {String} — type of control
     */

    getType: function() {
        return this.$control.attr('type');
    },

    /**
     * Return check state of the checkbox or radio
     * @returns {Boolean}
     */
    isChecked: function() {
        return this._isChecked;
    },

    /**
     * Checking checkbox or radio
     * @fires 'nb-checked', 'nb-changed'
     * @returns {Object} nb.block
     */
    check: function() {
        if (!this.isEnabled()) {
            return this;
        }

        var isChecked = this.isChecked();

        this.$control.prop({
            'indeterminate': false,
            'checked': true
        });

        this._isChecked = true;
        this.trigger('nb-checked', this);

        if (!isChecked) {
            this.trigger('nb-changed', this);
        }

        return this;
    },

    /**
     * Unchecking checkbox or radio
     * @fires 'nb-unchecked', 'nb-changed'
     * @returns {Object} nb.block
     */
    uncheck: function() {
        if (!this.isEnabled()) {
            return this;
        }

        var isChecked = this.isChecked();

        this.$control.prop({
            'indeterminate': false,
            'checked': false
        });

        this._isChecked = false;
        this.trigger('nb-unchecked', this);

        if (isChecked) {
            this.trigger('nb-changed', this);
        }

        return this;
    },

    /**
     * Toggle to the opposite state checkbox or radio
     * @fires 'change'
     * @return {Object} nb.block
     */
    toggle: function() {
        if (!this.isEnabled()) {
            return this;
        }

        this.trigger('nb-change', this);

        if (this.isChecked()) {
            this.uncheck();
        } else {
            this.check();
        }
        return this;
    },

    _onclick: function(e) {
        // <label><input/></label> may fires event twice
        // @see http://www.w3.org/TR/html5/forms.html#labeled-control
        if (e.target.nodeName === 'INPUT') {
            // fires block events
            if (this.$control.prop('checked')) {
                this.check();
            } else {
                this.uncheck();
            }
        }
    },

    /**
     * Return indeterminate state of the checkbox or radio
     * @returns {Boolean}
     */
    isIndeterminate: function() {
        return this.$control.prop('indeterminate');
    },

    /**
     * Set indeterminate state of the checkbox or radio
     * @fires 'nb-indeterminated'
     * @returns {Object} nb.block
     */
    setIndeterminate: function() {
        if (this.isEnabled()) {
            this.$control.prop('indeterminate', true);
            this.trigger('nb-indeterminated', this);
        }
        return this;
    },

    /**
     * Set determinate state of the checkbox or radio
     * @fires 'nb-determinated'
     * @returns {Object} nb.block
     */
    setDeterminate: function() {
        if (this.isEnabled()) {
            this.$control.prop('indeterminate', false);
            this.trigger('nb-determinated', this);
        }
        return this;
    },

    /**
     * Return enable state of the checkbox or radio
     * @returns {Boolean}
     */
    isEnabled: function() {
        return !this.$control.prop('disabled');
    },

    /**
     * Enable the checkbox or radio
     * @fires 'nb-enabled'
     * @returns {Object} nb.block
     */
    enable: function() {
        if (!this.isEnabled()) {
            this.$node.removeClass('is-disabled');
            this.$control.removeAttr('disabled');
            this.trigger('nb-enabled', this);
        }
        return this;
    },

    /**
     * Disable the checkbox or radio
     * @fires 'nb-disabled'
     * @returns {Object} nb.block
     */
    disable: function() {
        if (this.isEnabled()) {
            this.blur();
            this.$node.addClass('is-disabled');
            this.$control.attr('disabled', 'disabled');
            this.trigger('nb-disabled', this);
        }
        return this;
    },

    /**
     * Focus the checkbox or radio
     * @fires 'nb-focused'
     * @returns {Object} nb.block
     */
    focus: function() {
        this.$control.focus();
        this.trigger('nb-focused', this);
        return this;
    },

    /**
     * Blur the checkbox or radio
     * @fires 'nb-blured'
     * @returns {Object} nb.block
     */
    blur: function() {
        this.$control.blur();
        this.trigger('nb-blured', this);
        return this;
    },

    /**
     * Sets label of the checkbox or radio
     * @param {String|Number} label
     * @fires 'nb-label-set'
     * @returns {Object} nb.block
     */
    setLabel: function(label) {
        this.$node.find('.nb-checkbox__label').html(label);
        this.trigger('nb-label-set', this);
        return this;
    },

    /**
     * Gets label of the checkbox or radio
     * @returns {String | Number}
     */
    getLabel: function() {
        return this.$node.find('.nb-checkbox__label').html();
    },

    /**
     * Get name of the checkbox or radio
     * @returns {String|Object} name
     */
    getName: function() {
        return this.$control.prop('name');
    },

    /**
     * Set checkbox value
     * @param {String|Number} value
     * @fires 'nb-name-set'
     * @returns {Object} nb.block
     */
    setName: function(value) {
        this.$control.attr('name', value);
        this.trigger('nb-name-set', this);
        return this;
    },

    /**
     * Returns checkbox value
     * @returns {String}
     */
    getValue: function() {
        return this.$control.attr('value') || '';
    },

    /**
     * Set checkbox value
     * @param {String|Number} value
     * @fires 'nb-value-set'
     * @returns {Object} nb.block
     */
    setValue: function(value) {
        this.$control.attr('value', value);
        this.trigger('nb-value-set', this);
        return this;
    },

    /**
     * Destroy checkbox
     * @fires 'nb-destroyed'
     */
    destroy: function() {
        this.trigger('nb-destroyed', this);
        this.nbdestroy();
    }

}, 'base');

@@ -45,25 +45,193 @@
   'c
-lick': '_onclick'
+hange input': 'onchange'%0A    %7D,%0A%0A    onchange: function() %7B%0A        if (this.$control.prop('checked')) %7B%0A            this.check();%0A        %7D else %7B%0A            this.uncheck();%0A        %7D
 %0A   
@@ -2441,406 +2441,8 @@
 %7D,%0A%0A
-    _onclick: function(e) %7B%0A        // %3Clabel%3E%3Cinput/%3E%3C/label%3E may fires event twice%0A        // @see http://www.w3.org/TR/html5/forms.html#labeled-control%0A        if (e.target.nodeName === 'INPUT') %7B%0A            // fires block events%0A            if (this.$control.prop('checked')) %7B%0A                this.check();%0A            %7D else %7B%0A                this.uncheck();%0A            %7D%0A        %7D%0A    %7D,%0A%0A
     

fix double click bubbling for checobox