Skip to content

Commit

Permalink
Merge pull request #60 from FinalAngel/bugfix/uniform-radios-same-name
Browse files Browse the repository at this point in the history
fix incorrect uniform radio handling
  • Loading branch information
Angelo Dini committed Nov 5, 2014
2 parents 8288dcd + 0f0ccc2 commit 510f93f
Show file tree
Hide file tree
Showing 6 changed files with 2,526 additions and 2,199 deletions.
5 changes: 5 additions & 0 deletions src/cl.uniform/CHANGELOG.rst
Expand Up @@ -2,6 +2,11 @@
Cl.Uniform
==========

1.2.1
-----
- fixed issue with uniform unchecking all the radios with same name in the document, now relies on browser behaviour


1.2.0
-----
- added ``ready`` class option
Expand Down
49 changes: 24 additions & 25 deletions src/cl.uniform/cl.uniform.js
@@ -1,7 +1,7 @@
/*!
* @author Angelo Dini - github.com/finalangel/classjs-plugins
* @copyright Distributed under the BSD License.
* @version 1.2.0
* @version 1.2.1
* @contributer Vanessa Hänni, Vadim Sikora
*/

Expand Down Expand Up @@ -74,7 +74,6 @@ var Cl = window.Cl || {};

this.elements.each(function (index, item) {
var input = $(item);
// console.log(input);

//FIXME will break if you do custom templates
// also doesn't remove comment nodes
Expand Down Expand Up @@ -137,33 +136,35 @@ var Cl = window.Cl || {};
var parent = field.parents('.' + cls.prefix);

var _changeVisualState = function (input, type) {
var knob = input.siblings('.' + clsKnob);
var enabled = false;
var checked = false;
var knob;
var group;

if (type === 'checkbox') {
// we need to check if we should activate or deactivate the checkbox
enabled = input.is(':checked');
checked = input.is(':checked');
knob = input.siblings('.' + clsKnob);
// don't use toggle, jQuery UI bug: http://bugs.jqueryui.com/ticket/10557
if (enabled) {
knob.show();
} else {
knob.hide();
}
knob[checked ? 'show' : 'hide']();

// accessibility
parent.attr('aria-checked', enabled);
parent.attr('aria-checked', checked);

} else { // radio
// we need to determine the radio group and trigger/enable them at once
var group = $('input[type="radio"][name="' + input.attr('name') + '"]');
group.siblings('.' + clsKnob).hide();
//does it make sense to uncheck the whole group which is the native behaviour?
group.not(input).attr('checked', false);
knob.show();

// accessibility
group.parents('.' + cls.prefix).attr('aria-checked', false);
parent.attr('aria-checked',true);
group = $(':radio[name="' + input.attr('name') + '"]');
group.each(function () {
// update current state for each radio button with same name
// since the input state is already changed we can just change visual/accessibility
// state based on current state of the input
var input = $(this);
var knob = input.siblings('.' + clsKnob);
var parent = input.parents('.' + cls.prefix);
var checked = input.is(':checked');

knob[checked ? 'show' : 'hide']();
// accessibility
parent.attr('aria-checked', checked);
});
}
};

Expand All @@ -178,20 +179,18 @@ var Cl = window.Cl || {};
// cancel event if element is disabled
if (input.is(':disabled')) return false;

_changeVisualState(input, type);

if (type === 'checkbox') {
// we need to check if we should activate or deactivate the checkbox
enabled = input.is(':checked');
} else { // radio
enabled = true;
enabled = true;
}

// set focus and checked to current element
// setting the attribute fixes the issue for form submits
input.trigger('focus');
//we need to explicitly set in case there are no label and the input is unclickable
input.attr('checked', enabled);
input.attr('checked', enabled).trigger('change');

// api call
input.trigger(cls.prefix + 'change');
Expand Down
2 changes: 1 addition & 1 deletion src/cl.uniform/cl.uniform.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 48 additions & 1 deletion tests/cl.uniform.js
Expand Up @@ -9,7 +9,26 @@

var uniform = new Cl.Uniform();

module('cl.uniform.js');
module('cl.uniform.js', {
setup: function () {
var fixture = $('#qunit-fixture');
fixture.append([
'<div class="uniformed">',
'<form class="form1" action="."><input type="radio" name="x" value="1" checked="checked" /><input type="radio" name="x" value="2" /></form>',
'<form class="form2" action="."><input type="radio" name="x" value="3" checked="checked" /><input type="radio" name="x" value="4" /></form>',
'<div class="not-a-form">',
'<input type="radio" name="x" value="5" />',
'<input type="radio" name="x" value="6" />',
'<input type="radio" name="x" value="7" checked="checked" />',
'<input type="radio" name="x" value="8" />',
'</div>',
'</div>'
].join(''));

new Cl.Uniform('.uniformed input:radio');

}
});

test('Options', function() {
var options = ['offset'];
Expand Down Expand Up @@ -70,3 +89,31 @@ test('Test for issue #41: Uniform Upload in IE', function() {

ok(upload.length === 1, 'upload field is available.');
});

test('Test for issue #59: radios with same name across different forms', function () {
var fixture = $('#qunit-fixture');

equal(fixture.find('.form1').find('input:radio:checked').val(), '1', 'initial values are ok');
equal(fixture.find('.form2').find('input:radio:checked').val(), '3', 'initial values are ok');
// NOTE: these tests are commented because PhantomJS currently incorrectly handles radio groups that are injected/modified
// https://github.com/ariya/phantomjs/issues/12039
// equal(fixture.find('.not-a-form').find('input:radio:checked').val(), '7', 'initial values are ok');
});

test('Test for issue #59: radios with same name across different forms', function () {
var fixture = $('#qunit-fixture');
fixture.find('.form1').find('input:radio:last').prop('checked', true).trigger('change');

equal(fixture.find('.form1').find('input:radio:checked').val(), '2', 'change in the form affects only that form');
equal(fixture.find('.form2').find('input:radio:checked').val(), '3', 'change in the form affects only that form');
// equal(fixture.find('.not-a-form').find('input:radio:checked').val(), '7', 'change in the form affects only that form');
});

test('Test for issue #59: radios with same name across different forms', function () {
var fixture = $('#qunit-fixture');
fixture.find('.not-a-form').find('input:radio:first').prop('checked', true).trigger('change');

equal(fixture.find('.form1').find('input:radio:checked').val(), '1', 'change outside of the form affects only radios that are outside of forms');
equal(fixture.find('.form2').find('input:radio:checked').val(), '3', 'change outside of the form affects only radios that are outside of forms');
equal(fixture.find('.not-a-form').find('input:radio:checked').val(), '5', 'change outside of the form affects only radios that are outside of forms');
});

0 comments on commit 510f93f

Please sign in to comment.