Skip to content

Commit e9736b3

Browse files
committed
added: sequencial typeahead, thx to arzynik, see spacedevin@5df784f
1 parent 83a15c7 commit e9736b3

File tree

1 file changed

+64
-28
lines changed

1 file changed

+64
-28
lines changed

ui/jquery.ui.selectmenu.js

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ $.widget("ui.selectmenu", {
1717
eventPrefix: "selectmenu",
1818
options: {
1919
transferClasses: true,
20+
typeAhead: "sequential",
2021
style: 'dropdown',
2122
positionOptions: {
2223
my: "left top",
@@ -219,7 +220,8 @@ $.widget("ui.selectmenu", {
219220
break;
220221
default:
221222
ret = true;
222-
break;
223+
224+
self._typeAhead(event.keyCode,'focus'); break;
223225
}
224226
return ret;
225227
});
@@ -243,6 +245,7 @@ $.widget("ui.selectmenu", {
243245
text: self._formatText($(this).text()),
244246
selected: $(this).attr('selected'),
245247
classes: $(this).attr('class'),
248+
typeahead: $(this).attr('typeahead'),
246249
parentOptGroup: $(this).parent('optgroup').attr('label'),
247250
bgImage: o.bgImage.call($(this))
248251
});
@@ -256,7 +259,7 @@ $.widget("ui.selectmenu", {
256259

257260
// write li's
258261
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>')
260263
.data('index', i)
261264
.addClass(selectOptionData[i].classes)
262265
.data('optionClasses', selectOptionData[i].classes || '')
@@ -415,37 +418,70 @@ $.widget("ui.selectmenu", {
415418
$.Widget.prototype.destroy.apply(this, arguments);
416419
},
417420

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);
425423
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)
442445
}
443446
}
447+
});
448+
449+
// if we didnt find it clear the prevChar
450+
if (!focusFound) {
451+
//self._prevChar = undefined
444452
}
445-
});
446-
this._prevChar[0] = C;
447-
},
448453

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+
449485
// returns some usefull information, called by callbacks only
450486
_uiHash: function() {
451487
var index = this.index();

0 commit comments

Comments
 (0)