element.
* @param {Event} $event - Angular event instance
*/
scope.onWrapperBlurOrFocus = function($event) {
// ignore events that bubbled up
if (document.activeElement !== wrapperEl[0]) return;
util.dispatchEvent(selectEl[0], $event.type, false, false);
};
/**
* Handle click event on wrapper
element.
* @param {Event} $event - Angular event instance
*/
scope.onWrapperClick = function($event) {
// only left click, check default prevented and useDefault
if ($event.button !== 0 ||
$event.defaultPrevented ||
scope.useDefault ||
selectEl[0].disabled) {
return;
}
// focus wrapper
wrapperEl[0].focus();
// open custom menu
scope.isOpen = true;
};
/**
* Handle keydown event on wrapper element.
* @param {Event} $event - Angular event instance
*/
scope.onWrapperKeydown = function($event) {
// exit if preventDefault() was called or useDefault is true
if ($event.defaultPrevented || scope.useDefault) return;
var keyCode = $event.keyCode;
if (scope.isOpen === false) {
// spacebar, down, up
if (keyCode === 32 || keyCode === 38 || keyCode === 40) {
// prevent win scroll
$event.preventDefault();
// open menu
scope.isOpen = true;
}
} else {
// tab
if (keyCode === 9) return scope.isOpen = false;
// escape | up | down | enter
if (keyCode === 27
|| keyCode === 40
|| keyCode === 38
|| keyCode === 13) {
$event.preventDefault();
}
var options = selectEl.children(),
nextIndex = null,
i;
if (keyCode === 27) {
// escape -> close
scope.isOpen = false;
} else if (keyCode === 40) {
// down -> increment
i = scope.menuIndex + 1;
while (i < options.length) {
// exit if option not disabled
if (!options[i].disabled && !options[i].hidden) {
nextIndex = i;
break;
}
i += 1;
}
if (nextIndex !== null) scope.menuIndex = nextIndex;
} else if (keyCode === 38) {
// up -> decrement
i = scope.menuIndex - 1;
while (i > -1) {
// exit if option not disabled
if (!options[i].disabled && !options[i].hidden) {
nextIndex = i;
break;
}
i -= 1;
}
if (nextIndex !== null) scope.menuIndex = nextIndex;
} else if (keyCode === 13) {
// enter -> choose and close
dispatchChange(options[scope.menuIndex]);
scope.isOpen = false;
}
}
};
/**
* Handle keypress event on wrapper element.
* @param {Event} $event - Angular event instance
*/
scope.onWrapperKeypress = function($event) {
// exit if preventDefault() was called or useDefault is true or
// menu is closed
if ($event.defaultPrevented || scope.useDefault || !scope.isOpen) {
return;
}
// handle query timer
clearTimeout(scope.qTimeout);
scope.q += $event.key;
scope.qTimeout = setTimeout(function() {scope.q = '';}, 600);
// select first match alphabetically
var prefixRegex = new RegExp('^' + scope.q, 'i'),
options = selectEl.children(),
m = options.length,
option,
i;
for (i=0; i < m; i++) {
option = options[i];
if (!option.hidden &&
!option.disabled &&
prefixRegex.test(option.innerText)) {
scope.menuIndex = option.index;
break;
}
}
}
/**
* Handle mousedown event on Inner