/* * Fuel UX Checkbox * https://github.com/ExactTarget/fuelux * * Copyright (c) 2014 ExactTarget * Licensed under the BSD New license. */ // -- BEGIN UMD WRAPPER PREFACE -- // For more information on UMD visit: // https://github.com/umdjs/umd/blob/master/jqueryPlugin.js (function (factory) { if (typeof define === 'function' && define.amd) { // if AMD loader is available, register as an anonymous module. define(['jquery'], factory); } else { // OR use browser globals if AMD is not present factory(jQuery); } }(function ($) { // -- END UMD WRAPPER PREFACE -- // -- BEGIN MODULE CODE HERE -- var old = $.fn.checkbox; // CHECKBOX CONSTRUCTOR AND PROTOTYPE var Checkbox = function (element, options) { this.options = $.extend({}, $.fn.checkbox.defaults, options); // cache elements this.$element = $(element).is('input[type="checkbox"]') ? $(element) : $(element).find('input[type="checkbox"]:first'); this.$label = this.$element.parent(); this.$parent = this.$label.parent('.checkbox'); this.$toggleContainer = this.$element.attr('data-toggle'); this.state = { disabled: false, checked: false }; if( this.$parent.length === 0 ) { this.$parent = null; } if( Boolean( this.$toggleContainer ) ) { this.$toggleContainer = $( this.$toggleContainer ); } else { this.$toggleContainer = null; } // handle events this.$element.on('change.fu.checkbox', $.proxy( this.itemchecked, this )); this.$label.on('click', $.proxy(this.toggle, this));//make repeated label clicks work // set default state this.setState(); }; Checkbox.prototype = { constructor: Checkbox, setState: function( $chk ) { $chk = $chk || this.$element; this.state.disabled = Boolean( $chk.prop('disabled') ); this.state.checked = Boolean( $chk.is(':checked') ); this._resetClasses(); // set state of checkbox this._toggleCheckedState(); this._toggleDisabledState(); //toggle container this.toggleContainer(); }, enable: function() { this.state.disabled = false; this.$element.attr('disabled', false); this._resetClasses(); this.$element.trigger( 'enabled.fu.checkbox' ); }, disable: function() { this.state.disabled = true; this.$element.attr('disabled', true); this._setDisabledClass(); this.$element.trigger( 'disabled.fu.checkbox' ); }, check: function () { this.state.checked = true; this.$element.prop('checked', true); this.$element.attr('checked','checked'); this._setCheckedClass(); this.$element.trigger( 'checked.fu.checkbox' ); }, uncheck: function () { this.state.checked = false; this.$element.prop('checked', false); this.$element.removeAttr('checked'); this._resetClasses(); this.$element.trigger( 'unchecked.fu.checkbox' ); }, isChecked: function () { return this.state.checked; }, toggle: function(e) { //keep event from firing twice in Chrome if (!e || (e.target === e.originalEvent.target)) { this.state.checked = !this.state.checked; this._toggleCheckedState(); if(Boolean(e)){ //stop bubbling, otherwise event fires twice in Firefox. e.preventDefault(); //make change event still fire (prevented by preventDefault to avoid firefox bug, see preceeding line) this.$element.trigger('change', e); } } }, toggleContainer: function(){ if( Boolean( this.$toggleContainer ) ) { if( this.state.checked ) { this.$toggleContainer.removeClass('hide'); this.$toggleContainer.attr('aria-hidden', 'false'); }else { this.$toggleContainer.addClass('hide'); this.$toggleContainer.attr('aria-hidden', 'true'); } } }, itemchecked: function( element ) { this.setState( $( element.target ) ); }, destroy: function() { this.$parent.remove(); // remove any external bindings // [none] // empty elements to return to original markup // [none] return this.$parent[0].outerHTML; }, _resetClasses: function() { var classesToRemove = []; if( !this.state.checked ) { classesToRemove.push( 'checked' ); } if( !this.state.disabled ) { classesToRemove.push( 'disabled' ); } classesToRemove = classesToRemove.join( ' ' ); this.$label.removeClass( classesToRemove ); if( this.$parent ) { this.$parent.removeClass( classesToRemove ); } }, _toggleCheckedState: function() { if( this.state.checked ) { this.check(); } else { this.uncheck(); } }, _toggleDisabledState: function() { if( this.state.disabled ) { this.disable(); } else { this.enable(); } }, _setCheckedClass: function() { this.$label.addClass('checked'); if( this.$parent ) { this.$parent.addClass('checked'); } }, _setDisabledClass: function() { this.$label.addClass('disabled'); if( this.$parent ){ this.$parent.addClass('disabled'); } } }; // CHECKBOX PLUGIN DEFINITION $.fn.checkbox = function (option) { var args = Array.prototype.slice.call( arguments, 1 ); var methodReturn; var $set = this.each(function () { var $this = $( this ); var data = $this.data('fu.checkbox'); var options = typeof option === 'object' && option; if( !data ) { $this.data('fu.checkbox', (data = new Checkbox(this, options))); } if( typeof option === 'string' ) { methodReturn = data[ option ].apply( data, args ); } }); return ( methodReturn === undefined ) ? $set : methodReturn; }; $.fn.checkbox.defaults = {}; $.fn.checkbox.Constructor = Checkbox; $.fn.checkbox.noConflict = function () { $.fn.checkbox = old; return this; }; // DATA-API $(document).on('mouseover.fu.checkbox.data-api', '[data-initialize=checkbox]', function (e) { var $control = $(e.target).closest('.checkbox').find('[type=checkbox]'); if ( !$control.data('fu.checkbox') ) { $control.checkbox($control.data()); } }); // Must be domReady for AMD compatibility $(function () { $('[data-initialize=checkbox] [type=checkbox]').each(function () { var $this = $(this); if (!$this.data('fu.checkbox')) { $this.checkbox($this.data()); } }); }); // -- BEGIN UMD WRAPPER AFTERWORD -- })); // -- END UMD WRAPPER AFTERWORD --