diff --git a/index.html b/index.html index 0489d4e9d..855e01227 100644 --- a/index.html +++ b/index.html @@ -720,13 +720,13 @@

Radio Buttons

@@ -799,6 +799,14 @@

Radio Buttons

Custom inline highlight radio +
+ + + + + + +
diff --git a/index.js b/index.js index 46b77c315..53bff3631 100644 --- a/index.js +++ b/index.js @@ -426,22 +426,27 @@ define(function (require) { // sample method buttons $('#btnRadioDisable').on('click', function () { - $('[name=radio1]').radio('disable'); + console.log('in disable'); + $('#myCustomRadio1').radio('disable'); }); $('#btnRadioEnable').on('click', function () { - $('[name=radio1]').radio('enable'); + $('#myCustomRadio1').radio('enable'); }); $('#btnRadioDestroy').on('click', function () { - var $container = $('#myCustomRadio1').parents('.thin-box:first'); + var $container = $('#myCustomRadio1').parent(); var markup = $('#myCustomRadio1').radio('destroy'); + log(markup); $container.append(markup); - $('#myRadio1').radio(); }); - $('#btnRadioInlineDestroy').on('click', function () { - var $container = $('#myCustomInlineRadio1').parents('.thin-box:first'); - var markup = $('#myCustomInlineRadio1').radio('destroy'); - $container.append(markup); - $('#myCustomInlineRadio1').radio(); + $('#btnRadioIsChecked').on('click', function () { + var checked = $('#myCustomRadio1').radio('isChecked'); + log(checked); + }); + $('#btnRadioCheck').on('click', function () { + $('#myCustomRadio1').radio('check'); + }); + $('#btnRadioUncheck').on('click', function () { + $('#myCustomRadio1').radio('uncheck'); }); diff --git a/js/radio.js b/js/radio.js index 404ae32a9..e04eb0885 100644 --- a/js/radio.js +++ b/js/radio.js @@ -31,152 +31,132 @@ var Radio = function (element, options) { this.options = $.extend({}, $.fn.radio.defaults, options); - // cache elements - this.$radio = $(element).is('input[type="radio"]') ? $(element) : $(element).find('input[type="radio"]:first'); - this.$label = this.$radio.parent(); - this.groupName = this.$radio.attr('name'); - this.$blockWrapper = this.$label.parent('.radio'); // only used if block radio control, otherwise radio is inline - this.isBlockWrapped = true; // initialized as a block radio control - this.$toggleContainer = null; - - if (this.$blockWrapper.length === 0) { - this.isBlockWrapped = false; + if(element.tagName.toLowerCase() !== 'label') { + //console.log('initialize radio on the label that wraps the radio'); + return; } - var toggleSelector = this.$radio.attr('data-toggle'); - if (toggleSelector) { - this.$toggleContainer = $(toggleSelector); - } + // 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 - // set default state - this.setState(this.$radio); + // 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)); - // handle events - this.$radio.on('change.fu.radio', $.proxy(this.itemchecked, this)); + // set default state + this.setInitialState(); }; Radio.prototype = { constructor: Radio, - destroy: function () { - // remove any external bindings - // [none] - // empty elements to return to original markup - // [none] - // return string of markup - if (this.isBlockWrapped) { - this.$blockWrapper.remove(); - return this.$blockWrapper[0].outerHTML; - } else { - this.$label.remove(); - return this.$label[0].outerHTML; - } + setInitialState: function() { + var $radio = this.$radio; + var $lbl = this.$label; - }, + // get current state of input + var checked = $radio.prop('checked'); + var disabled = $radio.prop('disabled'); - setState: function ($radio) { - $radio = $radio || this.$radio; + // sync label class with input state + this.setCheckedState($radio, checked); + this.setDisabledState($radio, disabled); + }, - var checked = $radio.is(':checked'); - var disabled = !!$radio.prop('disabled'); + resetGroup: function() { + var $radios = $('input[name="' + this.groupName + '"]'); + $radios.each(function(index, item) { + var $radio = $(item); + var $lbl = $radio.parent(); + var containerSelector = $radio.attr('data-toggle'); + var $containerToggle = $(containerSelector); - this.$label.removeClass('checked'); - if (this.isBlockWrapped) { - this.$blockWrapper.removeClass('checked disabled'); - } - // set state of radio - if (checked === true) { - this.$label.addClass('checked'); - if (this.isBlockWrapped) { - this.$blockWrapper.addClass('checked'); - } + $lbl.removeClass('checked'); + $containerToggle.addClass('hidden'); + }); + }, - } + setCheckedState: function(element, checked) { + // reset all items in group + this.resetGroup(); - if (disabled === true) { - this.$label.addClass('disabled'); - if (this.isBlockWrapped) { - this.$blockWrapper.addClass('disabled'); - } + var $radio = element; + var $lbl = $radio.parent(); + var containerSelector = $radio.attr('data-toggle'); + var $containerToggle = $(containerSelector); + if(checked) { + $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'); } - //toggle container - this.toggleContainer(); + $lbl.trigger('changed.fu.radio', checked); }, - resetGroup: function () { - var group = $('input[name="' + this.groupName + '"]'); - - group.each(function () { - var lbl = $(this).parent('label'); - lbl.removeClass('checked'); - lbl.parent('.radio').removeClass('checked'); - }); - }, + setDisabledState: function(element, disabled) { + var $radio = element; + var $lbl = this.$label; - enable: function () { - this.$radio.attr('disabled', false); - this.$label.removeClass('disabled'); - if (this.isBlockWrapped) { - this.$blockWrapper.removeClass('disabled'); + if(disabled) { + this.$radio.prop('disabled', true); + $lbl.addClass('disabled'); + $lbl.trigger('disabled.fu.radio'); } - }, - - disable: function () { - this.$radio.attr('disabled', true); - this.$label.addClass('disabled'); - if (this.isBlockWrapped) { - this.$blockWrapper.addClass('disabled'); + else { + this.$radio.prop('disabled', false); + $lbl.removeClass('disabled'); + $lbl.trigger('enabled.fu.radio'); } }, - itemchecked: function (e) { - var radio = $(e.target); - - this.resetGroup(); - this.setState(radio); + itemchecked: function (evt) { + var $radio = $(evt.target); + this.setCheckedState($radio, true); }, check: function () { - this.resetGroup(); - this.$radio.prop('checked', true); - this.$radio.attr('checked', 'checked'); - this.setState(this.$radio); + this.setCheckedState(this.$radio, true); }, - toggleContainer: function () { - var group; - if (this.$toggleContainer) { - // show corresponding container for currently selected radio - if (this.isChecked()) { - // hide containers for each item in group - group = $('input[name="' + this.groupName + '"]'); - group.each(function () { - var selector = $(this).attr('data-toggle'); - $(selector).addClass('hidden'); - $(selector).attr('aria-hidden', 'true'); - }); - this.$toggleContainer.removeClass('hide hidden'); // hide is deprecated - this.$toggleContainer.attr('aria-hidden', 'false'); - } else { - this.$toggleContainer.addClass('hidden'); - this.$toggleContainer.attr('aria-hidden', 'true'); - } + uncheck: function () { + this.setCheckedState(this.$radio, false); + }, - } + isChecked: function () { + var checked = this.$radio.prop('checked'); + return checked; }, - uncheck: function () { - this.$radio.prop('checked', false); - this.$radio.removeAttr('checked'); - this.setState(this.$radio); + enable: function () { + this.setDisabledState(this.$radio, false); }, - isChecked: function () { - return this.$radio.is(':checked'); + disable: function () { + this.setDisabledState(this.$radio, true); + }, + + destroy: function () { + this.$label.remove(); + // remove any external bindings + // [none] + // empty elements to return to original markup + // [none] + return this.$label[0].outerHTML; } }; @@ -216,8 +196,8 @@ // DATA-API - $(document).on('mouseover.fu.checkbox.data-api', '[data-initialize=radio]', function (e) { - var $control = $(e.target).closest('.radio').find('[type=radio]'); + $(document).on('mouseover.fu.radio.data-api', '[data-initialize=radio]', function (e) { + var $control = $(e.target); if (!$control.data('fu.radio')) { $control.radio($control.data()); } @@ -225,13 +205,14 @@ // Must be domReady for AMD compatibility $(function () { - $('[data-initialize=radio] [type=radio]').each(function () { + $('[data-initialize=radio]').each(function () { var $this = $(this); - if ($this.data('fu.radio')) return; - $this.radio($this.data()); + if (!$this.data('fu.radio')) { + $this.radio($this.data()); + } }); }); // -- BEGIN UMD WRAPPER AFTERWORD -- })); -// -- END UMD WRAPPER AFTERWORD -- +// -- END UMD WRAPPER AFTERWORD -- \ No newline at end of file diff --git a/js/scheduler.js b/js/scheduler.js index eee3b9af5..85b5b0b94 100644 --- a/js/scheduler.js +++ b/js/scheduler.js @@ -99,7 +99,7 @@ this.$element.find('.datepicker').on('changed.fu.datepicker', $.proxy(this.changed, this)); this.$element.find('.selectlist').on('changed.fu.selectlist', $.proxy(this.changed, this)); this.$element.find('.spinbox').on('changed.fu.spinbox', $.proxy(this.changed, this)); - this.$element.find('.repeat-monthly .radio, .repeat-yearly .radio').on('change.fu.scheduler', $.proxy(this.changed, this)); + this.$element.find('.repeat-monthly .radio-custom, .repeat-yearly .radio-custom').on('change.fu.scheduler', $.proxy(this.changed, this)); }; Scheduler.prototype = { @@ -122,7 +122,7 @@ this.$element.find('.datepicker').datepicker('destroy'); this.$element.find('.selectlist').selectlist('destroy'); this.$element.find('.spinbox').spinbox('destroy'); - this.$element.find('[type=radio]').radio('destroy'); + this.$element.find('.radio-custom').radio('destroy'); this.$element.remove(); // any external bindings @@ -609,7 +609,7 @@ this.$element.find('.datepicker').datepicker(action); this.$element.find('.selectlist').selectlist(action); this.$element.find('.spinbox').spinbox(action); - this.$element.find('[type=radio]').radio(action); + this.$element.find('.radio-custom').radio(action); if (action === 'disable') { action = 'addClass'; diff --git a/less/radio.less b/less/radio.less index 66e06ed8e..717ee0b04 100644 --- a/less/radio.less +++ b/less/radio.less @@ -1,4 +1,5 @@ .radioTabbing() { + /* for keyboard tabbing */ input[type="radio"]:focus + .radio-label, input[type="radio"]:hover + .radio-label, @@ -6,17 +7,29 @@ color: @grayLight; } } - - .radio { &.highlight { padding: 4px; margin: 0 0 5px 0; - & + & { - margin-top: -9px; + & + .radio.highlight { + margin-top: -9px; } - &.checked { + & label.radio-custom { + left: -8px; + padding: 4px 4px 4px 24px; + border-radius: @baseBorderRadius; + &:before { + left: 5px; + top: 7px; + } + &:after { + left: 9px; + top: 11px; + } + } + &.checked label.radio-custom, + & label.radio-custom.checked { background: #e9e9e9; border-radius: @baseBorderRadius; } @@ -28,29 +41,32 @@ .radio-label:hover { color: @grayLight; } - } - -.form-horizontal .radio-inline{ +.form-horizontal .radio-inline { padding-top: 0; } - .input-group-addon.radio-custom.radio-inline { &:before { left: 11px; top: 9px; } - &:after { left: 15px; top: 13px; } } - - .radio-custom { position: relative; + .highlight { + padding: 4px; + margin: 0 0 5px 0; + + &.checked { + background: #e9e9e9; + border-radius: @baseBorderRadius; + } + } &:after { background: transparent; border-radius: 6px; @@ -61,9 +77,7 @@ top: 7px; width: 6px; } - - &:before - { + &:before { border: 1px solid #adadad; border-radius: 14px; content: " "; @@ -73,55 +87,48 @@ top: 3px; width: 14px; } - &.checked { &:after { background: #fff; } - &:before { background: #39b3d7; border-color: #39b3d7; } } - &.disabled { cursor: not-allowed; &:after { cursor: not-allowed; } - &:before { cursor: not-allowed; opacity: .5; } } - &.radio-inline { &:after { left: 4px; top: 7px; } - &:before { left: 0; top: 3px; } - &.highlight { + left: -3px; + padding: 4px 4px 4px 24px; &:after { left: 8px; top: 11px; } - &:before { left: 4px; top: 7px; } - &.checked { background: #e9e9e9; border-radius: @baseBorderRadius; @@ -133,11 +140,7 @@ input[type="radio"]:focus + .radio-label { color: @grayLight; } - } - - label.radio-custom.radio-inline { padding-left: 20px; -} - +} \ No newline at end of file diff --git a/test/markup/radio-markup.html b/test/markup/radio-markup.html index 7ef3ce3b1..e752822dd 100644 --- a/test/markup/radio-markup.html +++ b/test/markup/radio-markup.html @@ -1,47 +1,42 @@
-
-