Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Add md-autocomplete-snap="width" #7750

Merged
merged 7 commits into from
Dec 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
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
66 changes: 65 additions & 1 deletion src/components/autocomplete/autocomplete.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2564,4 +2564,68 @@ describe('<md-autocomplete>', function() {
element.remove();
});

});
describe('md-autocomplete-snap', function() {
it('should match the width of the snap element if width is set', inject(function($timeout, $material) {
var template = '\
<div style="width: 1000px" md-autocomplete-snap="width">\
<md-autocomplete\
md-selected-item="selectedItem"\
md-search-text="searchText"\
md-items="item in match(searchText)"\
md-item-text="item.display"\
placeholder="placeholder"\
style="width:200px">\
<span md-highlight-text="searchText">{{item.display}}</span>\
</md-autocomplete>\
</div>';
var scope = createScope();
var element = compile(template, scope);
var autoEl = element.find('md-autocomplete');
var ctrl = autoEl.controller('mdAutocomplete');
var ul = element.find('ul');

angular.element(document.body).append(element);

$material.flushInterimElement();
ctrl.focus();

autoEl.scope().searchText = 'fo';
waitForVirtualRepeat(autoEl);

expect(ul[0].offsetWidth).toBe(1000);
element.remove();
}));

it('should match the width of the wrap element if width is not set', inject(function($timeout, $material) {
var template = '\
<div style="width: 1000px" md-autocomplete-snap>\
<md-autocomplete\
md-selected-item="selectedItem"\
md-search-text="searchText"\
md-items="item in match(searchText)"\
md-item-text="item.display"\
placeholder="placeholder"\
style="width:200px">\
<span md-highlight-text="searchText">{{item.display}}</span>\
</md-autocomplete>\
</div>';
var scope = createScope();
var element = compile(template, scope);
var autoEl = element.find('md-autocomplete');
var ctrl = autoEl.controller('mdAutocomplete');
var ul = element.find('ul');

angular.element(document.body).append(element);

$material.flushInterimElement();
ctrl.focus();

autoEl.scope().searchText = 'fo';
waitForVirtualRepeat(autoEl);

expect(ul[0].offsetWidth).toBe(200);
element.remove();
}));
});

});
34 changes: 26 additions & 8 deletions src/components/autocomplete/js/autocompleteController.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,32 +251,50 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
* Gathers all of the elements needed for this controller
*/
function gatherElements () {

var snapWrap = gatherSnapWrap();

elements = {
main: $element[0],
scrollContainer: $element[0].querySelector('.md-virtual-repeat-container'),
scroller: $element[0].querySelector('.md-virtual-repeat-scroller'),
ul: $element.find('ul')[0],
input: $element.find('input')[0],
wrap: $element.find('md-autocomplete-wrap')[0],
wrap: snapWrap.wrap,
snap: snapWrap.snap,
root: document.body
};

elements.li = elements.ul.getElementsByTagName('li');
elements.snap = getSnapTarget();
elements.$ = getAngularElements(elements);

inputModelCtrl = elements.$.input.controller('ngModel');
}

/**
* Finds the element that the menu will base its position on
* @returns {*}
* Gathers the snap and wrap elements
*
*/
function getSnapTarget () {
for (var element = $element; element.length; element = element.parent()) {
if (angular.isDefined(element.attr('md-autocomplete-snap'))) return element[ 0 ];
function gatherSnapWrap() {
var element;
var value;
for (element = $element; element.length; element = element.parent()) {
value = element.attr('md-autocomplete-snap');
if (angular.isDefined(value)) break;
}
return elements.wrap;

if (element.length) {
return {
snap: element[0],
wrap: (value.toLowerCase() === 'width') ? element[0] : $element.find('md-autocomplete-wrap')[0]
};
}

var wrap = $element.find('md-autocomplete-wrap')[0];
Copy link
Contributor

Choose a reason for hiding this comment

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

You could move this above the if on line 225 so that you could reuse it on line 229.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

return {
snap: wrap,
wrap: wrap
};
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/components/autocomplete/js/autocompleteDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,15 @@ angular
*
* There is an example below of how this should look.
*
* ### Snapping Drop-Down
*
* You can cause the autocomplete drop-down to snap to an ancestor element by applying the
* `md-autocomplete-snap` attribute to that element. You can also snap to the width of
* the `md-autocomplete-snap` element by setting the attribute's value to `width`
* (ie. `md-autocomplete-snap="width"`).
*
* ### Notes
*
* **Autocomplete Dropdown Items Rendering**
*
* The `md-autocomplete` uses the the <a ng-href="api/directive/mdVirtualRepeatContainer">VirtualRepeat</a>
Expand Down