fix scroll event handling since it doesnt bubble. also add a shim behind the dropdown, this allows it to properly close even when used inside modals. sometimes modals will place their own shim that closes the modal and aborts the default mousedown event. in such cases the modal would close but the dropdown element would still float on the screen now detached and the only way to close it would be to make a selection
This commit is contained in:
parent
3f14f773f9
commit
7a006a7259
@ -107,6 +107,14 @@ Version: @@ver@@ Timestamp: @@timestamp@@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select2-drop-mask {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 9998;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.select2-drop {
|
||||
width: 100%;
|
||||
margin-top:-1px;
|
||||
|
66
select2.js
66
select2.js
@ -150,25 +150,6 @@ the specific language governing permissions and limitations under the Apache Lic
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(window).bind("resize", function(e) {
|
||||
var dropdown=$("#select2-drop");
|
||||
if (dropdown.length>0) {
|
||||
// there is an open dropdown
|
||||
|
||||
// adjust dropdown positioning so it sizes with the content
|
||||
dropdown.data("select2").positionDropdown();
|
||||
}
|
||||
}).delegate("*", "scroll", function(e) {
|
||||
var dropdown=$("#select2-drop");
|
||||
if (dropdown.length>0) {
|
||||
// there is an open dropdown
|
||||
|
||||
// adjust dropdown positioning so it scrolls with the content
|
||||
dropdown.data("select2").positionDropdown();
|
||||
}
|
||||
});
|
||||
|
||||
$document.bind("mousemove", function (e) {
|
||||
lastMousePosition = {x: e.pageX, y: e.pageY};
|
||||
});
|
||||
@ -553,7 +534,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
||||
|
||||
// abstract
|
||||
init: function (opts) {
|
||||
var results, search, resultsSelector = ".select2-results";
|
||||
var results, search, resultsSelector = ".select2-results", mask;
|
||||
|
||||
// prepare options
|
||||
this.opts = opts = this.prepareOpts(opts);
|
||||
@ -576,6 +557,15 @@ the specific language governing permissions and limitations under the Apache Lic
|
||||
// cache the body so future lookups are cheap
|
||||
this.body = thunk(function() { return opts.element.closest("body"); });
|
||||
|
||||
// create the dropdown mask if doesnt already exist
|
||||
mask = $("#select2-drop-mask");
|
||||
if (mask.length == 0) {
|
||||
mask = $(document.createElement("div"));
|
||||
mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask");
|
||||
mask.hide();
|
||||
mask.appendTo(this.body());
|
||||
}
|
||||
|
||||
if (opts.element.attr("class") !== undefined) {
|
||||
this.container.addClass(opts.element.attr("class").replace(/validate\[[\S ]+] ?/, ''));
|
||||
}
|
||||
@ -986,7 +976,10 @@ the specific language governing permissions and limitations under the Apache Lic
|
||||
*/
|
||||
// abstract
|
||||
opening: function() {
|
||||
var cid = this.containerId, selector = this.containerSelector;
|
||||
var cid = this.containerId,
|
||||
scroll = "scroll." + cid,
|
||||
resize = "resize."+cid,
|
||||
mask;
|
||||
|
||||
this.clearDropdownAlignmentPreference();
|
||||
|
||||
@ -1000,16 +993,39 @@ the specific language governing permissions and limitations under the Apache Lic
|
||||
this.dropdown.detach().appendTo(this.body());
|
||||
}
|
||||
|
||||
mask = $("#select2-drop-mask");
|
||||
|
||||
// ensure the mask is always right before the dropdown
|
||||
if (this.dropdown.prev()[0] !== mask[0]) {
|
||||
this.dropdown.before(mask);
|
||||
}
|
||||
|
||||
// move the global id to the correct dropdown
|
||||
$("#select2-drop").removeAttr("id");
|
||||
this.dropdown.attr("id", "select2-drop");
|
||||
|
||||
// show the elements
|
||||
mask.css({
|
||||
width: document.documentElement.scrollWidth,
|
||||
height: document.documentElement.scrollHeight});
|
||||
mask.show();
|
||||
this.dropdown.show();
|
||||
this.positionDropdown();
|
||||
|
||||
this.dropdown.addClass("select2-drop-active");
|
||||
this.ensureHighlightVisible();
|
||||
|
||||
// attach listeners to events that can change the position of the container and thus require
|
||||
// the position of the dropdown to be updated as well so it does not come unglued from the container
|
||||
this.container.parents().add(window).each(function () {
|
||||
$(this).bind(resize+" "+scroll, function (e) {
|
||||
$("#select2-drop-mask").css({
|
||||
width:document.documentElement.scrollWidth,
|
||||
height:document.documentElement.scrollHeight});
|
||||
$("#select2-drop").data("select2").positionDropdown();
|
||||
});
|
||||
});
|
||||
|
||||
this.focusSearch();
|
||||
},
|
||||
|
||||
@ -1017,10 +1033,16 @@ the specific language governing permissions and limitations under the Apache Lic
|
||||
close: function () {
|
||||
if (!this.opened()) return;
|
||||
|
||||
var self = this;
|
||||
var cid = this.containerId,
|
||||
scroll = "scroll." + cid,
|
||||
resize = "resize."+cid;
|
||||
|
||||
// unbind event listeners
|
||||
this.container.parents().add(window).each(function () { $(this).unbind(scroll).unbind(resize); });
|
||||
|
||||
this.clearDropdownAlignmentPreference();
|
||||
|
||||
$("#select2-drop-mask").hide();
|
||||
this.dropdown.removeAttr("id"); // only the active dropdown has the select2-drop id
|
||||
this.dropdown.hide();
|
||||
this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active");
|
||||
|
Loading…
Reference in New Issue
Block a user