@@ -17,6 +17,7 @@ $.widget("ui.selectmenu", {
17
17
eventPrefix : "selectmenu" ,
18
18
options : {
19
19
transferClasses : true ,
20
+ typeAhead : "sequential" ,
20
21
style : 'dropdown' ,
21
22
positionOptions : {
22
23
my : "left top" ,
@@ -219,7 +220,8 @@ $.widget("ui.selectmenu", {
219
220
break ;
220
221
default :
221
222
ret = true ;
222
- break ;
223
+
224
+ self . _typeAhead ( event . keyCode , 'focus' ) ; break ;
223
225
}
224
226
return ret ;
225
227
} ) ;
@@ -243,6 +245,7 @@ $.widget("ui.selectmenu", {
243
245
text : self . _formatText ( $ ( this ) . text ( ) ) ,
244
246
selected : $ ( this ) . attr ( 'selected' ) ,
245
247
classes : $ ( this ) . attr ( 'class' ) ,
248
+ typeahead : $ ( this ) . attr ( 'typeahead' ) ,
246
249
parentOptGroup : $ ( this ) . parent ( 'optgroup' ) . attr ( 'label' ) ,
247
250
bgImage : o . bgImage . call ( $ ( this ) )
248
251
} ) ;
@@ -256,7 +259,7 @@ $.widget("ui.selectmenu", {
256
259
257
260
// write li's
258
261
for ( var i = 0 ; i < selectOptionData . length ; i ++ ) {
259
- var thisLi = $ ( '<li role="presentation"><a href="#" tabindex="-1" role="option" aria-selected="false">' + selectOptionData [ i ] . text + '</a></li>' )
262
+ var thisLi = $ ( '<li role="presentation"><a href="#" tabindex="-1" role="option" aria-selected="false"' + ( selectOptionData [ i ] . typeahead ? ' typeahead="' + selectOptionData [ i ] . typeahead + '"' : '' ) + '>' + selectOptionData [ i ] . text + '</a></li>' )
260
263
. data ( 'index' , i )
261
264
. addClass ( selectOptionData [ i ] . classes )
262
265
. data ( 'optionClasses' , selectOptionData [ i ] . classes || '' )
@@ -415,37 +418,70 @@ $.widget("ui.selectmenu", {
415
418
$ . Widget . prototype . destroy . apply ( this , arguments ) ;
416
419
} ,
417
420
418
- _typeAhead : function ( code , eventType ) {
419
- var self = this ;
420
- //define self._prevChar if needed
421
- if ( ! self . _prevChar ) {
422
- self . _prevChar = [ '' , 0 ] ;
423
- }
424
- var C = String . fromCharCode ( code ) ;
421
+ _typeAhead : function ( code , eventType ) {
422
+ var self = this , focusFound = false , C = String . fromCharCode ( code ) ;
425
423
c = C . toLowerCase ( ) ;
426
- var focusFound = false ;
427
- function focusOpt ( elem , ind ) {
428
- focusFound = true ;
429
- $ ( elem ) . trigger ( eventType ) ;
430
- self . _prevChar [ 1 ] = ind ;
431
- }
432
- this . list . find ( 'li a' ) . each ( function ( i ) {
433
- if ( ! focusFound ) {
434
- var thisText = $ ( this ) . text ( ) ;
435
- if ( thisText . indexOf ( C ) === 0 || thisText . indexOf ( c ) === 0 ) {
436
- if ( self . _prevChar [ 0 ] == C ) {
437
- if ( self . _prevChar [ 1 ] < i ) {
438
- focusOpt ( this , i ) ;
439
- }
440
- } else {
441
- focusOpt ( this , i ) ;
424
+
425
+ if ( self . options . typeAhead == 'sequential' ) {
426
+ // clear the timeout so we can use _prevChar
427
+ window . clearTimeout ( 'ui.selectmenu-' + self . selectmenuId ) ;
428
+
429
+ // define our find var
430
+ var find = typeof ( self . _prevChar ) == 'undefined' ? '' : self . _prevChar . join ( '' ) ;
431
+
432
+ function focusOptSeq ( elem , ind , char ) {
433
+ focusFound = true ;
434
+ $ ( elem ) . trigger ( eventType ) ;
435
+ typeof ( self . _prevChar ) == 'undefined' ? self . _prevChar = [ char ] : self . _prevChar [ self . _prevChar . length ] = char ;
436
+ }
437
+ this . list . find ( 'li a' ) . each ( function ( i ) {
438
+ if ( ! focusFound ) {
439
+ // allow the typeahead attribute on the option tag for a more specific lookup
440
+ var thisText = $ ( this ) . attr ( 'typeahead' ) || $ ( this ) . text ( ) ;
441
+ if ( thisText . indexOf ( find + C ) == 0 ) {
442
+ focusOptSeq ( this , i , C )
443
+ } else if ( thisText . indexOf ( find + c ) == 0 ) {
444
+ focusOptSeq ( this , i , c )
442
445
}
443
446
}
447
+ } ) ;
448
+
449
+ // if we didnt find it clear the prevChar
450
+ if ( ! focusFound ) {
451
+ //self._prevChar = undefined
444
452
}
445
- } ) ;
446
- this . _prevChar [ 0 ] = C ;
447
- } ,
448
453
454
+ // set a 1 second timeout for sequenctial typeahead
455
+ // keep this set even if we have no matches so it doesnt typeahead somewhere else
456
+ window . setTimeout ( function ( el ) {
457
+ el . _prevChar = undefined ;
458
+ } , 1000 , self ) ;
459
+
460
+ } else {
461
+ //define self._prevChar if needed
462
+ if ( ! self . _prevChar ) { self . _prevChar = [ '' , 0 ] ; }
463
+
464
+ var focusFound = false ;
465
+ function focusOpt ( elem , ind ) {
466
+ focusFound = true ;
467
+ $ ( elem ) . trigger ( eventType ) ;
468
+ self . _prevChar [ 1 ] = ind ;
469
+ }
470
+ this . list . find ( 'li a' ) . each ( function ( i ) {
471
+ if ( ! focusFound ) {
472
+ var thisText = $ ( this ) . text ( ) ;
473
+ if ( thisText . indexOf ( C ) == 0 || thisText . indexOf ( c ) == 0 ) {
474
+ if ( self . _prevChar [ 0 ] == C ) {
475
+ if ( self . _prevChar [ 1 ] < i ) { focusOpt ( this , i ) ; }
476
+ }
477
+ else { focusOpt ( this , i ) ; }
478
+ }
479
+ }
480
+ } ) ;
481
+ this . _prevChar [ 0 ] = C ;
482
+ }
483
+ } ,
484
+
449
485
// returns some usefull information, called by callbacks only
450
486
_uiHash : function ( ) {
451
487
var index = this . index ( ) ;
0 commit comments