Skip to content
This repository has been archived by the owner on Oct 8, 2021. It is now read-only.

Commit

Permalink
Checkboxradio: Correctly assemble radio group
Browse files Browse the repository at this point in the history
Closes gh-6659
Closes gh-7082
Fixes gh-7088
  • Loading branch information
Gabriel Schulhof committed Feb 23, 2014
1 parent 1e63d05 commit 0bdab77
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 7 deletions.
54 changes: 47 additions & 7 deletions js/widgets/forms/checkboxradio.js
Expand Up @@ -10,12 +10,15 @@
//>>css.theme: ../css/themes/default/jquery.mobile.theme.css

define( [ "jquery",
"../../navigation/path",
"../../jquery.mobile.core",
"../../jquery.mobile.widget",
"./reset" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {

var escapeId = $.mobile.path.hashToSelector;

$.widget( "mobile.checkboxradio", $.extend( {

initSelector: "input:not( :jqmData(role='flipswitch' ) )[type='checkbox'],input[type='radio']:not( :jqmData(role='flipswitch' ))",
Expand All @@ -42,7 +45,7 @@ $.widget( "mobile.checkboxradio", $.extend( {
input
.closest( "form, fieldset, :jqmData(role='page'), :jqmData(role='dialog')" )
.find( "label" )
.filter( "[for='" + $.mobile.path.hashToSelector( input[0].id ) + "']" )
.filter( "[for='" + escapeId( input[0].id ) + "']" )
.first(),
inputtype = input[0].type,
checkedClass = "ui-" + inputtype + "-on",
Expand Down Expand Up @@ -182,14 +185,51 @@ $.widget( "mobile.checkboxradio", $.extend( {
});
},

//returns either a set of radios with the same name attribute, or a single checkbox
// Returns those radio buttons that are supposed to be in the same group as
// this radio button. In the case of a checkbox or a radio lacking a name
// attribute, it returns this.element.
_getInputSet: function() {
if ( this.inputtype === "checkbox" ) {
return this.element;
var selector, formId,
radio = this.element[ 0 ],
name = radio.name,
form = radio.form,
doc = this.element.parents().last().get( 0 ),

// A radio is always a member of its own group
radios = this.element;

// Only start running selectors if this is an attached radio button with a name
if ( name && this.inputtype === "radio" && doc ) {
selector = "input[type='radio'][name='" + escapeId( name ) + "']";

// If we're inside a form
if ( form ) {
formId = form.id;

// If the form has an ID, collect radios scattered throught the document which
// nevertheless are part of the form by way of the value of their form attribute
if ( formId ) {
radios = $( selector + "[form='" + escapeId( formId ) + "']", doc );
}

// Also add to those the radios in the form itself
radios = $( form ).find( selector ).filter( function() {

// Some radios inside the form may belong to some other form by virtue of
// having a form attribute defined on them, so we must filter them out here
return ( this.form === form );
}).add( radios );

// If we're outside a form
} else {

// Collect all those radios which are also outside of a form and match our name
radios = $( selector, doc ).filter( function() {
return !this.form;
});
}
}

return this.element.closest( "form, :jqmData(role='page'), :jqmData(role='dialog')" )
.find( "input[name='" + this.element[ 0 ].name + "'][type='" + this.inputtype + "']" );
return radios;
},

_updateAll: function() {
Expand Down
50 changes: 50 additions & 0 deletions tests/unit/checkboxradio/input-set-tests.html
@@ -0,0 +1,50 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>jQuery Mobile Checkboxradio Input Set Test Suite</title>

<script src="../../../external/requirejs/require.js"></script>
<script src="../../../js/requirejs.config.js"></script>
<script src="../../../js/jquery.tag.inserter.js"></script>
<script src="../../../tests/jquery.testHelper.js"></script>
<script src="../../../external/qunit/qunit.js"></script>
<script>
$.testHelper.asyncLoad([
[
"widgets/forms/checkboxradio",
],
[
"input_set_tests_core.js"
]
]);
</script>

<link rel="stylesheet" href="../../../external/qunit/qunit.css"/>
<link rel="stylesheet" href="../../jqm-tests.css"/>

<script src="../../swarminject.js"></script>
</head>
<body>

<div id="qunit"></div>

<div data-nstest-role="page">
<label>Radio<input id="radio:1" type="radio" name="group1"></label>
<form id="the-[form]">
<label>Radio<input id="radio:2" type="radio" name="group1"></label>
<label>Radio<input id="radio:7" type="radio" name="group1" form="the-'other'-form"></label>
</form>
<label>Radio<input id="radio:3" type="radio" name="group1" form="the-[form]"></label>
<form id="the-'other'-form">
<label>Radio<input id="radio:6" type="radio" name="group1" form="the-[form]"></label>
<label>Radio<input id="radio:4" type="radio" name="group1"></label>
</form>

<!-- radio5 (below) is not supposed to have a name -->
<label>Radio<input id="radio:5" type="radio"></label>
</div>

<label>Radio<input id="radio:8" type="radio" name="group1"></label>
</body>
</html>
36 changes: 36 additions & 0 deletions tests/unit/checkboxradio/input_set_tests_core.js
@@ -0,0 +1,36 @@
( function( $, undefined ) {

test( "Radio groups are correctly identified", function() {
var detached = $( "<input type='radio' name='group1' id='detached'>" ),
groups = {
"#radio\\:1": "#radio\\:1,#radio\\:8",
"#radio\\:2": "#radio\\:2,#radio\\:3,#radio\\:6",
"#radio\\:3": "#radio\\:2,#radio\\:3,#radio\\:6",
"#radio\\:6": "#radio\\:2,#radio\\:3,#radio\\:6",
"#radio\\:4": "#radio\\:4,#radio\\:7",
"#radio\\:7": "#radio\\:4,#radio\\:7",
"#radio\\:5": "#radio\\:5",
"#radio\\:8": "#radio\\:1,#radio\\:8"
},
checkGroup = function( radio, group ) {
var prefix = radio.attr( "id" ) + ": ",
result = $.mobile.checkboxradio.prototype._getInputSet.call({
element: radio,
inputtype: "radio"
});

deepEqual( group.length, result.length, prefix + "length of group is correct" );
group.each( function() {
deepEqual( result.filter( this ).length, 1,
prefix + $( this ).attr( "id" ) + " is correctly present in the result" );
});
};

$.each( groups, function( index, value ) {
checkGroup( $( index ), $( value ) );
});

checkGroup( detached, detached );
});

})( jQuery );

0 comments on commit 0bdab77

Please sign in to comment.