|
1 | 1 | uis.directive('uiSelect',
|
2 |
| - ['$document', 'uiSelectConfig', 'uiSelectMinErr', '$compile', '$parse', '$timeout', |
3 |
| - function($document, uiSelectConfig, uiSelectMinErr, $compile, $parse, $timeout) { |
| 2 | + ['$document', 'uiSelectConfig', 'uiSelectMinErr', 'uisOffset', '$compile', '$parse', '$timeout', |
| 3 | + function($document, uiSelectConfig, uiSelectMinErr, uisOffset, $compile, $parse, $timeout) { |
4 | 4 |
|
5 | 5 | return {
|
6 | 6 | restrict: 'EA',
|
@@ -162,6 +162,62 @@ uis.directive('uiSelect',
|
162 | 162 | $document.off('click', onDocumentClick);
|
163 | 163 | });
|
164 | 164 |
|
| 165 | + // Support for appending the select field to the body when its open |
| 166 | + var appendToBody = scope.$eval(attrs.appendToBody); |
| 167 | + if (appendToBody !== undefined ? appendToBody : uiSelectConfig.appendToBody) { |
| 168 | + scope.$watch('$select.open', function(isOpen) { |
| 169 | + if (isOpen) { |
| 170 | + positionDropdown(); |
| 171 | + } else { |
| 172 | + resetDropdown(); |
| 173 | + } |
| 174 | + }); |
| 175 | + |
| 176 | + // Move the dropdown back to its original location when the scope is destroyed. Otherwise |
| 177 | + // it might stick around when the user routes away or the select field is otherwise removed |
| 178 | + scope.$on('$destroy', function() { |
| 179 | + resetDropdown(); |
| 180 | + }); |
| 181 | + } |
| 182 | + |
| 183 | + // Hold on to a reference to the .ui-select-container element for appendToBody support |
| 184 | + var placeholder = null; |
| 185 | + |
| 186 | + function positionDropdown() { |
| 187 | + // Remember the absolute position of the element |
| 188 | + var offset = uisOffset(element); |
| 189 | + |
| 190 | + // Clone the element into a placeholder element to take its original place in the DOM |
| 191 | + placeholder = angular.element('<div class="ui-select-placeholder"></div>'); |
| 192 | + placeholder[0].style.width = offset.width + 'px'; |
| 193 | + placeholder[0].style.height = offset.height + 'px'; |
| 194 | + element.after(placeholder); |
| 195 | + |
| 196 | + // Now move the actual dropdown element to the end of the body |
| 197 | + $document.find('body').append(element); |
| 198 | + |
| 199 | + element[0].style.position = 'absolute'; |
| 200 | + element[0].style.left = offset.left + 'px'; |
| 201 | + element[0].style.top = offset.top + 'px'; |
| 202 | + element[0].style.width = offset.width + 'px'; |
| 203 | + } |
| 204 | + |
| 205 | + function resetDropdown() { |
| 206 | + if (placeholder === null) { |
| 207 | + // The dropdown has not actually been display yet, so there's nothing to reset |
| 208 | + return; |
| 209 | + } |
| 210 | + |
| 211 | + // Move the dropdown element back to its original location in the DOM |
| 212 | + placeholder.replaceWith(element); |
| 213 | + placeholder = null; |
| 214 | + |
| 215 | + element[0].style.position = ''; |
| 216 | + element[0].style.left = ''; |
| 217 | + element[0].style.top = ''; |
| 218 | + element[0].style.width = ''; |
| 219 | + } |
| 220 | + |
165 | 221 | // Move transcluded elements to their correct position in main template
|
166 | 222 | transcludeFn(scope, function(clone) {
|
167 | 223 | // See Transclude in AngularJS http://blog.omkarpatil.com/2012/11/transclude-in-angularjs.html
|
|
0 commit comments