1
|
|
|
/*! |
2
|
|
|
* jQuery UI Selectmenu 1.12.1 |
3
|
|
|
* http://jqueryui.com |
4
|
|
|
* |
5
|
|
|
* Copyright jQuery Foundation and other contributors |
6
|
|
|
* Released under the MIT license. |
7
|
|
|
* http://jquery.org/license |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
//>>label: Selectmenu |
11
|
|
|
//>>group: Widgets |
12
|
|
|
// jscs:disable maximumLineLength |
13
|
|
|
//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select. |
14
|
|
|
// jscs:enable maximumLineLength |
15
|
|
|
//>>docs: http://api.jqueryui.com/selectmenu/ |
16
|
|
|
//>>demos: http://jqueryui.com/selectmenu/ |
17
|
|
|
//>>css.structure: ../../themes/base/core.css |
18
|
|
|
//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css |
19
|
|
|
//>>css.theme: ../../themes/base/theme.css |
20
|
|
|
|
21
|
|
|
( function( factory ) { |
22
|
|
|
if ( typeof define === "function" && define.amd ) { |
23
|
|
|
|
24
|
|
|
// AMD. Register as an anonymous module. |
25
|
|
|
define( [ |
26
|
|
|
"jquery", |
27
|
|
|
"./menu", |
28
|
|
|
"../escape-selector", |
29
|
|
|
"../form-reset-mixin", |
30
|
|
|
"../keycode", |
31
|
|
|
"../labels", |
32
|
|
|
"../position", |
33
|
|
|
"../unique-id", |
34
|
|
|
"../version", |
35
|
|
|
"../widget" |
36
|
|
|
], factory ); |
37
|
|
|
} else { |
38
|
|
|
|
39
|
|
|
// Browser globals |
40
|
|
|
factory( jQuery ); |
41
|
|
|
} |
42
|
|
|
}( function( $ ) { |
43
|
|
|
|
44
|
|
|
return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { |
45
|
|
|
version: "1.12.1", |
46
|
|
|
defaultElement: "<select>", |
47
|
|
|
options: { |
48
|
|
|
appendTo: null, |
49
|
|
|
classes: { |
50
|
|
|
"ui-selectmenu-button-open": "ui-corner-top", |
51
|
|
|
"ui-selectmenu-button-closed": "ui-corner-all" |
52
|
|
|
}, |
53
|
|
|
disabled: null, |
54
|
|
|
icons: { |
55
|
|
|
button: "ui-icon-triangle-1-s" |
56
|
|
|
}, |
57
|
|
|
position: { |
58
|
|
|
my: "left top", |
59
|
|
|
at: "left bottom", |
60
|
|
|
collision: "none" |
61
|
|
|
}, |
62
|
|
|
width: false, |
63
|
|
|
|
64
|
|
|
// Callbacks |
65
|
|
|
change: null, |
66
|
|
|
close: null, |
67
|
|
|
focus: null, |
68
|
|
|
open: null, |
69
|
|
|
select: null |
70
|
|
|
}, |
71
|
|
|
|
72
|
|
|
_create: function() { |
73
|
|
|
var selectmenuId = this.element.uniqueId().attr( "id" ); |
74
|
|
|
this.ids = { |
75
|
|
|
element: selectmenuId, |
76
|
|
|
button: selectmenuId + "-button", |
77
|
|
|
menu: selectmenuId + "-menu" |
78
|
|
|
}; |
79
|
|
|
|
80
|
|
|
this._drawButton(); |
81
|
|
|
this._drawMenu(); |
82
|
|
|
this._bindFormResetHandler(); |
83
|
|
|
|
84
|
|
|
this._rendered = false; |
85
|
|
|
this.menuItems = $(); |
86
|
|
|
}, |
87
|
|
|
|
88
|
|
|
_drawButton: function() { |
89
|
|
|
var icon, |
90
|
|
|
that = this, |
91
|
|
|
item = this._parseOption( |
92
|
|
|
this.element.find( "option:selected" ), |
93
|
|
|
this.element[ 0 ].selectedIndex |
94
|
|
|
); |
95
|
|
|
|
96
|
|
|
// Associate existing label with the new button |
97
|
|
|
this.labels = this.element.labels().attr( "for", this.ids.button ); |
98
|
|
|
this._on( this.labels, { |
99
|
|
|
click: function( event ) { |
100
|
|
|
this.button.focus(); |
101
|
|
|
event.preventDefault(); |
102
|
|
|
} |
103
|
|
|
} ); |
104
|
|
|
|
105
|
|
|
// Hide original select element |
106
|
|
|
this.element.hide(); |
107
|
|
|
|
108
|
|
|
// Create button |
109
|
|
|
this.button = $( "<span>", { |
110
|
|
|
tabindex: this.options.disabled ? -1 : 0, |
111
|
|
|
id: this.ids.button, |
112
|
|
|
role: "combobox", |
113
|
|
|
"aria-expanded": "false", |
114
|
|
|
"aria-autocomplete": "list", |
115
|
|
|
"aria-owns": this.ids.menu, |
116
|
|
|
"aria-haspopup": "true", |
117
|
|
|
title: this.element.attr( "title" ) |
118
|
|
|
} ) |
119
|
|
|
.insertAfter( this.element ); |
120
|
|
|
|
121
|
|
|
this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", |
122
|
|
|
"ui-button ui-widget" ); |
123
|
|
|
|
124
|
|
|
icon = $( "<span>" ).appendTo( this.button ); |
125
|
|
|
this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); |
126
|
|
|
this.buttonItem = this._renderButtonItem( item ) |
127
|
|
|
.appendTo( this.button ); |
128
|
|
|
|
129
|
|
|
if ( this.options.width !== false ) { |
130
|
|
|
this._resizeButton(); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
this._on( this.button, this._buttonEvents ); |
134
|
|
|
this.button.one( "focusin", function() { |
135
|
|
|
|
136
|
|
|
// Delay rendering the menu items until the button receives focus. |
137
|
|
|
// The menu may have already been rendered via a programmatic open. |
138
|
|
|
if ( !that._rendered ) { |
139
|
|
|
that._refreshMenu(); |
140
|
|
|
} |
141
|
|
|
} ); |
142
|
|
|
}, |
143
|
|
|
|
144
|
|
|
_drawMenu: function() { |
145
|
|
|
var that = this; |
146
|
|
|
|
147
|
|
|
// Create menu |
148
|
|
|
this.menu = $( "<ul>", { |
149
|
|
|
"aria-hidden": "true", |
150
|
|
|
"aria-labelledby": this.ids.button, |
151
|
|
|
id: this.ids.menu |
152
|
|
|
} ); |
153
|
|
|
|
154
|
|
|
// Wrap menu |
155
|
|
|
this.menuWrap = $( "<div>" ).append( this.menu ); |
156
|
|
|
this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); |
157
|
|
|
this.menuWrap.appendTo( this._appendTo() ); |
158
|
|
|
|
159
|
|
|
// Initialize menu widget |
160
|
|
|
this.menuInstance = this.menu |
161
|
|
|
.menu( { |
162
|
|
|
classes: { |
163
|
|
|
"ui-menu": "ui-corner-bottom" |
164
|
|
|
}, |
165
|
|
|
role: "listbox", |
166
|
|
|
select: function( event, ui ) { |
167
|
|
|
event.preventDefault(); |
168
|
|
|
|
169
|
|
|
// Support: IE8 |
170
|
|
|
// If the item was selected via a click, the text selection |
171
|
|
|
// will be destroyed in IE |
172
|
|
|
that._setSelection(); |
173
|
|
|
|
174
|
|
|
that._select( ui.item.data( "ui-selectmenu-item" ), event ); |
175
|
|
|
}, |
176
|
|
|
focus: function( event, ui ) { |
177
|
|
|
var item = ui.item.data( "ui-selectmenu-item" ); |
178
|
|
|
|
179
|
|
|
// Prevent inital focus from firing and check if its a newly focused item |
180
|
|
|
if ( that.focusIndex != null && item.index !== that.focusIndex ) { |
181
|
|
|
that._trigger( "focus", event, { item: item } ); |
182
|
|
|
if ( !that.isOpen ) { |
183
|
|
|
that._select( item, event ); |
184
|
|
|
} |
185
|
|
|
} |
186
|
|
|
that.focusIndex = item.index; |
187
|
|
|
|
188
|
|
|
that.button.attr( "aria-activedescendant", |
189
|
|
|
that.menuItems.eq( item.index ).attr( "id" ) ); |
190
|
|
|
} |
191
|
|
|
} ) |
192
|
|
|
.menu( "instance" ); |
193
|
|
|
|
194
|
|
|
// Don't close the menu on mouseleave |
195
|
|
|
this.menuInstance._off( this.menu, "mouseleave" ); |
196
|
|
|
|
197
|
|
|
// Cancel the menu's collapseAll on document click |
198
|
|
|
this.menuInstance._closeOnDocumentClick = function() { |
199
|
|
|
return false; |
200
|
|
|
}; |
201
|
|
|
|
202
|
|
|
// Selects often contain empty items, but never contain dividers |
203
|
|
|
this.menuInstance._isDivider = function() { |
204
|
|
|
return false; |
205
|
|
|
}; |
206
|
|
|
}, |
207
|
|
|
|
208
|
|
|
refresh: function() { |
209
|
|
|
this._refreshMenu(); |
210
|
|
|
this.buttonItem.replaceWith( |
211
|
|
|
this.buttonItem = this._renderButtonItem( |
212
|
|
|
|
213
|
|
|
// Fall back to an empty object in case there are no options |
214
|
|
|
this._getSelectedItem().data( "ui-selectmenu-item" ) || {} |
215
|
|
|
) |
216
|
|
|
); |
217
|
|
|
if ( this.options.width === null ) { |
218
|
|
|
this._resizeButton(); |
219
|
|
|
} |
220
|
|
|
}, |
221
|
|
|
|
222
|
|
|
_refreshMenu: function() { |
223
|
|
|
var item, |
224
|
|
|
options = this.element.find( "option" ); |
225
|
|
|
|
226
|
|
|
this.menu.empty(); |
227
|
|
|
|
228
|
|
|
this._parseOptions( options ); |
229
|
|
|
this._renderMenu( this.menu, this.items ); |
230
|
|
|
|
231
|
|
|
this.menuInstance.refresh(); |
232
|
|
|
this.menuItems = this.menu.find( "li" ) |
233
|
|
|
.not( ".ui-selectmenu-optgroup" ) |
234
|
|
|
.find( ".ui-menu-item-wrapper" ); |
235
|
|
|
|
236
|
|
|
this._rendered = true; |
237
|
|
|
|
238
|
|
|
if ( !options.length ) { |
239
|
|
|
return; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
item = this._getSelectedItem(); |
243
|
|
|
|
244
|
|
|
// Update the menu to have the correct item focused |
245
|
|
|
this.menuInstance.focus( null, item ); |
246
|
|
|
this._setAria( item.data( "ui-selectmenu-item" ) ); |
247
|
|
|
|
248
|
|
|
// Set disabled state |
249
|
|
|
this._setOption( "disabled", this.element.prop( "disabled" ) ); |
250
|
|
|
}, |
251
|
|
|
|
252
|
|
|
open: function( event ) { |
253
|
|
|
if ( this.options.disabled ) { |
254
|
|
|
return; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
// If this is the first time the menu is being opened, render the items |
258
|
|
|
if ( !this._rendered ) { |
259
|
|
|
this._refreshMenu(); |
260
|
|
|
} else { |
261
|
|
|
|
262
|
|
|
// Menu clears focus on close, reset focus to selected item |
263
|
|
|
this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); |
264
|
|
|
this.menuInstance.focus( null, this._getSelectedItem() ); |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
// If there are no options, don't open the menu |
268
|
|
|
if ( !this.menuItems.length ) { |
269
|
|
|
return; |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
this.isOpen = true; |
273
|
|
|
this._toggleAttr(); |
274
|
|
|
this._resizeMenu(); |
275
|
|
|
this._position(); |
276
|
|
|
|
277
|
|
|
this._on( this.document, this._documentClick ); |
278
|
|
|
|
279
|
|
|
this._trigger( "open", event ); |
280
|
|
|
}, |
281
|
|
|
|
282
|
|
|
_position: function() { |
283
|
|
|
this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); |
284
|
|
|
}, |
285
|
|
|
|
286
|
|
|
close: function( event ) { |
287
|
|
|
if ( !this.isOpen ) { |
288
|
|
|
return; |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
this.isOpen = false; |
292
|
|
|
this._toggleAttr(); |
293
|
|
|
|
294
|
|
|
this.range = null; |
295
|
|
|
this._off( this.document ); |
296
|
|
|
|
297
|
|
|
this._trigger( "close", event ); |
298
|
|
|
}, |
299
|
|
|
|
300
|
|
|
widget: function() { |
301
|
|
|
return this.button; |
302
|
|
|
}, |
303
|
|
|
|
304
|
|
|
menuWidget: function() { |
305
|
|
|
return this.menu; |
306
|
|
|
}, |
307
|
|
|
|
308
|
|
|
_renderButtonItem: function( item ) { |
309
|
|
|
var buttonItem = $( "<span>" ); |
310
|
|
|
|
311
|
|
|
this._setText( buttonItem, item.label ); |
312
|
|
|
this._addClass( buttonItem, "ui-selectmenu-text" ); |
313
|
|
|
|
314
|
|
|
return buttonItem; |
315
|
|
|
}, |
316
|
|
|
|
317
|
|
|
_renderMenu: function( ul, items ) { |
318
|
|
|
var that = this, |
319
|
|
|
currentOptgroup = ""; |
320
|
|
|
|
321
|
|
|
$.each( items, function( index, item ) { |
322
|
|
|
var li; |
323
|
|
|
|
324
|
|
|
if ( item.optgroup !== currentOptgroup ) { |
325
|
|
|
li = $( "<li>", { |
326
|
|
|
text: item.optgroup |
327
|
|
|
} ); |
328
|
|
|
that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + |
329
|
|
|
( item.element.parent( "optgroup" ).prop( "disabled" ) ? |
330
|
|
|
" ui-state-disabled" : |
331
|
|
|
"" ) ); |
332
|
|
|
|
333
|
|
|
li.appendTo( ul ); |
334
|
|
|
|
335
|
|
|
currentOptgroup = item.optgroup; |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
that._renderItemData( ul, item ); |
339
|
|
|
} ); |
340
|
|
|
}, |
341
|
|
|
|
342
|
|
|
_renderItemData: function( ul, item ) { |
343
|
|
|
return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); |
344
|
|
|
}, |
345
|
|
|
|
346
|
|
|
_renderItem: function( ul, item ) { |
347
|
|
|
var li = $( "<li>" ), |
348
|
|
|
wrapper = $( "<div>", { |
349
|
|
|
title: item.element.attr( "title" ) |
350
|
|
|
} ); |
351
|
|
|
|
352
|
|
|
if ( item.disabled ) { |
353
|
|
|
this._addClass( li, null, "ui-state-disabled" ); |
354
|
|
|
} |
355
|
|
|
this._setText( wrapper, item.label ); |
356
|
|
|
|
357
|
|
|
return li.append( wrapper ).appendTo( ul ); |
358
|
|
|
}, |
359
|
|
|
|
360
|
|
|
_setText: function( element, value ) { |
361
|
|
|
if ( value ) { |
362
|
|
|
element.text( value ); |
363
|
|
|
} else { |
364
|
|
|
element.html( " " ); |
365
|
|
|
} |
366
|
|
|
}, |
367
|
|
|
|
368
|
|
|
_move: function( direction, event ) { |
369
|
|
|
var item, next, |
370
|
|
|
filter = ".ui-menu-item"; |
371
|
|
|
|
372
|
|
|
if ( this.isOpen ) { |
373
|
|
|
item = this.menuItems.eq( this.focusIndex ).parent( "li" ); |
374
|
|
|
} else { |
375
|
|
|
item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); |
376
|
|
|
filter += ":not(.ui-state-disabled)"; |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
if ( direction === "first" || direction === "last" ) { |
380
|
|
|
next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); |
381
|
|
|
} else { |
382
|
|
|
next = item[ direction + "All" ]( filter ).eq( 0 ); |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
if ( next.length ) { |
386
|
|
|
this.menuInstance.focus( event, next ); |
387
|
|
|
} |
388
|
|
|
}, |
389
|
|
|
|
390
|
|
|
_getSelectedItem: function() { |
391
|
|
|
return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); |
392
|
|
|
}, |
393
|
|
|
|
394
|
|
|
_toggle: function( event ) { |
395
|
|
|
this[ this.isOpen ? "close" : "open" ]( event ); |
396
|
|
|
}, |
397
|
|
|
|
398
|
|
|
_setSelection: function() { |
399
|
|
|
var selection; |
400
|
|
|
|
401
|
|
|
if ( !this.range ) { |
402
|
|
|
return; |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
if ( window.getSelection ) { |
406
|
|
|
selection = window.getSelection(); |
407
|
|
|
selection.removeAllRanges(); |
408
|
|
|
selection.addRange( this.range ); |
409
|
|
|
|
410
|
|
|
// Support: IE8 |
411
|
|
|
} else { |
412
|
|
|
this.range.select(); |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
// Support: IE |
416
|
|
|
// Setting the text selection kills the button focus in IE, but |
417
|
|
|
// restoring the focus doesn't kill the selection. |
418
|
|
|
this.button.focus(); |
419
|
|
|
}, |
420
|
|
|
|
421
|
|
|
_documentClick: { |
422
|
|
|
mousedown: function( event ) { |
423
|
|
|
if ( !this.isOpen ) { |
424
|
|
|
return; |
425
|
|
|
} |
426
|
|
|
|
427
|
|
|
if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + |
428
|
|
|
$.ui.escapeSelector( this.ids.button ) ).length ) { |
429
|
|
|
this.close( event ); |
430
|
|
|
} |
431
|
|
|
} |
432
|
|
|
}, |
433
|
|
|
|
434
|
|
|
_buttonEvents: { |
435
|
|
|
|
436
|
|
|
// Prevent text selection from being reset when interacting with the selectmenu (#10144) |
437
|
|
|
mousedown: function() { |
438
|
|
|
var selection; |
439
|
|
|
|
440
|
|
|
if ( window.getSelection ) { |
441
|
|
|
selection = window.getSelection(); |
442
|
|
|
if ( selection.rangeCount ) { |
443
|
|
|
this.range = selection.getRangeAt( 0 ); |
444
|
|
|
} |
445
|
|
|
|
446
|
|
|
// Support: IE8 |
447
|
|
|
} else { |
448
|
|
|
this.range = document.selection.createRange(); |
449
|
|
|
} |
450
|
|
|
}, |
451
|
|
|
|
452
|
|
|
click: function( event ) { |
453
|
|
|
this._setSelection(); |
454
|
|
|
this._toggle( event ); |
455
|
|
|
}, |
456
|
|
|
|
457
|
|
|
keydown: function( event ) { |
458
|
|
|
var preventDefault = true; |
459
|
|
|
switch ( event.keyCode ) { |
460
|
|
|
case $.ui.keyCode.TAB: |
461
|
|
|
case $.ui.keyCode.ESCAPE: |
462
|
|
|
this.close( event ); |
463
|
|
|
preventDefault = false; |
464
|
|
|
break; |
465
|
|
|
case $.ui.keyCode.ENTER: |
466
|
|
|
if ( this.isOpen ) { |
467
|
|
|
this._selectFocusedItem( event ); |
468
|
|
|
} |
469
|
|
|
break; |
470
|
|
|
case $.ui.keyCode.UP: |
471
|
|
|
if ( event.altKey ) { |
472
|
|
|
this._toggle( event ); |
473
|
|
|
} else { |
474
|
|
|
this._move( "prev", event ); |
475
|
|
|
} |
476
|
|
|
break; |
477
|
|
|
case $.ui.keyCode.DOWN: |
478
|
|
|
if ( event.altKey ) { |
479
|
|
|
this._toggle( event ); |
480
|
|
|
} else { |
481
|
|
|
this._move( "next", event ); |
482
|
|
|
} |
483
|
|
|
break; |
484
|
|
|
case $.ui.keyCode.SPACE: |
485
|
|
|
if ( this.isOpen ) { |
486
|
|
|
this._selectFocusedItem( event ); |
487
|
|
|
} else { |
488
|
|
|
this._toggle( event ); |
489
|
|
|
} |
490
|
|
|
break; |
491
|
|
|
case $.ui.keyCode.LEFT: |
492
|
|
|
this._move( "prev", event ); |
493
|
|
|
break; |
494
|
|
|
case $.ui.keyCode.RIGHT: |
495
|
|
|
this._move( "next", event ); |
496
|
|
|
break; |
497
|
|
|
case $.ui.keyCode.HOME: |
498
|
|
|
case $.ui.keyCode.PAGE_UP: |
499
|
|
|
this._move( "first", event ); |
500
|
|
|
break; |
501
|
|
|
case $.ui.keyCode.END: |
502
|
|
|
case $.ui.keyCode.PAGE_DOWN: |
503
|
|
|
this._move( "last", event ); |
504
|
|
|
break; |
505
|
|
|
default: |
506
|
|
|
this.menu.trigger( event ); |
507
|
|
|
preventDefault = false; |
508
|
|
|
} |
509
|
|
|
|
510
|
|
|
if ( preventDefault ) { |
511
|
|
|
event.preventDefault(); |
512
|
|
|
} |
513
|
|
|
} |
514
|
|
|
}, |
515
|
|
|
|
516
|
|
|
_selectFocusedItem: function( event ) { |
517
|
|
|
var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); |
518
|
|
|
if ( !item.hasClass( "ui-state-disabled" ) ) { |
519
|
|
|
this._select( item.data( "ui-selectmenu-item" ), event ); |
520
|
|
|
} |
521
|
|
|
}, |
522
|
|
|
|
523
|
|
|
_select: function( item, event ) { |
524
|
|
|
var oldIndex = this.element[ 0 ].selectedIndex; |
525
|
|
|
|
526
|
|
|
// Change native select element |
527
|
|
|
this.element[ 0 ].selectedIndex = item.index; |
528
|
|
|
this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); |
529
|
|
|
this._setAria( item ); |
530
|
|
|
this._trigger( "select", event, { item: item } ); |
531
|
|
|
|
532
|
|
|
if ( item.index !== oldIndex ) { |
533
|
|
|
this._trigger( "change", event, { item: item } ); |
534
|
|
|
} |
535
|
|
|
|
536
|
|
|
this.close( event ); |
537
|
|
|
}, |
538
|
|
|
|
539
|
|
|
_setAria: function( item ) { |
540
|
|
|
var id = this.menuItems.eq( item.index ).attr( "id" ); |
541
|
|
|
|
542
|
|
|
this.button.attr( { |
543
|
|
|
"aria-labelledby": id, |
544
|
|
|
"aria-activedescendant": id |
545
|
|
|
} ); |
546
|
|
|
this.menu.attr( "aria-activedescendant", id ); |
547
|
|
|
}, |
548
|
|
|
|
549
|
|
|
_setOption: function( key, value ) { |
550
|
|
|
if ( key === "icons" ) { |
551
|
|
|
var icon = this.button.find( "span.ui-icon" ); |
552
|
|
|
this._removeClass( icon, null, this.options.icons.button ) |
553
|
|
|
._addClass( icon, null, value.button ); |
554
|
|
|
} |
555
|
|
|
|
556
|
|
|
this._super( key, value ); |
557
|
|
|
|
558
|
|
|
if ( key === "appendTo" ) { |
559
|
|
|
this.menuWrap.appendTo( this._appendTo() ); |
560
|
|
|
} |
561
|
|
|
|
562
|
|
|
if ( key === "width" ) { |
563
|
|
|
this._resizeButton(); |
564
|
|
|
} |
565
|
|
|
}, |
566
|
|
|
|
567
|
|
|
_setOptionDisabled: function( value ) { |
568
|
|
|
this._super( value ); |
569
|
|
|
|
570
|
|
|
this.menuInstance.option( "disabled", value ); |
571
|
|
|
this.button.attr( "aria-disabled", value ); |
572
|
|
|
this._toggleClass( this.button, null, "ui-state-disabled", value ); |
573
|
|
|
|
574
|
|
|
this.element.prop( "disabled", value ); |
575
|
|
|
if ( value ) { |
576
|
|
|
this.button.attr( "tabindex", -1 ); |
577
|
|
|
this.close(); |
578
|
|
|
} else { |
579
|
|
|
this.button.attr( "tabindex", 0 ); |
580
|
|
|
} |
581
|
|
|
}, |
582
|
|
|
|
583
|
|
|
_appendTo: function() { |
584
|
|
|
var element = this.options.appendTo; |
585
|
|
|
|
586
|
|
|
if ( element ) { |
587
|
|
|
element = element.jquery || element.nodeType ? |
588
|
|
|
$( element ) : |
589
|
|
|
this.document.find( element ).eq( 0 ); |
590
|
|
|
} |
591
|
|
|
|
592
|
|
|
if ( !element || !element[ 0 ] ) { |
593
|
|
|
element = this.element.closest( ".ui-front, dialog" ); |
594
|
|
|
} |
595
|
|
|
|
596
|
|
|
if ( !element.length ) { |
597
|
|
|
element = this.document[ 0 ].body; |
598
|
|
|
} |
599
|
|
|
|
600
|
|
|
return element; |
601
|
|
|
}, |
602
|
|
|
|
603
|
|
|
_toggleAttr: function() { |
604
|
|
|
this.button.attr( "aria-expanded", this.isOpen ); |
605
|
|
|
|
606
|
|
|
// We can't use two _toggleClass() calls here, because we need to make sure |
607
|
|
|
// we always remove classes first and add them second, otherwise if both classes have the |
608
|
|
|
// same theme class, it will be removed after we add it. |
609
|
|
|
this._removeClass( this.button, "ui-selectmenu-button-" + |
610
|
|
|
( this.isOpen ? "closed" : "open" ) ) |
611
|
|
|
._addClass( this.button, "ui-selectmenu-button-" + |
612
|
|
|
( this.isOpen ? "open" : "closed" ) ) |
613
|
|
|
._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); |
614
|
|
|
|
615
|
|
|
this.menu.attr( "aria-hidden", !this.isOpen ); |
616
|
|
|
}, |
617
|
|
|
|
618
|
|
|
_resizeButton: function() { |
619
|
|
|
var width = this.options.width; |
620
|
|
|
|
621
|
|
|
// For `width: false`, just remove inline style and stop |
622
|
|
|
if ( width === false ) { |
623
|
|
|
this.button.css( "width", "" ); |
624
|
|
|
return; |
625
|
|
|
} |
626
|
|
|
|
627
|
|
|
// For `width: null`, match the width of the original element |
628
|
|
|
if ( width === null ) { |
629
|
|
|
width = this.element.show().outerWidth(); |
630
|
|
|
this.element.hide(); |
631
|
|
|
} |
632
|
|
|
|
633
|
|
|
this.button.outerWidth( width ); |
634
|
|
|
}, |
635
|
|
|
|
636
|
|
|
_resizeMenu: function() { |
637
|
|
|
this.menu.outerWidth( Math.max( |
638
|
|
|
this.button.outerWidth(), |
639
|
|
|
|
640
|
|
|
// Support: IE10 |
641
|
|
|
// IE10 wraps long text (possibly a rounding bug) |
642
|
|
|
// so we add 1px to avoid the wrapping |
643
|
|
|
this.menu.width( "" ).outerWidth() + 1 |
644
|
|
|
) ); |
645
|
|
|
}, |
646
|
|
|
|
647
|
|
|
_getCreateOptions: function() { |
648
|
|
|
var options = this._super(); |
649
|
|
|
|
650
|
|
|
options.disabled = this.element.prop( "disabled" ); |
651
|
|
|
|
652
|
|
|
return options; |
653
|
|
|
}, |
654
|
|
|
|
655
|
|
|
_parseOptions: function( options ) { |
656
|
|
|
var that = this, |
657
|
|
|
data = []; |
658
|
|
|
options.each( function( index, item ) { |
659
|
|
|
data.push( that._parseOption( $( item ), index ) ); |
660
|
|
|
} ); |
661
|
|
|
this.items = data; |
662
|
|
|
}, |
663
|
|
|
|
664
|
|
|
_parseOption: function( option, index ) { |
665
|
|
|
var optgroup = option.parent( "optgroup" ); |
666
|
|
|
|
667
|
|
|
return { |
668
|
|
|
element: option, |
669
|
|
|
index: index, |
670
|
|
|
value: option.val(), |
671
|
|
|
label: option.text(), |
672
|
|
|
optgroup: optgroup.attr( "label" ) || "", |
673
|
|
|
disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) |
674
|
|
|
}; |
675
|
|
|
}, |
676
|
|
|
|
677
|
|
|
_destroy: function() { |
678
|
|
|
this._unbindFormResetHandler(); |
679
|
|
|
this.menuWrap.remove(); |
680
|
|
|
this.button.remove(); |
681
|
|
|
this.element.show(); |
682
|
|
|
this.element.removeUniqueId(); |
683
|
|
|
this.labels.attr( "for", this.ids.element ); |
684
|
|
|
} |
685
|
|
|
} ] ); |
686
|
|
|
|
687
|
|
|
} ) ); |
688
|
|
|
|