Material: Autocomplete dropdown is too narrow when inside of md-chips

Created on 3 Sep 2015  路  40Comments  路  Source: angular/material

Hi,

if I use a autocomplete in a chips the dropdown items are too short, is there any way to influence the dropdown's width?
screen shot 2015-09-03 at 11 22 55

http://codepen.io/mxab/pen/xwbZBL?editors=101

minor Pull Request fixed

Most helpful comment

So, I think I finally figured out the real reason this is happening: the autocomplete was updated in 0.11 to use the virtual repeat for performance reasons. Part of this change also updated the autocomplete dropdown to set it's size based on the autocomplete's input size.

So, a quick & dirty workaround is to set the size of the input in your CSS:

.md-chips .md-chip-input-container md-autocomplete input {
    width: 400px;
}

This should make the autocomplete the right size and still provides a decent experience; however, I think the proper fix would be to figure out why the autocomplete manually sets this, and perhaps give users more control.

@r0b- @lievenjanssen @tirana Can you guys give this a try and provide some feedback on whether or not this workaround helps, or if your particular use-cases require a different solution?

All 40 comments

same here. 0.10.1 and 0.11.0-rc1

I was looking into this the other day but didn't have time to figure out why the CSS wasn't working like it should, as the inner items are the correct size. If either of you have a moment to dig in, some more information about exactly why the width is off would be very much appreciated.

the width is set in directive programmatically.

@nestorneto From what I was seeing, the min-width/max-width was set programmatically, but not the actual width. Are you seeing the actual width property being set?

it didnt set width. maybe its the problem. the component assumes the min-width

@nestorneto That's the part I couldn't figure out. Just setting min/max shouldn't actually affect it at all, it should still be sizing to the items contents as long as it's between min/max. I think there is an odd CSS interaction going on here. We'll try to track it down.

This is what's causing the items to be 16px not as wide (if you set it to 0 it will fill the whole area):

.md-virtual-repeat-container .md-virtual-repeat-offsetter {
 .....
right: 16px;
... }

There is also the "sizer" which is causing the scrollbars, if you take it out the scrollbars go away, but I am sure it has a use :)

<div class="md-virtual-repeat-sizer" style="height: 48px;"></div>

It would be great if you could also fix the height of the dropdown when there are no matches - it defaults to 226 px because the resizing does not execute if there are no items:

VirtualRepeatController.prototype.containerUpdated = function() { 
  // If itemSize is unknown, attempt to measure it.
    if (!this.itemSize) {
    this.unwatchItemSize_ = this.$scope.$watchCollection(
        this.repeatListExpression,
        angular.bind(this, function(items) {
          if (items && items.length) {
            this.$$rAF(angular.bind(this, this.readItemSize_));
          }

Finally, this is not really related to these issues, but is there a way to add a link or a button in the md-not-found template? I tried both but the click event doesn't get fired, or perhaps it is intended to work this way? Thanks!

+1

+1

I would love to have this fixed in 0.11.1 since it's a bug introduced in 0.11. It's breaking for our application. For us priority is more then medium.

+1 to increase priority - a lot of our users reported about it :(

So, I think I finally figured out the real reason this is happening: the autocomplete was updated in 0.11 to use the virtual repeat for performance reasons. Part of this change also updated the autocomplete dropdown to set it's size based on the autocomplete's input size.

So, a quick & dirty workaround is to set the size of the input in your CSS:

.md-chips .md-chip-input-container md-autocomplete input {
    width: 400px;
}

This should make the autocomplete the right size and still provides a decent experience; however, I think the proper fix would be to figure out why the autocomplete manually sets this, and perhaps give users more control.

@r0b- @lievenjanssen @tirana Can you guys give this a try and provide some feedback on whether or not this workaround helps, or if your particular use-cases require a different solution?

yes. it works! thanks!

Thanks for finding the workaround - it's working well for me.

Hmmm, I have a responsive site that needs different widths depending on the screen size.
If I set the width by css breakpoints the container width is changed but the virtual repeat seems to work with the old item heights and things get messed up if the text wraps and item height changes..

Is there a way to let the virtual repeat recalculate or sth like that?

+1

Same as @r0b- here.
Different autocomplete widths, but for now I can add some classes, set diffenret widths and hope page isn't risized hehe

+1

I agree and am confused with this issue. I also discovered that the actual width of the dropdown menu (the md-virtual-repeat-container and all child elements) is set by the min-width value on the md-virtual-repeat container element, rather than expanding to a width that is between min-width and max-width and that also expands to display the full length of all the content of all the child elements. Also interesting, when you set the min-width to "0 !important" via CSS, thereby restoring the default value, it will override the programmatically established min-width on the md-virtual-repeat-container element, but the md-virtual-repeat-container element will then not appear when values are typed in the md-autocomplete input element. What I am wondering is if there is another CSS setting on the element that forces the menu to set its width equal to the min-width? Or, if there is a CSS setting that suppresses the impact of the menu-item content to set the width of parent elements? Otherwise, I cannot determine why the width is not set to a width that is between min-width and max-width that also expands to a width that displays all of the child element contents.

I used another workaround.

I didn't put the autocomplete tag inside the chips one and hid chips input field.

<md-autocomplete ...>
</md-autocomplete>
<md-chips ...>
</md-chips>



.md-chips .md-chip-input-container input:not([type]) {
    display: none
}

This should be a flexible workaround for a responsive layout.

My two cents.

+1 Does anybody have a workaround? I seem to have something working, will try to submit a PR. Testing it now

Using this as a workaround:

.md-chips .md-chip-input-container {
    width: 100%;
}

.md-chips .md-chip-input-container md-autocomplete md-autocomplete-wrap {
    width: 100%;
}

This will always create a full line for autocomplete and while it may be uglier, it's fully functional. The ideal setting is a table/grid like structure where the last element uses the remaining width (if there is enough space or else make a new row). This would need a bigger rewrite which I don't have the time, personally, to do.

+1

+1

+1

+1

I have a solution for this. PR #7750 would allow a parent element to be used to evaluate the the width of the autocomplete drop down by adding the md-autocomplete-snap="width" attribute to it. This is similar to how the anchor element can be picked by adding the md-autocomplete-snap attribute to a parent element.
autocompleteoverride
I have a working example here https://codepen.io/allenperl/pen/KzmQwr

+1

This issue is closed as part of our deprecation effort.
For details, see our post Spring Cleaning 2016.

For what this worth, this is my solution for responsive design
First, I get the width of the element or window and then I kept it updated
Second, I added ng-style (ng-style="vm.windowWidth") or any other directive that is more convenient

`vm.windowWidth = {
"min-width": (window.innerWidth * percentageVar)
};

angular.element($window).bind('resize', function () {
var windowWidth = ($window.innerWidth * percentageVar);
vm.windowWidth = {
"min-width": windowWidth
};
});`

@ThomasBurleson
What is the status to increase the width of the dropdown menu?
I see a lot of issue on google about md-autocomplete and width, but I can't find any solution right now.

I tried to use the "md-menu-class" to force a min-with to the items, but the main container "md-virtual-repeat-container" hide it with his width and a overflow hidden.

@jbdemonte Did you see the comment from @aperl above talking about the md-autocomplete-snap="width" option?

https://github.com/angular/material/issues/4450#issuecomment-201354077

I think this will do what you need.

@jbdemonte is there any chance of getting #4450 merged?

@topherfangio Yes, I saw that commit, but, It is not merged

@jbdemonte Apologies! I thought it got merged in a long time ago. I'm talking to the team now about it to see why it was closed.

@topherfangio a few months back there was a large sweep where nearly all issues were closed in order to make the back log more manageable. This issue was closed in that sweep.

@aperl Indeed; however, I didn't realize this got caught up in the mix since it was already marked as needs: merge. I'll see about reopening it.

Reopening this and associated PR.

@topherfangio really looking forward to this fix. Any update on the merge?

This fixed has already been merged with PR #7750 but this issue was never closed. Closing now.

The original problem, that despite the intention to have the drop-down increase freely based on content is not solved with this issue.

@nestorneto That's the part I couldn't figure out. Just setting min/max shouldn't actually affect it at all, it should still be sizing to the items contents as long as it's between min/max. I think there is an odd CSS interaction going on here. We'll try to track it down.

CSS is working as expected and there is no odd interaction. Simply every absolute positioned box is extracted from the flow. Absolute positioned boxes inside absolute positioned box are no excuse from this either.

To make the content define the width of the dropdown there can only be one level of absolute positioning. Currently there are 3.
virtual-container > scroller > offsetter.

Scroller and offsetter don't have to be absolute if the repeat-sizer itself becomes absolute positioned.

See here: https://codepen.io/gkormany/pen/pmaPvo

@gabor-kormany if you would like to propose a change, please open a new issue (that references this issue) rather than commenting on a closed issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rdantonio picture rdantonio  路  3Comments

kasajian picture kasajian  路  3Comments

chriseyhorn picture chriseyhorn  路  3Comments

ghost picture ghost  路  3Comments

rtprakash picture rtprakash  路  3Comments