Skip to content

Commit 6263fba

Browse files
committed
Checkboxradio: allow the parent of the input to be the label
Conflicts: ui/checkboxradio.js
1 parent 9b75e1d commit 6263fba

File tree

6 files changed

+68
-30
lines changed

6 files changed

+68
-30
lines changed

tests/unit/checkboxradio/checkboxradio.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@
8080
<input type="checkbox" class="foo" id="checkbox-option-icon"/>
8181
<label for="checkbox-option-label">checkbox label</label>
8282
<input type="checkbox" class="foo" id="checkbox-option-label"/>
83+
<label>
84+
<input type="checkbox" id="label-with-no-for"/>
85+
</label>
8386
</div>
8487
</body>
8588
</html>

tests/unit/checkboxradio/checkboxradio_core.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ if ( !$.ui.ie || ( document.documentMode && document.documentMode > 8 ) ) {
9090
}, 1 );
9191
});
9292
}
93-
test( "Checkbox creation that requires a matching label does not find label in all cases", function() {
94-
expect( 5 );
93+
test( "Checkbox creation that requires a matching finds label in all cases", function() {
94+
expect( 6 );
9595
var group = $( "<span><label for='t7092a'></label><input type='checkbox' id='t7092a'></span>" );
9696
group.find( "input[type=checkbox]" ).checkboxradio();
9797
ok( group.find( "label" ).is( ".ui-button" ) );
@@ -111,6 +111,10 @@ test( "Checkbox creation that requires a matching label does not find label in a
111111
group = $( "<input type='checkbox' id='t7092e'><span><label for='t7092e'></label></span>" );
112112
group.filter( "input[type=checkbox]" ).checkboxradio();
113113
ok( group.find( "label" ).is( ".ui-button" ) );
114+
115+
group = $( "<span><label><input type='checkbox' id='t7092f'></label></span>" );
116+
group.find( "input[type=checkbox]" ).checkboxradio();
117+
ok( group.find( "label" ).is( ".ui-button" ) );
114118
});
115119

116120
asyncTest( "Resetting a button's form should refresh the visual state of the button widget to match.", function() {

tests/unit/checkboxradio/checkboxradio_methods.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module( "Checkboxradio: methods" );
4040
"label classes match original after destroy" );
4141
});
4242

43-
test( "Checkbox: disable / enable", function(){
43+
test( "Checkbox: disable / enable", function() {
4444
var checkbox = $( "#checkbox-method-disable" );
4545

4646
expect( 4 );
@@ -101,7 +101,7 @@ module( "Checkboxradio: methods" );
101101
"label classes match original after destroy" );
102102
});
103103

104-
test( "Radio: disable / enable", function(){
104+
test( "Radio: disable / enable", function() {
105105
var radio = $( "#checkbox-method-disable" );
106106

107107
expect( 4 );
@@ -127,5 +127,14 @@ module( "Checkboxradio: methods" );
127127
strictEqual( radio.checkboxradio( "widget" ).attr( "id" ), label.attr( "id" ),
128128
"widget method returns label" );
129129
});
130+
test( "Input wrapped in a label preserved on refresh", function() {
131+
var input = $( "#label-with-no-for" ).checkboxradio(),
132+
element = input.checkboxradio( "widget" );
133+
134+
expect( 1 );
135+
136+
input.checkboxradio( "refresh" );
137+
strictEqual( input.parent().is( element ), true, "Input preserved" );
138+
});
130139

131140
})(jQuery);

tests/unit/checkboxradio/checkboxradio_options.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
-/*
22
* checkboxradio_methods.js
33
*/
44

@@ -130,7 +130,7 @@ module( "Checkboxradio: checkbox: options" );
130130

131131
strictEqual( checkbox.checkboxradio( "option", "label" ),
132132
"checkbox label", "When no value passed on create text from dom is used for option" );
133-
strictEqual( widget.text(),
133+
strictEqual( widget.contents().not( this.element ),
134134
"checkbox label", "When no value passed on create text from dom is used in dom" );
135135

136136
checkbox.checkboxradio( "destroy" );
@@ -141,7 +141,7 @@ module( "Checkboxradio: checkbox: options" );
141141

142142
strictEqual( checkbox.checkboxradio( "option", "label" ),
143143
"foo", "When value is passed on create value is used for option" );
144-
strictEqual( widget.text(),
144+
strictEqual( widget.contents().not( this.element ),
145145
"foo", "When value is passed on create value is used in dom" );
146146

147147
checkbox.checkboxradio( "destroy" );
@@ -151,21 +151,21 @@ module( "Checkboxradio: checkbox: options" );
151151

152152
strictEqual( checkbox.checkboxradio( "option", "label" ),
153153
"foo", "When null is passed on create text from dom is used for option" );
154-
strictEqual( widget.text(),
154+
strictEqual( widget.contents().not( this.element ),
155155
"foo", "When null is passed on create text from dom is used in dom" );
156156

157157
checkbox.checkboxradio( "option", "label", "bar" );
158158

159159
strictEqual( checkbox.checkboxradio( "option", "label" ),
160160
"bar", "When value is passed value is used for option" );
161-
strictEqual( widget.text(),
161+
strictEqual( widget.contents().not( this.element ),
162162
"bar", "When value is passed value is used in dom" );
163163

164164
checkbox.checkboxradio( "option", "label", null );
165165

166166
strictEqual( checkbox.checkboxradio( "option", "label" ),
167167
"bar", "When null is passed text from dom is used for option" );
168-
strictEqual( widget.text(),
168+
strictEqual( widget.contents().not( this.element ),
169169
"bar", "When null is passed text from dom is used in dom" );
170170

171171
});

tests/visual/checkboxradio/checkbox.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,8 @@
6161
<label for="checkbox-1">Checkbox widget sample</label>
6262
<input type="checkbox" id="checkbox-2"><label for="checkbox-2">Checkbox widget sample</label>
6363

64-
<input type="radio" id="radio-1" name="radio" checked>
65-
<label for="radio-1">Radio widget sample</label>
66-
<input type="radio" id="radio-2" name="radio"><label for="radio-2">Radio widget sample 2</label>
64+
<label for="radio-1">Radio widget sample <input type="radio" id="radio-1" name="radio" checked></label>
65+
<input type="radio" id="radio-2" name="radio"><label for="radio-2"><span>boom</span>Radio widget sample 2</label>
6766
<button type="reset">Reset</button>
6867
</form>
6968
</body>

ui/checkboxradio.js

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,38 @@ var baseClasses = "ui-button ui-widget ui-corner-all",
5454

5555
$.widget( "ui.checkboxradio", {
5656
version: "@VERSION",
57-
defaultElement: "<input type='checkbox'>",
5857
options: {
5958
disabled: null,
6059
label: null,
61-
icon: false
60+
icon: true,
61+
classes: {
62+
"ui-checkboxradio": null,
63+
"ui-checkbox": null,
64+
"ui-radio": null,
65+
"ui-checkbox-label": "ui-corner-all",
66+
"ui-radio-label": "ui-corner-all",
67+
"ui-checkboxradio-icon": "ui-corner-all",
68+
"ui-radio-checked": null,
69+
"ui-checkbox-checked": null
70+
}
6271
},
6372

6473
_getCreateOptions: function() {
65-
var options = {};
74+
var disabled,
75+
that = this,
76+
options = {};
6677

6778
this._readLabel();
6879

69-
this.originalLabel = this.label.html();
80+
this.originalLabel = "";
81+
this.label.contents().not( this.element ).each( function() {
82+
that.originalLabel += ( this.nodeType === 3 ) ? $( this ).text() : this.outerHTML;
83+
});
7084

71-
this._readDisabled( options );
85+
disabled = this.element.prop( "disabled" );
86+
if ( disabled != null ) {
87+
options.disabled = disabled;
88+
}
7289

7390
if ( this.originalLabel ) {
7491
options.label = this.originalLabel;
@@ -95,13 +112,9 @@ $.widget( "ui.checkboxradio", {
95112
formElement.off( "reset" + this.eventNamespace, formResetHandler );
96113
formElement.on( "reset" + this.eventNamespace, formResetHandler );
97114

98-
// If the option is a boolean its been set by either user or by
99-
// _getCreateOptions so we need to make sure the prop matches
100-
// If it is not a boolean the user set it explicitly to null so we need to check the dom
101-
if ( typeof this.options.disabled === "boolean" ) {
102-
this.element.prop( "disabled", this.options.disabled );
103-
} else {
104-
this._readDisabled( this.options );
115+
// If it is null the user set it explicitly to null so we need to check the dom
116+
if ( this.options.disabled == null ) {
117+
this.options.disabled = this.element.prop( "disabled" ) || false;
105118
}
106119

107120
// If the option is true we call set options to add the disabled
@@ -134,11 +147,16 @@ $.widget( "ui.checkboxradio", {
134147

135148
_readLabel: function() {
136149
var ancestor, labelSelector,
137-
labels = this.element[ 0 ].labels;
150+
parent = this.element.closest( "label" );
151+
152+
this.parentLabel = false;
138153

139154
// Check control.labels first
140-
if ( labels !== undefined && labels.length > 0 ) {
141-
this.label = $( labels[ 0 ] );
155+
if ( this.element[ 0 ].labels !== undefined && this.element[ 0 ].labels.length > 0 ){
156+
this.label = $( this.element[ 0 ].labels[ 0 ] );
157+
} else if ( parent.length > 0 ) {
158+
this.label = parent;
159+
this.parentLabel = true;
142160
} else {
143161

144162
// We don't search against the document in case the element
@@ -241,6 +259,8 @@ $.widget( "ui.checkboxradio", {
241259

242260
if ( this.type === "checkbox" ) {
243261
toAdd += checked ? "ui-icon-check" : "ui-icon-blank";
262+
} else {
263+
toAdd += "ui-icon-blank";
244264
}
245265
this.icon.addClass( toAdd ).appendTo( this.label );
246266
} else if ( this.icon !== undefined ) {
@@ -254,9 +274,12 @@ $.widget( "ui.checkboxradio", {
254274
var checked = this.element.is( ":checked" ),
255275
isDisabled = this.element.is( ":disabled" );
256276
this._updateIcon( checked );
257-
this.label.toggleClass( "ui-state-active ui-" + this.type + "-checked", checked );
277+
console.log( this.options.label );
278+
this.label.toggleClass( "ui-state-active " + this._classes( "ui-" + this.type + "-checked" ), checked );
258279
if ( this.options.label !== null ) {
259-
this.label.html( !!this.icon ? this.icon : "" ).append( this.options.label );
280+
this.label.contents().not( this.element.add( this.icon ) ).remove();
281+
this.label.append( this.options.label );
282+
260283
}
261284

262285
if ( isDisabled !== this.options.disabled ) {

0 commit comments

Comments
 (0)