Selectmenu: Fix selecting options following hidden ones

Change a2b25ef6ca made options with
the `hidden` attribute skipped when rendering. However, that makes
indexes misaligned with native options as hidden ones maintain their
index values. Instead, don't skip hidden options but add the `hidden`
attribute to the respective jQuery UI elements as well.

Fixes gh-2082
Closes gh-2144
Ref a2b25ef6ca
This commit is contained in:
Michał Gołębiowski-Owczarek 2023-05-10 10:55:01 +02:00 committed by GitHub
parent beeb410ccb
commit 020828e7ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 8 deletions

View File

@ -394,16 +394,75 @@ QUnit.test( "Options with hidden attribute should not be rendered", function( as
setTimeout( function() { setTimeout( function() {
button.trigger( "click" ); button.trigger( "click" );
options = menu.children() options = menu.children()
.map( function() { .get()
return $( this ).text(); .filter( function( item ) {
return $( item ).is( ":visible" );
} ) } )
.get(); .map( function( item ) {
return $( item ).text();
} );
assert.deepEqual( options, [ "Slower", "Medium", "Fast", "Faster" ], "correct elements" ); assert.deepEqual( options, [ "Slower", "Medium", "Fast", "Faster" ], "correct elements" );
ready(); ready();
} ); } );
} ); } );
QUnit.test( "Options with hidden attribute should not break the widget (gh-2082)",
function( assert ) {
var ready = assert.async();
assert.expect( 1 );
var button;
var element = $( "#speed" );
element.find( "option" ).slice( 0, 2 ).prop( "hidden", true );
element.val( "Faster" );
element.selectmenu();
button = element.selectmenu( "widget" );
button.simulate( "focus" );
setTimeout( function() {
try {
button.trigger( "click" );
assert.strictEqual( button.text(), "Faster", "Selected value is correct" );
} catch ( e ) {
assert.ok( false, "Clicking on the select box crashed" );
}
ready();
} );
} );
QUnit.test( "Optgroups with hidden attribute should not break the widget (gh-2082)",
function( assert ) {
var ready = assert.async();
assert.expect( 1 );
var button;
var element = $( "#files" );
element.find( "optgroup" ).first().prop( "hidden", true );
element
.find( "optgroup" ).eq( 1 )
.find( "option" ).first()
.prop( "hidden", true );
element.val( "someotherfile" );
element.selectmenu();
button = element.selectmenu( "widget" );
button.simulate( "focus" );
setTimeout( function() {
try {
button.trigger( "click" );
assert.strictEqual( button.text(), "Some other file", "Selected option is correct" );
} catch ( e ) {
assert.ok( false, "Clicking on the select box crashed" );
}
ready();
} );
} );
QUnit.test( "extra listeners created after selection (trac-15078, trac-15152)", function( assert ) { QUnit.test( "extra listeners created after selection (trac-15078, trac-15152)", function( assert ) {
assert.expect( 3 ); assert.expect( 3 );

View File

@ -354,7 +354,12 @@ return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
if ( item.disabled ) { if ( item.disabled ) {
this._addClass( li, null, "ui-state-disabled" ); this._addClass( li, null, "ui-state-disabled" );
} }
if ( item.hidden ) {
li.prop( "hidden", true );
} else {
this._setText( wrapper, item.label ); this._setText( wrapper, item.label );
}
return li.append( wrapper ).appendTo( ul ); return li.append( wrapper ).appendTo( ul );
}, },
@ -658,10 +663,6 @@ return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
var that = this, var that = this,
data = []; data = [];
options.each( function( index, item ) { options.each( function( index, item ) {
if ( item.hidden ) {
return;
}
data.push( that._parseOption( $( item ), index ) ); data.push( that._parseOption( $( item ), index ) );
} ); } );
this.items = data; this.items = data;
@ -675,6 +676,7 @@ return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
index: index, index: index,
value: option.val(), value: option.val(),
label: option.text(), label: option.text(),
hidden: optgroup.prop( "hidden" ) || option.prop( "hidden" ),
optgroup: optgroup.attr( "label" ) || "", optgroup: optgroup.attr( "label" ) || "",
disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
}; };