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

Add md-dropdown-position option to mdAutocomplete. #9774

Merged
merged 1 commit into from
Oct 21, 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
48 changes: 48 additions & 0 deletions src/components/autocomplete/autocomplete.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2246,6 +2246,54 @@ describe('<md-autocomplete>', function() {
document.body.removeChild(parent[0]);
}));

it('should allow dropdown position to be specified', inject(function($timeout, $window) {
var scope = createScope();

scope.match = fakeItemMatch;
scope.position = 'top';

var template = '<div>' +
'<md-autocomplete ' +
'md-search-text="searchText" ' +
'md-items="item in match(searchText)" ' +
'md-item-text="item" ' +
'md-min-length="0" ' +
'md-dropdown-position="{{position}}" ' +
'placeholder="placeholder">' +
'<span md-highlight-text="searchText">{{item}}</span>' +
'</md-autocomplete>' +
'</div>';

var parent = compile(template, scope);
var element = parent.find('md-autocomplete');
var ctrl = element.controller('mdAutocomplete');

// Add container to the DOM to be able to test the rect calculations.
document.body.appendChild(parent[0]);

$timeout.flush();

// Focus the autocomplete and trigger a query to be able to open the dropdown.
ctrl.focus();
scope.$apply('searchText = "Query 1"');
waitForVirtualRepeat(element);

var scrollContainer = document.body.querySelector('.md-virtual-repeat-container');

expect(scrollContainer).toBeTruthy();
expect(scrollContainer.style.top).toBe('auto');
expect(scrollContainer.style.bottom).toMatch(/[0-9]+px/);

// Change position and resize to force a DOM update.
scope.$apply('position = "bottom"');
angular.element($window).triggerHandler('resize');

expect(scrollContainer.style.top).toMatch(/[0-9]+px/);
expect(scrollContainer.style.bottom).toBe('auto');

parent.remove();
}));

});

describe('md-highlight-text', function() {
Expand Down
9 changes: 8 additions & 1 deletion src/components/autocomplete/js/autocompleteController.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,13 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
left = hrect.left - root.left,
width = hrect.width,
offset = getVerticalOffset(),
position = $scope.dropdownPosition,
styles;

// Automatically determine dropdown placement based on available space in viewport.
Copy link
Member

Choose a reason for hiding this comment

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

While you are at it, can you add an empty line before the comment (just looks better then)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if (!position) {
position = (top > bot && root.height - hrect.bottom - MENU_PADDING < dropdownHeight) ? 'top' : 'bottom';
}
// Adjust the width to account for the padding provided by `md-input-container`
if ($attrs.mdFloatingLabel) {
left += INPUT_PADDING;
Expand All @@ -124,7 +130,8 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
minWidth: width + 'px',
maxWidth: Math.max(hrect.right - root.left, root.right - hrect.left) - MENU_PADDING + 'px'
};
if (top > bot && root.height - hrect.bottom - MENU_PADDING < dropdownHeight) {

if (position === 'top') {
styles.top = 'auto';
styles.bottom = bot + 'px';
styles.maxHeight = Math.min(dropdownHeight, hrect.top - root.top - MENU_PADDING) + 'px';
Expand Down
4 changes: 3 additions & 1 deletion src/components/autocomplete/js/autocompleteDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ angular
* the dropdown.<br/><br/>
* When the dropdown doesn't fit into the viewport, the dropdown will shrink
* as less as possible.
* @param {string=} md-dropdown-position Overrides the default dropdown position. Options: `top`, `bottom`.
* @param {string=} ng-trim If set to false, the search text will be not trimmed automatically.
* Defaults to true.
* @param {string=} ng-pattern Adds the pattern validator to the ngModel of the search text.
Expand Down Expand Up @@ -230,7 +231,8 @@ function MdAutocomplete ($$mdSvgRegistry) {
menuClass: '@?mdMenuClass',
inputId: '@?mdInputId',
escapeOptions: '@?mdEscapeOptions',
dropdownItems: '=?mdDropdownItems'
dropdownItems: '=?mdDropdownItems',
dropdownPosition: '@?mdDropdownPosition'
},
compile: function(tElement, tAttrs) {
var attributes = ['md-select-on-focus', 'md-no-asterisk', 'ng-trim', 'ng-pattern'];
Expand Down