1
0
mirror of synced 2024-11-26 06:46:04 +03:00

Add option to automatically size dropdown width

This commit is contained in:
jfoster 2013-03-18 18:39:10 -04:00
parent 6a29e594b6
commit 7956d7aee3
2 changed files with 51 additions and 10 deletions

View File

@ -147,6 +147,15 @@ Version: @@ver@@ Timestamp: @@timestamp@@
box-shadow: 0 4px 5px rgba(0, 0, 0, .15); box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
} }
.select2-drop-auto-width {
border-top: 1px solid #aaa;
width: auto;
}
.select2-drop-auto-width .select2-search {
padding-top: 4px;
}
.select2-drop.select2-drop-above { .select2-drop.select2-drop-above {
margin-top: 1px; margin-top: 1px;
border-top: 1px solid #aaa; border-top: 1px solid #aaa;

View File

@ -47,7 +47,7 @@ the specific language governing permissions and limitations under the Apache Lic
} }
var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer, var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,
lastMousePosition, $document; lastMousePosition, $document, scrollBarDimensions,
KEY = { KEY = {
TAB: 9, TAB: 9,
@ -95,7 +95,8 @@ the specific language governing permissions and limitations under the Apache Lic
k = k.which ? k.which : k; k = k.which ? k.which : k;
return k >= 112 && k <= 123; return k >= 112 && k <= 123;
} }
}; },
MEASURE_SCROLLBAR_TEMPLATE = "<div style='position:absolute; top:-10000px; left:-10000px; width:100px; height:100px; overflow:scroll;'></div>";
$document = $(document); $document = $(document);
@ -109,6 +110,19 @@ the specific language governing permissions and limitations under the Apache Lic
return -1; return -1;
} }
function measureScrollbar () {
var $template = $( MEASURE_SCROLLBAR_TEMPLATE );
$template.appendTo('body');
var dim = {
width: $template.width() - $template[0].clientWidth,
height: $template.height() - $template[0].clientHeight
};
$template.remove();
return dim;
}
/** /**
* Compares equality of a and b * Compares equality of a and b
* @param a * @param a
@ -691,6 +705,9 @@ the specific language governing permissions and limitations under the Apache Lic
} }
if (opts.element.is(":disabled") || opts.element.is("[readonly='readonly']")) this.disable(); if (opts.element.is(":disabled") || opts.element.is("[readonly='readonly']")) this.disable();
// Calculate size of scrollbar
scrollBarDimensions = scrollBarDimensions || measureScrollbar();
}, },
// abstract // abstract
@ -977,22 +994,37 @@ the specific language governing permissions and limitations under the Apache Lic
// abstract // abstract
positionDropdown: function() { positionDropdown: function() {
var offset = this.container.offset(), var $dropdown = this.dropdown,
offset = this.container.offset(),
height = this.container.outerHeight(false), height = this.container.outerHeight(false),
width = this.container.outerWidth(false), width = this.container.outerWidth(false),
dropHeight = this.dropdown.outerHeight(false), dropHeight = $dropdown.outerHeight(false),
viewPortRight = $(window).scrollLeft() + $(window).width(), viewPortRight = $(window).scrollLeft() + $(window).width(),
viewportBottom = $(window).scrollTop() + $(window).height(), viewportBottom = $(window).scrollTop() + $(window).height(),
dropTop = offset.top + height, dropTop = offset.top + height,
dropLeft = offset.left, dropLeft = offset.left,
enoughRoomBelow = dropTop + dropHeight <= viewportBottom, enoughRoomBelow = dropTop + dropHeight <= viewportBottom,
enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(), enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(),
dropWidth = this.dropdown.outerWidth(false), dropWidth = $dropdown.outerWidth(false),
enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight, enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight,
aboveNow = this.dropdown.hasClass("select2-drop-above"), aboveNow = $dropdown.hasClass("select2-drop-above"),
bodyOffset, bodyOffset,
above, above,
css; css,
resultsListNode;
if (this.opts.dropdownAutoWidth) {
resultsListNode = $('.select2-results', $dropdown)[0];
$dropdown.addClass('select2-drop-auto-width');
$dropdown.css('width', '');
// Add scrollbar width to dropdown if vertical scrollbar is present
dropWidth = $dropdown.outerWidth(false) + (resultsListNode.scrollHeight === resultsListNode.clientHeight ? 0 : scrollBarDimensions.width);
dropWidth > width ? width = dropWidth : dropWidth = width;
enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight;
}
else {
this.container.removeClass('select2-drop-auto-width');
}
//console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow); //console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow);
//console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body().scrollTop(), "enough?", enoughRoomAbove); //console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body().scrollTop(), "enough?", enoughRoomAbove);
@ -1022,11 +1054,11 @@ the specific language governing permissions and limitations under the Apache Lic
if (above) { if (above) {
dropTop = offset.top - dropHeight; dropTop = offset.top - dropHeight;
this.container.addClass("select2-drop-above"); this.container.addClass("select2-drop-above");
this.dropdown.addClass("select2-drop-above"); $dropdown.addClass("select2-drop-above");
} }
else { else {
this.container.removeClass("select2-drop-above"); this.container.removeClass("select2-drop-above");
this.dropdown.removeClass("select2-drop-above"); $dropdown.removeClass("select2-drop-above");
} }
css = $.extend({ css = $.extend({
@ -1035,7 +1067,7 @@ the specific language governing permissions and limitations under the Apache Lic
width: width width: width
}, evaluate(this.opts.dropdownCss)); }, evaluate(this.opts.dropdownCss));
this.dropdown.css(css); $dropdown.css(css);
}, },
// abstract // abstract