UNPKG

fuelux

Version:

Base Fuel UX styles and controls

231 lines (179 loc) 6.13 kB
/* global jQuery:true */ /* * Fuel UX Radio * 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 umdFactory (factory) { if (typeof define === 'function' && define.amd) { // if AMD loader is available, register as an anonymous module. define(['jquery'], factory); } else if (typeof exports === 'object') { // Node/CommonJS module.exports = factory(require('jquery')); } else { // OR use browser globals if AMD is not present factory(jQuery); } }(function RadioWrapper ($) { // -- END UMD WRAPPER PREFACE -- // -- BEGIN MODULE CODE HERE -- var old = $.fn.radio; // RADIO CONSTRUCTOR AND PROTOTYPE var logError = function logError (error) { if (window && window.console && window.console.error) { window.console.error(error); } }; var Radio = function Radio (element, options) { this.options = $.extend({}, $.fn.radio.defaults, options); if (element.tagName.toLowerCase() !== 'label') { logError('Radio must be initialized on the `label` that wraps the `input` element. See https://github.com/ExactTarget/fuelux/blob/master/reference/markup/radio.html for example of proper markup. Call `.radio()` on the `<label>` not the `<input>`'); return; } // cache elements this.$label = $(element); this.$radio = this.$label.find('input[type="radio"]'); this.groupName = this.$radio.attr('name'); // don't cache group itself since items can be added programmatically if (!this.options.ignoreVisibilityCheck && this.$radio.css('visibility').match(/hidden|collapse/)) { logError('For accessibility reasons, in order for tab and space to function on radio, `visibility` must not be set to `hidden` or `collapse`. See https://github.com/ExactTarget/fuelux/pull/1996 for more details.'); } // determine if a toggle container is specified var containerSelector = this.$radio.attr('data-toggle'); this.$toggleContainer = $(containerSelector); // handle internal events this.$radio.on('change', $.proxy(this.itemchecked, this)); // set default state this.setInitialState(); }; Radio.prototype = { constructor: Radio, setInitialState: function setInitialState () { var $radio = this.$radio; // get current state of input var checked = $radio.prop('checked'); var disabled = $radio.prop('disabled'); // sync label class with input state this.setCheckedState($radio, checked); this.setDisabledState($radio, disabled); }, resetGroup: function resetGroup () { var $radios = $('input[name="' + this.groupName + '"]'); $radios.each(function resetRadio (index, item) { var $radio = $(item); var $lbl = $radio.parent(); var containerSelector = $radio.attr('data-toggle'); var $containerToggle = $(containerSelector); $lbl.removeClass('checked'); $containerToggle.addClass('hidden'); }); }, setCheckedState: function setCheckedState (element, checked) { var $radio = element; var $lbl = $radio.parent(); var containerSelector = $radio.attr('data-toggle'); var $containerToggle = $(containerSelector); if (checked) { // reset all items in group this.resetGroup(); $radio.prop('checked', true); $lbl.addClass('checked'); $containerToggle.removeClass('hide hidden'); $lbl.trigger('checked.fu.radio'); } else { $radio.prop('checked', false); $lbl.removeClass('checked'); $containerToggle.addClass('hidden'); $lbl.trigger('unchecked.fu.radio'); } $lbl.trigger('changed.fu.radio', checked); }, setDisabledState: function setDisabledState (element, disabled) { var $radio = $(element); var $lbl = this.$label; if (disabled) { $radio.prop('disabled', true); $lbl.addClass('disabled'); $lbl.trigger('disabled.fu.radio'); } else { $radio.prop('disabled', false); $lbl.removeClass('disabled'); $lbl.trigger('enabled.fu.radio'); } return $radio; }, itemchecked: function itemchecked (evt) { var $radio = $(evt.target); this.setCheckedState($radio, true); }, check: function check () { this.setCheckedState(this.$radio, true); }, uncheck: function uncheck () { this.setCheckedState(this.$radio, false); }, isChecked: function isChecked () { var checked = this.$radio.prop('checked'); return checked; }, enable: function enable () { this.setDisabledState(this.$radio, false); }, disable: function disable () { this.setDisabledState(this.$radio, true); }, destroy: function destroy () { this.$label.remove(); return this.$label[0].outerHTML; } }; Radio.prototype.getValue = Radio.prototype.isChecked; // RADIO PLUGIN DEFINITION $.fn.radio = function radio (option) { var args = Array.prototype.slice.call(arguments, 1); var methodReturn; var $set = this.each(function applyData () { var $this = $(this); var data = $this.data('fu.radio'); var options = typeof option === 'object' && option; if (!data) { $this.data('fu.radio', (data = new Radio(this, options))); } if (typeof option === 'string') { methodReturn = data[option].apply(data, args); } }); return (methodReturn === undefined) ? $set : methodReturn; }; $.fn.radio.defaults = { ignoreVisibilityCheck: false }; $.fn.radio.Constructor = Radio; $.fn.radio.noConflict = function noConflict () { $.fn.radio = old; return this; }; // DATA-API $(document).on('mouseover.fu.radio.data-api', '[data-initialize=radio]', function initializeRadios (e) { var $control = $(e.target); if (!$control.data('fu.radio')) { $control.radio($control.data()); } }); // Must be domReady for AMD compatibility $(function onReadyInitializeRadios () { $('[data-initialize=radio]').each(function initializeRadio () { var $this = $(this); if (!$this.data('fu.radio')) { $this.radio($this.data()); } }); }); // -- BEGIN UMD WRAPPER AFTERWORD -- })); // -- END UMD WRAPPER AFTERWORD --