diff --git a/src/js/select2/dropdown/attachBody.js b/src/js/select2/dropdown/attachBody.js index 7380d9c6..1ef2373c 100644 --- a/src/js/select2/dropdown/attachBody.js +++ b/src/js/select2/dropdown/attachBody.js @@ -190,7 +190,14 @@ define([ $offsetParent = $offsetParent.offsetParent(); } - var parentOffset = $offsetParent.offset(); + var parentOffset = { + top: 0, + left: 0 + }; + + if ($.contains(document.body, $offsetParent[0])) { + parentOffset = $offsetParent.offset(); + } css.top -= parentOffset.top; css.left -= parentOffset.left; diff --git a/tests/dropdown/positioning-tests.js b/tests/dropdown/positioning-tests.js index 2da68982..eb721654 100644 --- a/tests/dropdown/positioning-tests.js +++ b/tests/dropdown/positioning-tests.js @@ -174,4 +174,53 @@ test('dropdown is positioned down with absolute offsets', function (assert) { '0px', 'There should not be an extra left offset' ); -}); \ No newline at end of file +}); + +test('dropdown is positioned even when not in document', function (assert) { + var $ = require('jquery'); + var $select = $(''); + + var $container = $('test'); + var container = new MockContainer(); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Dropdown = require('select2/dropdown'); + var AttachBody = require('select2/dropdown/attachBody'); + + var DropdownAdapter = Utils.Decorate(Dropdown, AttachBody); + + var dropdown = new DropdownAdapter($select, new Options({ + dropdownParent: $('html') + })); + + var $dropdown = dropdown.render(); + + assert.equal( + $dropdown[0].style.top, + 0, + 'The drodpown should not have any offset before it is displayed' + ); + + dropdown.bind(container, $container); + dropdown.position($dropdown, $container); + dropdown._showDropdown(); + + assert.ok( + dropdown.$dropdown.hasClass('select2-dropdown--below'), + 'The dropdown should be forced down' + ); + + assert.equal( + $dropdown.css('top'), + '0px', + 'The offset should be 0px at the top' + ); + + assert.equal( + $dropdown.css('left'), + '0px', + 'The offset should be 0px on the left' + ); +});