Skip to content

Commit

Permalink
Add 'auto' option for dropdownAlignRight
Browse files Browse the repository at this point in the history
If dropdownAlignRight is set to 'auto', the menu will auto align to the
right if there's not enough room to open aligned to the left. close
snapappointments#1127, close snapappointments#1016, close snapappointments#1160, close snapappointments#1269
  • Loading branch information
caseyjhol authored and avantika-gupta-jtg committed May 14, 2020
1 parent 582a3d6 commit 1daf83f
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 44 deletions.
70 changes: 49 additions & 21 deletions dist/js/bootstrap-select.js
Expand Up @@ -363,8 +363,7 @@

this.$element.removeClass('bs-select-hidden');

if (this.options.dropdownAlignRight)
this.$menu.addClass('dropdown-menu-right');
if (this.options.dropdownAlignRight === true) this.$menu.addClass('dropdown-menu-right');

if (typeof id !== 'undefined') {
this.$button.attr('data-id', id);
Expand Down Expand Up @@ -802,13 +801,24 @@
// fall back to jQuery if getComputedStyle is not supported
menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,
$menu = menuStyle ? null : $(menu),
menuPadding = parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +
parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +
parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +
parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),
menuExtras = menuPadding +
menuPadding = {
vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +
parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +
parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +
parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),
horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) +
parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) +
parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) +
parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth'))
},
menuExtras = {
vert: menuPadding.vert +
parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +
parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2;
parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2,
horiz: menuPadding.horiz +
parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) +
parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2
}

document.body.removeChild(newElement);

Expand Down Expand Up @@ -836,6 +846,7 @@
$menuInner = this.$menuInner,
$window = $(window),
selectHeight = this.$newElement[0].offsetHeight,
selectWidth = this.$newElement[0].offsetWidth,
liHeight = this.sizeInfo['liHeight'],
headerHeight = this.sizeInfo['headerHeight'],
searchHeight = this.sizeInfo['searchHeight'],
Expand All @@ -846,15 +857,22 @@
menuExtras = this.sizeInfo['menuExtras'],
notDisabled = this.options.hideDisabled ? '.disabled' : '',
menuHeight,
menuWidth,
getHeight,
getWidth,
selectOffsetTop,
selectOffsetBot,
posVert = function () {
selectOffsetTop = that.$newElement.offset().top - $window.scrollTop();
selectOffsetLeft,
selectOffsetRight,
getPos = function() {
var pos = that.$newElement.offset();
selectOffsetTop = pos.top - $window.scrollTop();
selectOffsetBot = $window.height() - selectOffsetTop - selectHeight;
selectOffsetLeft = pos.left - $window.scrollLeft();
selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth;
};

posVert();
getPos();

if (this.options.size === 'auto') {
var getSize = function () {
Expand All @@ -872,25 +890,35 @@
lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),
optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');

posVert();
menuHeight = selectOffsetBot - menuExtras;
getPos();
menuHeight = selectOffsetBot - menuExtras.vert;
menuWidth = selectOffsetRight - menuExtras.horiz;

if (that.options.container) {
if (!$menu.data('height')) $menu.data('height', $menu.height());
getHeight = $menu.data('height');

if (!$menu.data('width')) $menu.data('width', $menu.width());
getWidth = $menu.data('width');
} else {
getHeight = $menu.height();
getWidth = $menu.width();
}

if (that.options.dropupAuto) {
that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);
that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);
}

if (that.$newElement.hasClass('dropup')) {
menuHeight = selectOffsetTop - menuExtras;
menuHeight = selectOffsetTop - menuExtras.vert;
}

if (that.options.dropdownAlignRight === 'auto') {
$menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth));
}

if ((lisVisible.length + optGroup.length) > 3) {
minHeight = liHeight * 3 + menuExtras - 2;
minHeight = liHeight * 3 + menuExtras.vert - 2;
} else {
minHeight = 0;
}
Expand All @@ -901,9 +929,9 @@
'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'
});
$menuInner.css({
'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding + 'px',
'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px',
'overflow-y': 'auto',
'min-height': Math.max(minHeight - menuPadding, 0) + 'px'
'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px'
});
};
getSize();
Expand All @@ -912,7 +940,7 @@
} else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {
var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),
divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;
menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding;
menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;

if (that.options.container) {
if (!$menu.data('height')) $menu.data('height', $menu.height());
Expand All @@ -923,15 +951,15 @@

if (that.options.dropupAuto) {
//noinspection JSUnusedAssignment
this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);
this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);
}
$menu.css({
'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',
'overflow': 'hidden',
'min-height': ''
});
$menuInner.css({
'max-height': menuHeight - menuPadding + 'px',
'max-height': menuHeight - menuPadding.vert + 'px',
'overflow-y': 'auto',
'min-height': ''
});
Expand Down
2 changes: 1 addition & 1 deletion dist/js/bootstrap-select.js.map

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion dist/js/bootstrap-select.min.js

Large diffs are not rendered by default.

70 changes: 49 additions & 21 deletions js/bootstrap-select.js
Expand Up @@ -340,8 +340,7 @@

this.$element.removeClass('bs-select-hidden');

if (this.options.dropdownAlignRight)
this.$menu.addClass('dropdown-menu-right');
if (this.options.dropdownAlignRight === true) this.$menu.addClass('dropdown-menu-right');

if (typeof id !== 'undefined') {
this.$button.attr('data-id', id);
Expand Down Expand Up @@ -779,13 +778,24 @@
// fall back to jQuery if getComputedStyle is not supported
menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,
$menu = menuStyle ? null : $(menu),
menuPadding = parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +
parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +
parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +
parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),
menuExtras = menuPadding +
menuPadding = {
vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +
parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +
parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +
parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),
horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) +
parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) +
parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) +
parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth'))
},
menuExtras = {
vert: menuPadding.vert +
parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +
parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2;
parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2,
horiz: menuPadding.horiz +
parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) +
parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2
}

document.body.removeChild(newElement);

Expand Down Expand Up @@ -813,6 +823,7 @@
$menuInner = this.$menuInner,
$window = $(window),
selectHeight = this.$newElement[0].offsetHeight,
selectWidth = this.$newElement[0].offsetWidth,
liHeight = this.sizeInfo['liHeight'],
headerHeight = this.sizeInfo['headerHeight'],
searchHeight = this.sizeInfo['searchHeight'],
Expand All @@ -823,15 +834,22 @@
menuExtras = this.sizeInfo['menuExtras'],
notDisabled = this.options.hideDisabled ? '.disabled' : '',
menuHeight,
menuWidth,
getHeight,
getWidth,
selectOffsetTop,
selectOffsetBot,
posVert = function () {
selectOffsetTop = that.$newElement.offset().top - $window.scrollTop();
selectOffsetLeft,
selectOffsetRight,
getPos = function() {
var pos = that.$newElement.offset();
selectOffsetTop = pos.top - $window.scrollTop();
selectOffsetBot = $window.height() - selectOffsetTop - selectHeight;
selectOffsetLeft = pos.left - $window.scrollLeft();
selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth;
};

posVert();
getPos();

if (this.options.size === 'auto') {
var getSize = function () {
Expand All @@ -849,25 +867,35 @@
lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),
optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');

posVert();
menuHeight = selectOffsetBot - menuExtras;
getPos();
menuHeight = selectOffsetBot - menuExtras.vert;
menuWidth = selectOffsetRight - menuExtras.horiz;

if (that.options.container) {
if (!$menu.data('height')) $menu.data('height', $menu.height());
getHeight = $menu.data('height');

if (!$menu.data('width')) $menu.data('width', $menu.width());
getWidth = $menu.data('width');
} else {
getHeight = $menu.height();
getWidth = $menu.width();
}

if (that.options.dropupAuto) {
that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);
that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);
}

if (that.$newElement.hasClass('dropup')) {
menuHeight = selectOffsetTop - menuExtras;
menuHeight = selectOffsetTop - menuExtras.vert;
}

if (that.options.dropdownAlignRight === 'auto') {
$menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth));
}

if ((lisVisible.length + optGroup.length) > 3) {
minHeight = liHeight * 3 + menuExtras - 2;
minHeight = liHeight * 3 + menuExtras.vert - 2;
} else {
minHeight = 0;
}
Expand All @@ -878,9 +906,9 @@
'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'
});
$menuInner.css({
'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding + 'px',
'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px',
'overflow-y': 'auto',
'min-height': Math.max(minHeight - menuPadding, 0) + 'px'
'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px'
});
};
getSize();
Expand All @@ -889,7 +917,7 @@
} else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {
var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),
divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;
menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding;
menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;

if (that.options.container) {
if (!$menu.data('height')) $menu.data('height', $menu.height());
Expand All @@ -900,15 +928,15 @@

if (that.options.dropupAuto) {
//noinspection JSUnusedAssignment
this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);
this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);
}
$menu.css({
'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',
'overflow': 'hidden',
'min-height': ''
});
$menuInner.css({
'max-height': menuHeight - menuPadding + 'px',
'max-height': menuHeight - menuPadding.vert + 'px',
'overflow-y': 'auto',
'min-height': ''
});
Expand Down

0 comments on commit 1daf83f

Please sign in to comment.