@@ -57,7 +57,7 @@ $.widget( "ui.selectmenu", {
57
57
_drawButton : function ( ) {
58
58
var tabindex = this . element . attr ( "tabindex" ) ;
59
59
60
- // Fix existing label
60
+ // Associate existing label with the new button
61
61
this . label = $ ( "label[for='" + this . ids . element + "']" ) . attr ( "for" , this . ids . button ) ;
62
62
this . _on ( this . label , {
63
63
click : function ( event ) {
@@ -66,7 +66,7 @@ $.widget( "ui.selectmenu", {
66
66
}
67
67
} ) ;
68
68
69
- // Hide original select tag
69
+ // Hide original select element
70
70
this . element . hide ( ) ;
71
71
72
72
// Create button
@@ -101,7 +101,7 @@ $.widget( "ui.selectmenu", {
101
101
_drawMenu : function ( ) {
102
102
var that = this ;
103
103
104
- // Create menu portion, append to body
104
+ // Create menu
105
105
this . menu = $ ( "<ul>" , {
106
106
"aria-hidden" : "true" ,
107
107
"aria-labelledby" : this . ids . button ,
@@ -110,28 +110,24 @@ $.widget( "ui.selectmenu", {
110
110
111
111
// Wrap menu
112
112
this . menuWrap = $ ( "<div>" , {
113
- "class" : "ui-selectmenu-menu ui-front" ,
114
- outerWidth : this . button . outerWidth ( )
115
- } )
116
- . append ( this . menu )
117
- . appendTo ( this . _appendTo ( ) ) ;
113
+ "class" : "ui-selectmenu-menu ui-front" ,
114
+ outerWidth : this . button . outerWidth ( )
115
+ } )
116
+ . append ( this . menu )
117
+ . appendTo ( this . _appendTo ( ) ) ;
118
118
119
- // Init menu widget
119
+ // Initialize menu widget
120
120
this . menuInstance = this . menu . menu ( {
121
+ role : "listbox" ,
121
122
select : function ( event , ui ) {
122
123
var item = ui . item . data ( "ui-selectmenu-item" ) ;
123
124
124
125
that . _select ( item , event ) ;
125
-
126
- if ( that . isOpen ) {
127
- event . preventDefault ( ) ;
128
- that . close ( event ) ;
129
- }
130
126
} ,
131
127
focus : function ( event , ui ) {
132
128
var item = ui . item . data ( "ui-selectmenu-item" ) ;
133
129
134
- // prevent inital focus from firing and checks if its a newly focused item
130
+ // Prevent inital focus from firing and checks if its a newly focused item
135
131
if ( that . focusIndex != null && item . index !== that . focusIndex ) {
136
132
that . _trigger ( "focus" , event , { item : item } ) ;
137
133
if ( ! that . isOpen ) {
@@ -140,16 +136,18 @@ $.widget( "ui.selectmenu", {
140
136
}
141
137
that . focusIndex = item . index ;
142
138
143
- that . button . attr ( "aria-activedescendant" , that . menuItems . eq ( item . index ) . attr ( "id" ) ) ;
144
- } ,
145
- role : "listbox"
139
+ that . button . attr ( "aria-activedescendant" ,
140
+ that . menuItems . eq ( item . index ) . attr ( "id" ) ) ;
141
+ }
146
142
} )
147
143
. menu ( "instance" ) ;
148
144
149
- // adjust menu styles to dropdown
145
+ // Adjust menu styles to dropdown
150
146
this . menu . addClass ( "ui-corner-bottom" ) . removeClass ( "ui-corner-all" ) ;
151
147
152
- // Unbind uneeded Menu events
148
+ // TODO: Can we make this cleaner?
149
+ // If not, at least update the comment to say what we're removing
150
+ // Unbind uneeded menu events
153
151
this . menuInstance . _off ( this . menu , "mouseleave" ) ;
154
152
155
153
// Cancel the menu's collapseAll on document click
@@ -171,32 +169,34 @@ $.widget( "ui.selectmenu", {
171
169
this . _readOptions ( options ) ;
172
170
this . _renderMenu ( this . menu , this . items ) ;
173
171
174
- this . menu . menu ( " refresh" ) ;
172
+ this . menuInstance . refresh ( ) ;
175
173
this . menuItems = this . menu . find ( "li" ) . not ( ".ui-selectmenu-optgroup" ) . find ( "a" ) ;
176
174
177
175
item = this . _getSelectedItem ( ) ;
178
176
179
- // Make sure menu is selected item aware
180
- this . menu . menu ( " focus" , null , item ) ;
177
+ // Update the menu to have the correct item focused
178
+ this . menuInstance . focus ( null , item ) ;
181
179
this . _setAria ( item . data ( "ui-selectmenu-item" ) ) ;
182
180
183
181
this . _setText ( this . buttonText , item . text ( ) ) ;
184
182
185
183
// Set disabled state
186
- this . _setOption ( "disabled" , ! ! this . element . prop ( "disabled" ) ) ;
184
+ this . _setOption ( "disabled" , this . element . prop ( "disabled" ) ) ;
187
185
} ,
188
186
189
187
open : function ( event ) {
190
188
if ( this . options . disabled ) {
191
189
return ;
192
190
}
193
191
194
- // Support: IE6-IE9 click doesn't trigger focus on the button
192
+ // If this is the first time the menu is being opened, render the items
195
193
if ( ! this . menuItems ) {
196
194
this . refresh ( ) ;
197
195
} else {
196
+ // TODO: Why is this necessary?
197
+ // Shouldn't the underlying menu always have accurate state?
198
198
this . menu . find ( ".ui-state-focus" ) . removeClass ( "ui-state-focus" ) ;
199
- this . menu . menu ( " focus" , null , this . _getSelectedItem ( ) ) ;
199
+ this . menuInstance . focus ( null , this . _getSelectedItem ( ) ) ;
200
200
}
201
201
202
202
this . isOpen = true ;
@@ -245,9 +245,13 @@ $.widget( "ui.selectmenu", {
245
245
$ . each ( items , function ( index , item ) {
246
246
if ( item . optgroup !== currentOptgroup ) {
247
247
$ ( "<li>" , {
248
- "class" : "ui-selectmenu-optgroup" + ( item . element . parent ( "optgroup" ) . attr ( "disabled" ) ? " ui-state-disabled" : "" ) ,
248
+ "class" : "ui-selectmenu-optgroup" +
249
+ ( item . element . parent ( "optgroup" ) . attr ( "disabled" ) ?
250
+ " ui-state-disabled" :
251
+ "" ) ,
249
252
text : item . optgroup
250
- } ) . appendTo ( ul ) ;
253
+ } )
254
+ . appendTo ( ul ) ;
251
255
currentOptgroup = item . optgroup ;
252
256
}
253
257
that . _renderItemData ( ul , item ) ;
@@ -283,7 +287,8 @@ $.widget( "ui.selectmenu", {
283
287
// Set focus manually for first or last item
284
288
this . menu . menu ( "focus" , event , this . menuItems [ direction ] ( ) ) ;
285
289
} else {
286
- if ( direction === "previous" && this . menu . menu ( "isFirstItem" ) || direction === "next" && this . menu . menu ( "isLastItem" ) ) {
290
+ if ( direction === "previous" && this . menu . menu ( "isFirstItem" ) ||
291
+ direction === "next" && this . menu . menu ( "isLastItem" ) ) {
287
292
return ;
288
293
}
289
294
@@ -313,30 +318,25 @@ $.widget( "ui.selectmenu", {
313
318
} ,
314
319
315
320
_buttonEvents : {
316
- focus : function ( ) {
317
- // Init Menu on first focus
318
- this . refresh ( ) ;
319
- // Reset focus class as its removed by ui.widget._setOption
320
- this . button . addClass ( "ui-state-focus" ) ;
321
- this . _off ( this . button , "focus" ) ;
322
- } ,
323
- click : function ( event ) {
324
- this . _toggle ( event ) ;
325
- event . preventDefault ( ) ;
321
+ focusin : function ( ) {
322
+ // Delay rendering the menu items until the button receives focus
323
+ if ( ! this . menuItems ) {
324
+ this . refresh ( ) ;
325
+ }
326
+ this . _off ( this . button , "focusin" ) ;
326
327
} ,
328
+ click : "_toggle" ,
327
329
keydown : function ( event ) {
328
- var prevDef = true ;
330
+ var preventDefault = true ;
329
331
switch ( event . keyCode ) {
330
332
case $ . ui . keyCode . TAB :
331
333
case $ . ui . keyCode . ESCAPE :
332
- if ( this . isOpen ) {
333
- this . close ( event ) ;
334
- }
335
- prevDef = false ;
334
+ this . close ( event ) ;
335
+ preventDefault = false ;
336
336
break ;
337
337
case $ . ui . keyCode . ENTER :
338
338
if ( this . isOpen ) {
339
- this . menu . menu ( " select" , event ) ;
339
+ this . menuInstance . select ( event ) ;
340
340
}
341
341
break ;
342
342
case $ . ui . keyCode . UP :
@@ -355,7 +355,7 @@ $.widget( "ui.selectmenu", {
355
355
break ;
356
356
case $ . ui . keyCode . SPACE :
357
357
if ( this . isOpen ) {
358
- this . menu . menu ( " select" , event ) ;
358
+ this . menuInstance . select ( event ) ;
359
359
} else {
360
360
this . _toggle ( event ) ;
361
361
}
@@ -376,16 +376,18 @@ $.widget( "ui.selectmenu", {
376
376
break ;
377
377
default :
378
378
this . menu . trigger ( event ) ;
379
- prevDef = false ;
379
+ preventDefault = false ;
380
380
}
381
- if ( prevDef ) {
381
+
382
+ if ( preventDefault ) {
382
383
event . preventDefault ( ) ;
383
384
}
384
385
}
385
386
} ,
386
387
387
388
_select : function ( item , event ) {
388
389
var oldIndex = this . element [ 0 ] . selectedIndex ;
390
+
389
391
// Change native select element
390
392
this . element [ 0 ] . selectedIndex = item . index ;
391
393
this . _setText ( this . buttonText , item . label ) ;
@@ -395,6 +397,8 @@ $.widget( "ui.selectmenu", {
395
397
if ( item . index !== oldIndex ) {
396
398
this . _trigger ( "change" , event , { item : item } ) ;
397
399
}
400
+
401
+ this . close ( event ) ;
398
402
} ,
399
403
400
404
_setAria : function ( item ) {
@@ -421,17 +425,16 @@ $.widget( "ui.selectmenu", {
421
425
this . menuWrap . appendTo ( this . _appendTo ( ) ) ;
422
426
}
423
427
if ( key === "disabled" ) {
424
- this . menu . menu ( " option" , "disabled" , value ) ;
428
+ this . menuInstance . option ( "disabled" , value ) ;
425
429
this . button
426
- . toggleClass ( "ui-state-disabled" , ! ! value )
430
+ . toggleClass ( "ui-state-disabled" , value )
427
431
. attr ( "aria-disabled" , value ) ;
428
432
433
+ this . element . prop ( "disabled" , value ) ;
429
434
if ( value ) {
430
- this . element . attr ( "disabled" , "disabled" ) ;
431
435
this . button . attr ( "tabindex" , - 1 ) ;
432
436
this . close ( ) ;
433
437
} else {
434
- this . element . removeAttr ( "disabled" ) ;
435
438
this . button . attr ( "tabindex" , 0 ) ;
436
439
}
437
440
}
@@ -458,14 +461,16 @@ $.widget( "ui.selectmenu", {
458
461
} ,
459
462
460
463
_toggleAttr : function ( ) {
461
- this . button . toggleClass ( "ui-corner-top" , this . isOpen ) . toggleClass ( "ui-corner-all" , ! this . isOpen ) ;
464
+ this . button
465
+ . toggleClass ( "ui-corner-top" , this . isOpen )
466
+ . toggleClass ( "ui-corner-all" , ! this . isOpen ) ;
462
467
this . menuWrap . toggleClass ( "ui-selectmenu-open" , this . isOpen ) ;
463
- this . menu . attr ( "aria-hidden" , ! this . isOpen ) ;
464
- this . button . attr ( "aria-expanded" , this . isOpen ) ;
468
+ this . menu . attr ( "aria-hidden" , ! this . isOpen ) ;
469
+ this . button . attr ( "aria-expanded" , this . isOpen ) ;
465
470
} ,
466
471
467
472
_getCreateOptions : function ( ) {
468
- return { disabled : ! ! this . element . prop ( "disabled" ) } ;
473
+ return { disabled : this . element . prop ( "disabled" ) } ;
469
474
} ,
470
475
471
476
_readOptions : function ( options ) {
0 commit comments