reworked how dropdown is managed in singleselect so the search field has focus even when the dropdown is not opened and can capture te first keypress. fixes #196
This commit is contained in:
parent
06ec20dec6
commit
1605a631e5
139
select2.js
139
select2.js
@ -806,26 +806,34 @@
|
|||||||
|
|
||||||
if (!this.shouldOpen()) return false;
|
if (!this.shouldOpen()) return false;
|
||||||
|
|
||||||
|
window.setTimeout(this.bind(this.opening), 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the opening of the dropdown
|
||||||
|
*/
|
||||||
|
// abstract
|
||||||
|
opening: function() {
|
||||||
this.clearDropdownAlignmentPreference();
|
this.clearDropdownAlignmentPreference();
|
||||||
|
|
||||||
if (this.search.val() === " ") { this.search.val(""); }
|
if (this.search.val() === " ") { this.search.val(""); }
|
||||||
|
|
||||||
this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
|
|
||||||
if(this.dropdown[0] !== this.body.children().last()[0]) {
|
|
||||||
// ensure the dropdown is the last child of body, so the z-index is always respected correctly
|
|
||||||
this.dropdown.detach().appendTo(this.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dropdown.addClass("select2-drop-active");
|
this.dropdown.addClass("select2-drop-active");
|
||||||
|
|
||||||
this.positionDropdown();
|
this.positionDropdown();
|
||||||
|
|
||||||
this.updateResults(true);
|
this.updateResults(true);
|
||||||
|
|
||||||
|
if(this.dropdown[0] !== this.body.children().last()[0]) {
|
||||||
|
this.dropdown.detach().appendTo(this.body);
|
||||||
|
}
|
||||||
|
|
||||||
this.dropdown.show();
|
this.dropdown.show();
|
||||||
this.ensureHighlightVisible();
|
this.ensureHighlightVisible();
|
||||||
this.focusSearch();
|
this.focusSearch();
|
||||||
|
this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// abstract
|
// abstract
|
||||||
@ -1132,11 +1140,11 @@
|
|||||||
"class": "select2-container",
|
"class": "select2-container",
|
||||||
"style": "width: " + this.getContainerWidth()
|
"style": "width: " + this.getContainerWidth()
|
||||||
}).html([
|
}).html([
|
||||||
" <a href='javascript:void(0)' class='select2-choice'><input type='text' class='select2-offscreen select2-focusser'/>",
|
" <a href='javascript:void(0)' class='select2-choice'>",
|
||||||
" <span></span><abbr class='select2-search-choice-close' style='display:none;'></abbr>",
|
" <span></span><abbr class='select2-search-choice-close' style='display:none;'></abbr>",
|
||||||
" <div><b></b></div>" ,
|
" <div><b></b></div>" ,
|
||||||
"</a>",
|
"</a>",
|
||||||
" <div class='select2-drop' style='display:none;'>" ,
|
" <div class='select2-drop select2-offscreen'>" ,
|
||||||
" <div class='select2-search'>" ,
|
" <div class='select2-search'>" ,
|
||||||
" <input type='text' autocomplete='off' class='select2-input'/>" ,
|
" <input type='text' autocomplete='off' class='select2-input'/>" ,
|
||||||
" </div>" ,
|
" </div>" ,
|
||||||
@ -1145,16 +1153,23 @@
|
|||||||
"</div>"].join(""));
|
"</div>"].join(""));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// single
|
||||||
|
opening: function () {
|
||||||
|
this.parent.opening.apply(this, arguments);
|
||||||
|
this.dropdown.removeClass("select2-offscreen");
|
||||||
|
},
|
||||||
|
|
||||||
// single
|
// single
|
||||||
close: function () {
|
close: function () {
|
||||||
if (!this.opened()) return;
|
if (!this.opened()) return;
|
||||||
this.parent.close.apply(this, arguments);
|
this.parent.close.apply(this, arguments);
|
||||||
|
this.dropdown.removeAttr("style").addClass("select2-offscreen").insertAfter(this.selection).show();
|
||||||
},
|
},
|
||||||
|
|
||||||
// single
|
// single
|
||||||
focus: function () {
|
focus: function () {
|
||||||
this.close();
|
this.close();
|
||||||
this.selection.focus();
|
this.search.focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
// single
|
// single
|
||||||
@ -1165,7 +1180,7 @@
|
|||||||
// single
|
// single
|
||||||
cancel: function () {
|
cancel: function () {
|
||||||
this.parent.cancel.apply(this, arguments);
|
this.parent.cancel.apply(this, arguments);
|
||||||
this.selection.focus();
|
this.search.focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
// single
|
// single
|
||||||
@ -1174,65 +1189,66 @@
|
|||||||
var selection,
|
var selection,
|
||||||
container = this.container,
|
container = this.container,
|
||||||
dropdown = this.dropdown,
|
dropdown = this.dropdown,
|
||||||
containers = $([this.container.get(0), this.dropdown.get(0)]),
|
clickingInside = false;
|
||||||
clickingInside = false,
|
|
||||||
selector = ".select2-choice",
|
|
||||||
focusser=container.find("input.select2-focusser");
|
|
||||||
|
|
||||||
this.selection = selection = container.find(selector);
|
this.selection = selection = container.find(".select2-choice");
|
||||||
|
|
||||||
this.search.bind("keydown", this.bind(function (e) {
|
this.search.bind("keydown", this.bind(function (e) {
|
||||||
switch (e.which) {
|
if (!this.enabled) return;
|
||||||
case KEY.UP:
|
|
||||||
case KEY.DOWN:
|
if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN || e.which === KEY.SPACE) {
|
||||||
this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
|
// prevent the page from scrolling
|
||||||
killEvent(e);
|
|
||||||
return;
|
|
||||||
case KEY.TAB:
|
|
||||||
case KEY.ENTER:
|
|
||||||
this.selectHighlighted();
|
|
||||||
killEvent(e);
|
|
||||||
return;
|
|
||||||
case KEY.ESC:
|
|
||||||
this.cancel(e);
|
|
||||||
killEvent(e);
|
killEvent(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.opened()) {
|
||||||
|
switch (e.which) {
|
||||||
|
case KEY.UP:
|
||||||
|
case KEY.DOWN:
|
||||||
|
this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
|
||||||
|
killEvent(e);
|
||||||
|
return;
|
||||||
|
case KEY.TAB:
|
||||||
|
case KEY.ENTER:
|
||||||
|
this.selectHighlighted();
|
||||||
|
killEvent(e);
|
||||||
|
return;
|
||||||
|
case KEY.ESC:
|
||||||
|
this.cancel(e);
|
||||||
|
killEvent(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.open();
|
||||||
|
|
||||||
|
if (e.which === KEY.ENTER) {
|
||||||
|
// do not propagate the event otherwise we open, and propagate enter which closes
|
||||||
|
killEvent(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
containers.delegate(selector, "click", this.bind(function (e) {
|
selection.bind("click", this.bind(function (e) {
|
||||||
clickingInside = true;
|
clickingInside = true;
|
||||||
|
|
||||||
if (this.opened()) {
|
if (this.opened()) {
|
||||||
this.close();
|
this.close();
|
||||||
selection.focus();
|
this.search.focus();
|
||||||
} else if (this.enabled) {
|
} else if (this.enabled) {
|
||||||
this.open();
|
this.open();
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
killEvent(e);
|
||||||
|
|
||||||
clickingInside = false;
|
clickingInside = false;
|
||||||
}));
|
}));
|
||||||
containers.delegate(selector, "keydown", this.bind(function (e) {
|
|
||||||
if (!this.enabled || e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
|
dropdown.bind("click", this.bind(function() { this.search.focus(); }));
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.open();
|
|
||||||
if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN || e.which === KEY.SPACE) {
|
|
||||||
// prevent the page from scrolling
|
|
||||||
killEvent(e);
|
|
||||||
}
|
|
||||||
if (e.which === KEY.ENTER) {
|
|
||||||
// do not propagate the event otherwise we open, and propagate enter which closes
|
|
||||||
killEvent(e);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
containers.delegate(selector, "focus", function () { if (this.enabled) { containers.addClass("select2-container-active"); dropdown.addClass("select2-drop-active"); }});
|
|
||||||
containers.delegate(selector, "blur", this.bind(function (e) {
|
|
||||||
if (clickingInside) return;
|
|
||||||
if (e.target===focusser.get(0)) return; // ignore blurs from focusser
|
|
||||||
if (!this.opened()) { this.blur(); }
|
|
||||||
}));
|
|
||||||
|
|
||||||
selection.delegate("abbr", "click", this.bind(function (e) {
|
selection.delegate("abbr", "click", this.bind(function (e) {
|
||||||
if (!this.enabled) return;
|
if (!this.enabled) return;
|
||||||
@ -1240,18 +1256,16 @@
|
|||||||
killEvent(e);
|
killEvent(e);
|
||||||
this.close();
|
this.close();
|
||||||
this.triggerChange();
|
this.triggerChange();
|
||||||
selection.focus();
|
this.search.focus();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
selection.bind("focus", this.bind(function() { this.search.focus(); }));
|
||||||
|
|
||||||
this.setPlaceholder();
|
this.setPlaceholder();
|
||||||
|
|
||||||
focusser.bind("focus", function() { selection.focus(); });
|
this.search.bind("focus", this.bind(function() {
|
||||||
selection.bind("focus", this.bind(function() {
|
|
||||||
focusser.hide();
|
|
||||||
this.container.addClass("select2-container-active");
|
this.container.addClass("select2-container-active");
|
||||||
}));
|
}));
|
||||||
selection.bind("blur", function() { focusser.show(); });
|
|
||||||
this.opts.element.bind("open", function() { focusser.hide(); });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
clear: function() {
|
clear: function() {
|
||||||
@ -1358,7 +1372,7 @@
|
|||||||
this.opts.element.val(this.id(data));
|
this.opts.element.val(this.id(data));
|
||||||
this.updateSelection(data);
|
this.updateSelection(data);
|
||||||
this.close();
|
this.close();
|
||||||
this.selection.focus();
|
this.search.focus();
|
||||||
|
|
||||||
if (!equal(old, this.id(data))) { this.triggerChange(); }
|
if (!equal(old, this.id(data))) { this.triggerChange(); }
|
||||||
},
|
},
|
||||||
@ -1623,13 +1637,12 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
// multi
|
// multi
|
||||||
open: function () {
|
opening: function () {
|
||||||
if (this.parent.open.apply(this, arguments) === false) return false;
|
this.parent.opening.apply(this, arguments);
|
||||||
|
|
||||||
this.clearPlaceholder();
|
this.clearPlaceholder();
|
||||||
this.resizeSearch();
|
this.resizeSearch();
|
||||||
this.focusSearch();
|
this.focusSearch();
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// multi
|
// multi
|
||||||
|
Loading…
Reference in New Issue
Block a user