Skip to content
This repository was archived by the owner on Oct 2, 2019. It is now read-only.

Add an append-to-body attribute for improved layering. #718

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/bootstrap/choices.tpl.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<ul class="ui-select-choices ui-select-choices-content dropdown-menu"
style="display: block"
role="listbox"
ng-show="$select.items.length > 0">
ng-show="$select.open">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why this was changed? We have so many nuanced use cases for this project, I worry this could break the template for one of the many in our large array.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll back that out, it isn't needed, and results in empty dropdown appearing with the Bootstrap theme.

<li class="ui-select-choices-group" id="ui-select-choices-{{ $select.generatedId }}" >
<div class="divider" ng-show="$select.isGrouped && $index > 0"></div>
<div ng-show="$select.isGrouped" class="ui-select-choices-group-label dropdown-header" ng-bind="$group.name"></div>
Expand Down
12 changes: 6 additions & 6 deletions src/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
}

/* See Scrollable Menu with Bootstrap 3 http://stackoverflow.com/questions/19227496 */
.ui-select-bootstrap > .ui-select-choices {
.ui-select-choices {
width: 100%;
height: auto;
max-height: 200px;
Expand Down Expand Up @@ -163,7 +163,7 @@
border-right: 1px solid #428bca;
}

.ui-select-bootstrap .ui-select-choices-row>a {
.ui-select-choices-row>a {
display: block;
padding: 3px 20px;
clear: both;
Expand All @@ -173,21 +173,21 @@
white-space: nowrap;
}

.ui-select-bootstrap .ui-select-choices-row>a:hover, .ui-select-bootstrap .ui-select-choices-row>a:focus {
.ui-select-choices-row>a:hover, .ui-select-choices-row>a:focus {
text-decoration: none;
color: #262626;
background-color: #f5f5f5;
}

.ui-select-bootstrap .ui-select-choices-row.active>a {
.ui-select-choices-row.active>a {
color: #fff;
text-decoration: none;
outline: 0;
background-color: #428bca;
}

.ui-select-bootstrap .ui-select-choices-row.disabled>a,
.ui-select-bootstrap .ui-select-choices-row.active.disabled>a {
.ui-select-choices-row.disabled>a,
.ui-select-choices-row.active.disabled>a {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mentioned in your PR that you only tested Bootstrap, removing the CSS class namespace would very likely have impact on the other themes, so please test them as well, seems likely this could cause a regression.

color: #777;
cursor: not-allowed;
background-color: #fff;
Expand Down
22 changes: 21 additions & 1 deletion src/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,5 +133,25 @@ var uis = angular.module('ui.select', [])
return function(matchItem, query) {
return query && matchItem ? matchItem.replace(new RegExp(escapeRegexp(query), 'gi'), '<span class="ui-select-highlight">$&</span>') : matchItem;
};
});
})

/**
* A read-only equivalent of jQuery's offset function: http://api.jquery.com/offset/
*
* Taken from AngularUI Bootstrap Position:
* See https://github.com/angular-ui/bootstrap/blob/master/src/position/position.js#L70
*/
.factory('uisOffset',
['$document', '$window',
function ($document, $window) {

return function(element) {
var boundingClientRect = element[0].getBoundingClientRect();
return {
width: boundingClientRect.width || element.prop('offsetWidth'),
height: boundingClientRect.height || element.prop('offsetHeight'),
top: boundingClientRect.top + ($window.pageYOffset || $document[0].documentElement.scrollTop),
left: boundingClientRect.left + ($window.pageXOffset || $document[0].documentElement.scrollLeft)
};
};
}]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for keeping this lightweight 👍

3 changes: 2 additions & 1 deletion src/select2/choices.tpl.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<ul class="ui-select-choices ui-select-choices-content select2-results">
<ul class="ui-select-choices ui-select-choices-content select2-results"
ng-style="{top: position.top+'px', left: position.left+'px'}">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the impression that you were making this directive "opt-in", meaning that it only impacts the directive if invoked. This gives me the opposite impression, can you explain a bit for me?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll back that out, it was a leftover from earlier experimentation. The styles are set in the positionDropdown() function.

<li class="ui-select-choices-group" ng-class="{'select2-result-with-children': $select.choiceGrouped($group) }">
<div ng-show="$select.choiceGrouped($group)" class="ui-select-choices-group-label select2-result-label" ng-bind="$group.name"></div>
<ul role="listbox"
Expand Down
3 changes: 2 additions & 1 deletion src/selectize/choices.tpl.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<div ng-show="$select.open" class="ui-select-choices selectize-dropdown single">
<div ng-show="$select.open" class="ui-select-choices selectize-dropdown single"
ng-style="{top: position.top+'px', left: position.left+'px'}">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same question.

<div class="ui-select-choices-content selectize-dropdown-content">
<div class="ui-select-choices-group optgroup" role="listbox">
<div ng-show="$select.isGrouped" class="ui-select-choices-group-label optgroup-header" ng-bind="$group.name"></div>
Expand Down
43 changes: 41 additions & 2 deletions src/uiSelectChoicesDirective.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
uis.directive('uiSelectChoices',
['uiSelectConfig', 'RepeatParser', 'uiSelectMinErr', '$compile',
function(uiSelectConfig, RepeatParser, uiSelectMinErr, $compile) {
['uiSelectConfig', 'RepeatParser', 'uiSelectMinErr', 'uisOffset', '$compile', '$document',
function(uiSelectConfig, RepeatParser, uiSelectMinErr, uisOffset, $compile, $document) {

return {
restrict: 'EA',
Expand All @@ -21,6 +21,7 @@ uis.directive('uiSelectChoices',

// var repeat = RepeatParser.parse(attrs.repeat);
var groupByExp = attrs.groupBy;
var appendToBody = scope.$eval(attrs.appendToBody);

$select.parseRepeatAttr(attrs.repeat, groupByExp); //Result ready at $select.parserResult

Expand Down Expand Up @@ -60,6 +61,44 @@ uis.directive('uiSelectChoices',
var refreshDelay = scope.$eval(attrs.refreshDelay);
$select.refreshDelay = refreshDelay !== undefined ? refreshDelay : uiSelectConfig.refreshDelay;
});

if (appendToBody) {
scope.$watch('$select.open', function(isOpen) {
if (isOpen) {
positionDropdown();
} else {
resetDropdown();
}
});
}

// Hold on to a reference to the .ui-select-container element for appendToBody support
var parent = element.parent();

function positionDropdown() {
if (!appendToBody) {
return;
}

// Move the dropdown element to the end of the body
$document.find('body').append(element);

var position = uisOffset(parent);
element[0].style.left = position.left + 'px';
element[0].style.top = position.top + parent[0].offsetHeight + 'px';
element[0].style.width = parent[0].offsetWidth + 'px';
}

function resetDropdown() {
if (!appendToBody) {
return;
}
parent.append(element);
element[0].style.left = '';
element[0].style.top = '';
element[0].style.width = '';
}

};
}
};
Expand Down