Skip to content

Commit 3597045

Browse files
committed
Don't have .val() return selected-but-disabled options, or selected options inside a disabled optgroup. Doesn't change the .val() returned for a disabled select. Fixes jquery#3240, adapted from Nathan Hammond's patch there.
1 parent d637ec3 commit 3597045

File tree

6 files changed

+30
-11
lines changed

6 files changed

+30
-11
lines changed

src/attributes.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,10 @@ jQuery.fn.extend({
158158
for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
159159
var option = options[ i ];
160160

161-
if ( option.selected ) {
162-
// Get the specifc value for the option
161+
// Don't return options that are disabled or in a disabled optgroup
162+
if ( option.selected && !option.disabled &&
163+
(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
164+
// Get the specific value for the option
163165
value = jQuery(option).val();
164166

165167
// We don't need an array for one selects

test/index.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,15 @@ <h2 id="qunit-userAgent"></h2>
114114
<option id="option3d" value="3">3</option>
115115
<option id="option3e">no value</option>
116116
</select>
117+
<select name="select4" id="select4" multiple="multiple">
118+
<optgroup disabled="disabled">
119+
<option id="option4a" class="emptyopt" value="">Nothing</option>
120+
<option id="option4b" disabled="disabled" selected="selected" value="1">1</option>
121+
<option id="option4c" selected="selected" value="2">2</option>
122+
</optgroup>
123+
<option selected="selected" disabled="disabled" id="option4d" value="3">3</option>
124+
<option id="option4e">no value</option>
125+
</select>
117126

118127
<object id="object1" codebase="stupid">
119128
<param name="p1" value="x1" />

test/unit/attributes.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ test("removeAttr(String)", function() {
301301
});
302302

303303
test("val()", function() {
304-
expect(17);
304+
expect(20);
305305

306306
document.getElementById('text1').value = "bla";
307307
equals( jQuery("#text1").val(), "bla", "Check for modified value of input element" );
@@ -327,6 +327,14 @@ test("val()", function() {
327327

328328
jQuery('#select3').val("");
329329
same( jQuery('#select3').val(), [''], 'Call val() on a multiple="multiple" select' );
330+
331+
same( jQuery('#select4').val(), [], 'Call val() on multiple="multiple" select with all disabled options' );
332+
333+
jQuery('#select4 optgroup').add('#select4 > [disabled]').attr('disabled', false);
334+
same( jQuery('#select4').val(), ['2', '3'], 'Call val() on multiple="multiple" select with some disabled options' );
335+
336+
jQuery('#select4').attr('disabled', true);
337+
same( jQuery('#select4').val(), ['2', '3'], 'Call val() on disabled multiple="multiple" select' );
330338

331339
var checks = jQuery("<input type='checkbox' name='test' value='1'/>").appendTo("#form")
332340
.add( jQuery("<input type='checkbox' name='test' value='2'/>").appendTo("#form") )

test/unit/event.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ test("bind(), iframes", function() {
216216
});
217217

218218
test("bind(), trigger change on select", function() {
219-
expect(3);
219+
expect(4);
220220
var counter = 0;
221221
function selectOnChange(event) {
222222
equals( event.data, counter++, "Event.data is not a global event object" );

test/unit/selector.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ test("pseudo - misc", function() {
331331
test("pseudo - :not", function() {
332332
expect(24);
333333
t( "Not", "a.blog:not(.link)", ["mark"] );
334-
t( "Not - multiple", "#form option:not(:contains('Nothing'),#option1b,:selected)", ["option1c", "option1d", "option2b", "option2c", "option3d", "option3e"] );
334+
t( "Not - multiple", "#form option:not(:contains('Nothing'),#option1b,:selected)", ["option1c", "option1d", "option2b", "option2c", "option3d", "option3e", "option4e"] );
335335
t( "Not - recursive", "#form option:not(:not(:selected))[id^='option3']", [ "option3b", "option3c"] );
336336

337337
t( ":not() failing interior", "p:not(.foo)", ["firstp","ap","sndp","en","sap","first"] );
@@ -353,8 +353,8 @@ test("pseudo - :not", function() {
353353
t( "No element not selector", ".container div:not(.excluded) div", [] );
354354

355355
t( ":not() Existing attribute", "#form select:not([multiple])", ["select1", "select2"]);
356-
t( ":not() Equals attribute", "#form select:not([name=select1])", ["select2", "select3"]);
357-
t( ":not() Equals quoted attribute", "#form select:not([name='select1'])", ["select2", "select3"]);
356+
t( ":not() Equals attribute", "#form select:not([name=select1])", ["select2", "select3", "select4""]);
357+
t( ":not() Equals quoted attribute", "#form select:not([name='select1'])", ["select2", "select3", "select4"]);
358358

359359
t( ":not() Multiple Class", "#foo a:not(.blog)", ["yahoo","anchor2"] );
360360
t( ":not() Multiple Class", "#foo a:not(.link)", ["yahoo","anchor2"] );
@@ -420,13 +420,13 @@ test("pseudo - visibility", function() {
420420
test("pseudo - form", function() {
421421
expect(8);
422422

423-
t( "Form element :input", "#form :input", ["text1", "text2", "radio1", "radio2", "check1", "check2", "hidden1", "hidden2", "name", "search", "button", "area1", "select1", "select2", "select3"] );
423+
t( "Form element :input", "#form :input", ["text1", "text2", "radio1", "radio2", "check1", "check2", "hidden1", "hidden2", "name", "search", "button", "area1", "select1", "select2", "select3", "select4"] );
424424
t( "Form element :radio", "#form :radio", ["radio1", "radio2"] );
425425
t( "Form element :checkbox", "#form :checkbox", ["check1", "check2"] );
426426
t( "Form element :text", "#form :text:not(#search)", ["text1", "text2", "hidden2", "name"] );
427427
t( "Form element :radio:checked", "#form :radio:checked", ["radio2"] );
428428
t( "Form element :checkbox:checked", "#form :checkbox:checked", ["check1"] );
429429
t( "Form element :radio:checked, :checkbox:checked", "#form :radio:checked, #form :checkbox:checked", ["radio2", "check1"] );
430430

431-
t( "Selected Option Element", "#form option:selected", ["option1a","option2d","option3b","option3c"] );
431+
t( "Selected Option Element", "#form option:selected", ["option1a","option2d","option3b","option3c","option4b", "option4c", "option4d"] );
432432
});

test/unit/traversing.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ test("not(Selector)", function() {
152152
equals( jQuery("#main > p#ap > a").not("#google").length, 2, "not('selector')" );
153153
same( jQuery("p").not(".result").get(), q("firstp", "ap", "sndp", "en", "sap", "first"), "not('.class')" );
154154
same( jQuery("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" );
155-
same( jQuery("#form option").not("option.emptyopt:contains('Nothing'),[selected],[value='1']").get(), q("option1c", "option1d", "option2c", "option3d", "option3e" ), "not('complex selector')");
155+
same( jQuery("#form option").not("option.emptyopt:contains('Nothing'),[selected],[value='1']").get(), q("option1c", "option1d", "option2c", "option3d", "option3e", "option4e" ), "not('complex selector')");
156156

157157
same( jQuery('#ap *').not('code').get(), q("google", "groups", "anchor1", "mark"), "not('tag selector')" );
158158
same( jQuery('#ap *').not('code, #mark').get(), q("google", "groups", "anchor1"), "not('tag, ID selector')" );
@@ -163,7 +163,7 @@ test("not(Element)", function() {
163163
expect(1);
164164

165165
var selects = jQuery("#form select");
166-
same( selects.not( selects[1] ).get(), q("select1", "select3"), "filter out DOM element");
166+
same( selects.not( selects[1] ).get(), q("select1", "select3", "select4"), "filter out DOM element");
167167
});
168168

169169
test("not(Function)", function() {

0 commit comments

Comments
 (0)