mirror of
https://github.com/ExactTarget/fuelux.git
synced 2026-01-10 15:08:02 -05:00
231 lines
6.0 KiB
JavaScript
231 lines
6.0 KiB
JavaScript
/* 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 --
|