I have written a custom drop down menu handler using jQuery because I felt that the native drop down didn't fit my UI. I have taking into consideration the native way of going through a drop down box using arrows and tabs to move to next input.
I was wondering if anyone can see any mistakes or errors or anyway I could improve this.
Basic markup for a drop down box:
<label>
<a class="dropdown button drop white"><span>Title</span><i></i></a>
<ul class="dropmenu">
<li>Mr</li>
<li>Mrs</li>
<li>Ms</li>
<li>Miss</li>
</ul>
<input type="text" class="dropFocuser" />
</label>
jQuery:
(function() {
var listItems
, direction
, index=0
, shift='off'
, next
, method = false;
var changeInput = function(drop, next, enter) {
var input = drop.parent().siblings('a').find('span');
var newinput = drop.html();
$(input).html(newinput);
if(next){
if(enter) {
drop.parent().removeClass('show');
drop.parent().parent().next().focus();
} else {
method = true;
console.log(drop.parent().removeClass('show'));
console.log(drop.parent().parent().next().focus());
}
}
}
$('input.dropFocuser').focus(function() {
if(method == false) {
index = 0;
$(this).siblings('ul').addClass('show');
listItems = $(this).siblings('ul').find('li');
} else {
method = false;
}
});
$('ul.dropmenu').find('li').mouseover(function(e){
var that = this;
$('li').removeClass('focusList');
$(this).addClass('focusList');
$(listItems).each(function(i) {
if($(listItems)[i] == that){
index = i;
return false;
}
});
});
$('ul.dropmenu').find('li').click(function(e) {
changeInput($(this), next=true);
})
/**
* Keep track of the shift keys so that we weither to focus next or prev input element.
*/
$(document).keydown(function(e){
//if shift key has been pressed down set it to on
if(e.keyCode == 16) {
shift = 'on';
}
});
$(document).keyup(function(e){
//if shift key has been released set it to off
if(e.keyCode == 16) {
shift = 'off';
}
})
$('input.dropFocuser').keydown(function(e) {
$('li').removeClass('focusList');
switch (e.keyCode){
case 9:
//this checks to see if the shift key is pressed or not and
//from there takes appropriate action.
if(shift == 'off'){
$(this).siblings('ul').removeClass('show');
console.log($(this).parent().next().focus());
} else {
$(this).siblings('ul').removeClass('show');
console.log($(this).parent().prev().focus());
}
return false;
break;
case 13:
var current = listItems[index-1];
changeInput($(current), next=true, enter=true);
$(current).addClass('focusList');
return false;
break;
case 40:
if(index == listItems.length){
index = 1;
$(listItems[0]).addClass('focusList');
changeInput($(listItems[0]), next=false);
} else{
index++
}
direction = 'down';
break;
case 38:
if(direction == 'down') {
$(listItems[index-2]).addClass('focusList');
changeInput($(listItems[index-2]), next=false);
index -= 1;
if(index == 0) {
$(listItems[listItems.length-1]).addClass('focusList');
changeInput($(listItems[listItems.length-1]));
index = listItems.length;
}
return false;
}
direction = 'up';
break;
default : return false;
}
changeInput($(listItems[index-1]), next=false);
$(listItems[index-1]).addClass('focusList');
});
})();
I have found this code to be unreliable so I did a little bit of digging and I found that I could change the native UI look that works in modern browsers. I have written in a fallback for
Here is the new HTML / CSS only code.