1
0
mirror of synced 2024-11-22 21:16:10 +03:00

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:
Igor Vaynberg 2012-07-15 22:22:38 +03:00
parent 06ec20dec6
commit 1605a631e5

View File

@ -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,14 +1189,20 @@
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) {
if (!this.enabled) return;
if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN || e.which === KEY.SPACE) {
// prevent the page from scrolling
killEvent(e);
return;
}
if (this.opened()) {
switch (e.which) { switch (e.which) {
case KEY.UP: case KEY.UP:
case KEY.DOWN: case KEY.DOWN:
@ -1198,41 +1219,36 @@
killEvent(e); killEvent(e);
return; 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