Switch back to late binding the positioning handlers
This is how it used to work pre-4.0.9, where the bound handlers for resizing and positioning the dropdown were bound at the first time that the dropdown was opened. This was changed for the 4.0.9 release as a part of 3f75227a693 where it was not clear why this late binding was happening, so it was removed to simplify the code. The late binding is necessary because the handlers within results for generating the results, and thus the content within the dropdown, are bound after the handlers for the dropdown are bound. This results in situations where the handlers for positioning the dropdown are bound before the dropdown is updated with content, resulting in the positioning being calculated for the old content and thus being incorrectly placed. By binding the positioning handlers after the dropdow is opened for the first time, we can ensure that the positioning handlers are bound after the result handlers, so we won't have to worry about this issue. The handlers are only bound once because they only need to perform all the calculations a single time. There is no need to keep checking all of the calculated styles more than we need to, so this is guarded by a flag which ensures it is only bound a single time per dropdown. Fixes #5619 Fixes #5620
This commit is contained in:
parent
d54560f21e
commit
d8d2aa5b03
66
src/js/select2/dropdown/attachBody.js
vendored
66
src/js/select2/dropdown/attachBody.js
vendored
@ -16,6 +16,9 @@ define([
|
||||
container.on('open', function () {
|
||||
self._showDropdown();
|
||||
self._attachPositioningHandler(container);
|
||||
|
||||
// Must bind after the results handlers to ensure correct sizing
|
||||
self._bindContainerResultHandlers(container);
|
||||
});
|
||||
|
||||
container.on('close', function () {
|
||||
@ -23,31 +26,6 @@ define([
|
||||
self._detachPositioningHandler(container);
|
||||
});
|
||||
|
||||
container.on('results:all', function () {
|
||||
self._positionDropdown();
|
||||
self._resizeDropdown();
|
||||
});
|
||||
|
||||
container.on('results:append', function () {
|
||||
self._positionDropdown();
|
||||
self._resizeDropdown();
|
||||
});
|
||||
|
||||
container.on('results:message', function () {
|
||||
self._positionDropdown();
|
||||
self._resizeDropdown();
|
||||
});
|
||||
|
||||
container.on('select', function () {
|
||||
self._positionDropdown();
|
||||
self._resizeDropdown();
|
||||
});
|
||||
|
||||
container.on('unselect', function () {
|
||||
self._positionDropdown();
|
||||
self._resizeDropdown();
|
||||
});
|
||||
|
||||
this.$dropdownContainer.on('mousedown', function (evt) {
|
||||
evt.stopPropagation();
|
||||
});
|
||||
@ -89,6 +67,44 @@ define([
|
||||
this.$dropdownContainer.detach();
|
||||
};
|
||||
|
||||
AttachBody.prototype._bindContainerResultHandlers =
|
||||
function (decorated, container) {
|
||||
|
||||
// These should only be bound once
|
||||
if (this._containerResultsHandlersBound) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
container.on('results:all', function () {
|
||||
self._positionDropdown();
|
||||
self._resizeDropdown();
|
||||
});
|
||||
|
||||
container.on('results:append', function () {
|
||||
self._positionDropdown();
|
||||
self._resizeDropdown();
|
||||
});
|
||||
|
||||
container.on('results:message', function () {
|
||||
self._positionDropdown();
|
||||
self._resizeDropdown();
|
||||
});
|
||||
|
||||
container.on('select', function () {
|
||||
self._positionDropdown();
|
||||
self._resizeDropdown();
|
||||
});
|
||||
|
||||
container.on('unselect', function () {
|
||||
self._positionDropdown();
|
||||
self._resizeDropdown();
|
||||
});
|
||||
|
||||
this._containerResultsHandlersBound = true;
|
||||
};
|
||||
|
||||
AttachBody.prototype._attachPositioningHandler =
|
||||
function (decorated, container) {
|
||||
var self = this;
|
||||
|
Loading…
Reference in New Issue
Block a user