Drop mouse following focus behavior as it interferes with custom value inputs,
rely on CSS based hover effects instead.
Also slightly improve keyboard navigation by auto-focussing the custom value
input when entering the last dropdown choice via arrow down or tab key, and
by allowing to leave the text input again with the arrow up key.
Fixes: #6903
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
(cherry picked from commit
3980c192cda6985c2e2d2608e74677cf236005db)
window.addEventListener('touchstart', this.closeAllDropdowns);
}
else {
window.addEventListener('touchstart', this.closeAllDropdowns);
}
else {
- sb.addEventListener('mouseover', this.handleMouseover.bind(this));
- sb.addEventListener('mouseout', this.handleMouseout.bind(this));
sb.addEventListener('focus', this.handleFocus.bind(this));
canary.addEventListener('focus', this.handleCanaryFocus.bind(this));
sb.addEventListener('focus', this.handleFocus.bind(this));
canary.addEventListener('focus', this.handleCanaryFocus.bind(this));
sb.insertBefore(pv, ul.nextElementSibling);
li.forEach(function(l) {
sb.insertBefore(pv, ul.nextElementSibling);
li.forEach(function(l) {
- l.setAttribute('tabindex', 0);
+ if (!l.hasAttribute('unselectable'))
+ l.setAttribute('tabindex', 0);
});
sb.lastElementChild.setAttribute('tabindex', 0);
});
sb.lastElementChild.setAttribute('tabindex', 0);
- /** @private */
- handleMouseout: function(ev) {
- var sb = ev.currentTarget;
-
- if (!sb.hasAttribute('open'))
- return;
-
- sb.querySelectorAll('.focus').forEach(function(e) {
- e.classList.remove('focus');
- });
-
- sb.querySelector('ul.dropdown').focus();
- },
-
/** @private */
createChoiceElement: function(sb, value, label) {
var tpl = sb.querySelector(this.options.create_template),
/** @private */
createChoiceElement: function(sb, value, label) {
var tpl = sb.querySelector(this.options.create_template),
case 40:
if (active && active.nextElementSibling) {
case 40:
if (active && active.nextElementSibling) {
- this.setFocus(sb, active.nextElementSibling);
+ var li = active.nextElementSibling;
+ this.setFocus(sb, li);
+ if (this.options.create && li == li.parentNode.lastElementChild) {
+ var input = li.querySelector('input');
+ if (input) input.focus();
+ }
ev.preventDefault();
}
else if (document.activeElement === ul) {
ev.preventDefault();
}
else if (document.activeElement === ul) {
this.closeDropdown(sb, true);
},
this.closeDropdown(sb, true);
},
- /** @private */
- handleMouseover: function(ev) {
- var sb = ev.currentTarget;
-
- if (!sb.hasAttribute('open'))
- return;
-
- var li = findParent(ev.target, 'li');
-
- if (li && li.parentNode.classList.contains('dropdown'))
- this.setFocus(sb, li);
- },
-
/** @private */
handleFocus: function(ev) {
var sb = ev.currentTarget;
/** @private */
handleFocus: function(ev) {
var sb = ev.currentTarget;
/** @private */
handleCreateKeydown: function(ev) {
var input = ev.currentTarget,
/** @private */
handleCreateKeydown: function(ev) {
var input = ev.currentTarget,
- sb = findParent(input, '.cbi-dropdown');
+ li = findParent(input, 'li'),
+ sb = findParent(li, '.cbi-dropdown');
switch (ev.keyCode) {
case 13:
switch (ev.keyCode) {
case 13:
input.value = '';
input.blur();
break;
input.value = '';
input.blur();
break;
+
+ case 38:
+ if (li.previousElementSibling) {
+ this.handleCreateBlur(ev);
+ this.setFocus(sb, li.previousElementSibling, true);
+ }
+ break;
}
},
/** @private */
handleCreateFocus: function(ev) {
var input = ev.currentTarget,
}
},
/** @private */
handleCreateFocus: function(ev) {
var input = ev.currentTarget,
- cbox = findParent(input, 'li').querySelector('input[type="checkbox"]'),
+ li = findParent(input, 'li'),
+ cbox = li.querySelector('input[type="checkbox"]'),
sb = findParent(input, '.cbi-dropdown');
if (cbox)
cbox.checked = true;
sb.setAttribute('locked-in', '');
sb = findParent(input, '.cbi-dropdown');
if (cbox)
cbox.checked = true;
sb.setAttribute('locked-in', '');
+ this.setFocus(sb, li, true);