From 47b55d12304a8ced2590e6213c107bd103ab0f68 Mon Sep 17 00:00:00 2001 From: Christopher Lenz Date: Thu, 12 Mar 2015 18:01:39 +0100 Subject: [PATCH 1/2] Fix for `appendToBody` support: remember the original inline style width of the select element, so that it can be properly restored after it gets moved back to its original location. --- src/uiSelectDirective.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/uiSelectDirective.js b/src/uiSelectDirective.js index 5706f1b34..589adaecc 100644 --- a/src/uiSelectDirective.js +++ b/src/uiSelectDirective.js @@ -181,7 +181,8 @@ uis.directive('uiSelect', } // Hold on to a reference to the .ui-select-container element for appendToBody support - var placeholder = null; + var placeholder = null, + originalWidth = ''; function positionDropdown() { // Remember the absolute position of the element @@ -193,6 +194,10 @@ uis.directive('uiSelect', placeholder[0].style.height = offset.height + 'px'; element.after(placeholder); + // Remember the original value of the element width inline style, so it can be restored + // when the dropdown is closed + originalWidth = element[0].style.width; + // Now move the actual dropdown element to the end of the body $document.find('body').append(element); @@ -215,7 +220,7 @@ uis.directive('uiSelect', element[0].style.position = ''; element[0].style.left = ''; element[0].style.top = ''; - element[0].style.width = ''; + element[0].style.width = originalWidth; } // Move transcluded elements to their correct position in main template From a221d11f4568b7b4f3d14ee7f728a1063edd3786 Mon Sep 17 00:00:00 2001 From: Christopher Lenz Date: Thu, 12 Mar 2015 18:04:42 +0100 Subject: [PATCH 2/2] Another fix for `appendToBody` support: for some reason that I don't comprehend right now, the transclude function needs to be called before the `appendToBody` attribute is wire up. Otherwise the height measurement is incorrect when the the dropdown is opened (using the Bootstrap theme) because both the `ui-select-match` and the `ui-select-choices` elements are visible at the same time. I'd appreciate if anyone could explain this, but this change does the trick for me. --- src/uiSelectDirective.js | 52 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/uiSelectDirective.js b/src/uiSelectDirective.js index 589adaecc..76df08b67 100644 --- a/src/uiSelectDirective.js +++ b/src/uiSelectDirective.js @@ -162,6 +162,32 @@ uis.directive('uiSelect', $document.off('click', onDocumentClick); }); + // Move transcluded elements to their correct position in main template + transcludeFn(scope, function(clone) { + // See Transclude in AngularJS http://blog.omkarpatil.com/2012/11/transclude-in-angularjs.html + + // One day jqLite will be replaced by jQuery and we will be able to write: + // var transcludedElement = clone.filter('.my-class') + // instead of creating a hackish DOM element: + var transcluded = angular.element('
').append(clone); + + var transcludedMatch = transcluded.querySelectorAll('.ui-select-match'); + transcludedMatch.removeAttr('ui-select-match'); //To avoid loop in case directive as attr + transcludedMatch.removeAttr('data-ui-select-match'); // Properly handle HTML5 data-attributes + if (transcludedMatch.length !== 1) { + throw uiSelectMinErr('transcluded', "Expected 1 .ui-select-match but got '{0}'.", transcludedMatch.length); + } + element.querySelectorAll('.ui-select-match').replaceWith(transcludedMatch); + + var transcludedChoices = transcluded.querySelectorAll('.ui-select-choices'); + transcludedChoices.removeAttr('ui-select-choices'); //To avoid loop in case directive as attr + transcludedChoices.removeAttr('data-ui-select-choices'); // Properly handle HTML5 data-attributes + if (transcludedChoices.length !== 1) { + throw uiSelectMinErr('transcluded', "Expected 1 .ui-select-choices but got '{0}'.", transcludedChoices.length); + } + element.querySelectorAll('.ui-select-choices').replaceWith(transcludedChoices); + }); + // Support for appending the select field to the body when its open var appendToBody = scope.$eval(attrs.appendToBody); if (appendToBody !== undefined ? appendToBody : uiSelectConfig.appendToBody) { @@ -222,32 +248,6 @@ uis.directive('uiSelect', element[0].style.top = ''; element[0].style.width = originalWidth; } - - // Move transcluded elements to their correct position in main template - transcludeFn(scope, function(clone) { - // See Transclude in AngularJS http://blog.omkarpatil.com/2012/11/transclude-in-angularjs.html - - // One day jqLite will be replaced by jQuery and we will be able to write: - // var transcludedElement = clone.filter('.my-class') - // instead of creating a hackish DOM element: - var transcluded = angular.element('
').append(clone); - - var transcludedMatch = transcluded.querySelectorAll('.ui-select-match'); - transcludedMatch.removeAttr('ui-select-match'); //To avoid loop in case directive as attr - transcludedMatch.removeAttr('data-ui-select-match'); // Properly handle HTML5 data-attributes - if (transcludedMatch.length !== 1) { - throw uiSelectMinErr('transcluded', "Expected 1 .ui-select-match but got '{0}'.", transcludedMatch.length); - } - element.querySelectorAll('.ui-select-match').replaceWith(transcludedMatch); - - var transcludedChoices = transcluded.querySelectorAll('.ui-select-choices'); - transcludedChoices.removeAttr('ui-select-choices'); //To avoid loop in case directive as attr - transcludedChoices.removeAttr('data-ui-select-choices'); // Properly handle HTML5 data-attributes - if (transcludedChoices.length !== 1) { - throw uiSelectMinErr('transcluded', "Expected 1 .ui-select-choices but got '{0}'.", transcludedChoices.length); - } - element.querySelectorAll('.ui-select-choices').replaceWith(transcludedChoices); - }); }; } };