Angular Material - md-autocomplete dropdown's width - javascript

I'm using md-autocomplete from Angular Material: here
It seems the dropdown's width goes with the input field's width. If an item's text is too long, there is ellipsis.
However, I want to show full text of an item, while keeping the input field's width relatively short. That is, the dropdown's width should expand with its content.
I tried inspecting the styles of md-autocomplete's elements, but couldn't find any style that does the trick. Any idea?
EDIT:
Here are the style I ended up having:
.md-autocomplete-suggestions-container{
overflow-y:scroll
}
.md-autocomplete-suggestions-container .md-virtual-repeat-scroller{
position:static
}
.md-autocomplete-suggestions-container .md-virtual-repeat-sizer{
height:0 !important
}
.md-autocomplete-suggestions-container .md-virtual-repeat-offsetter{
position:static
}
However there is one more issue. The overflow-y:scroll always shows the vertial scroll bar even when not needed. If I change it to overflow-y:auto, the vertical scroll bar when present will create ellipsis. How do I solve this?

For anyone still facing the problem of autocomplete values being cropped because the panel width is only as wide as the field, the good news is that it has now been fixed, woohoo!
Angular Material Release 6.4.0 (2018-07-16) introduced the following feature,
autocomplete: allow panel to have a width value of auto (#11879) (8a5713e)
So now it's possible to just add the property panelWidth with the value auto and the panel will grow to fit the values.
<mat-autocomplete panelWidth="auto">
<mat-option value="myValue">Now an option with a long label will still be readable<option>
</mat-autocomplete>

You can use css to style md-virtual-repeat-container.
However, that would style every instance of md-virtual-repeat-container that you may have on your site (ie, md-autocomplete and md-virtual-repeat).
Unfortunately, there isn't an option to adjust individual md-autocomplete dropdowns at the moment. I created a ticket and pull request to hopefully solve this issue. Fingers crossed that this will be included in one of the future releases of Angular Material.
Best of luck!

You need to set class on your md-autocomplete element so you can target it in css. See this example
<md-autocomplete class="autocompletable"
md-min-length="0"
...
placeholder="US State?"
md-menu-class="autocompletable-contents">
<md-item-template>
<table>
<tr>
<td><span md-highlight-text="ctrl.searchText"
md-highlight-flags="^i">{{item.ok}}</span>
</td><td>Foo</td>
</tr>
</table>
</md-item-template>
<md-not-found>
No states matching "{{ctrl.searchText}}" were found.
<a ng-click="ctrl.newState(ctrl.searchText)">Create a new one!</a>
</md-not-found>
</md-autocomplete>
And then in css you need to do this
md-autocomplete.autocompletable{ width: 200px; }
.autocompletable-contents{ }
EDITS: Tested with materials 1.0.9

I know it very late but in materials 1.1.9 you can add an attribute md-menu-class on the md-autocomplete directive.
The class you add will reported on the .md-autocomplete-suggestions element in the virtual repeat. So you be able to customize the css for this autocomplete only.
exemple :
<md-autocomplete ... md-menu-class="search-field-autocomplete">
will generate
<ul class="md-autocomplete-suggestions search-field-autocomplete" ... >
<li md-virtual-repeat="item in $mdAutocompleteCtrl.matches" ...
so you can customize with css like :
.md-autocomplete-suggestions.search-field-autocomplete {
li {
color: red;
}
}

Related

Mat Chip List opon selection expands input

Giving the default behavior, when value is selected from a dropdown, MatChip appears within the input, but also expands it. I am a bit surprised this is the default behavior. Anyone can suggest how they fix it? Providing a forked StackBlitz demo (source take from Angular Material documentation):
DEMO
You can see in the images bellow - when chip selected, input becomes taller.
Problem
The problem is mat-form-field-infix class. When there are chips in the input, they increase the height.
Solution
You can set the minimal height for that class to be the same as when there are chips in the input. You can do it in the CSS file like this:
::ng-deep .mat-form-field-infix {
min-height: 32px;
}
Working example

React-select: weird look inside of react-table filter cell, is it problem with CSS?

I'm using React-table to represent my data and I wanted to filter every column using react-select with multiselect option. The problem is that select that I use look very weird when it is in filter table cell:
What I want to do/have:
search field is needed (sometimes there is a lot of options to select)
input with selected options should be fit to column width but heigh can change so if user select many items if they don't fit they should be moved to the next line
I've prepared fiddle - in the first column is the same situation as in my project. Maybe someone can help me with this issue? Thanks
https://codesandbox.io/s/react-table-custom-filtering-multiple-values-filter-tjtl3
I debugged the actual website of react-select
Link: https://react-select.com/home
This behavior is normal for the input box sizing, only issue is you are getting border for the input.
To Quickly solve that i will recommend you use css selector and target the search input for border
.ReactTable .Select-input input {
border: none;
}
Tried in your code and working as expected

adjust drop down menu height to show more options (AngularJS Material)

i'm new to Angularjs Material so maybe this is something obvious yet it seems i can't figure it out.
i have a multiple choice drop down menu which shows only 4 options when initially clicked on and the rest can be viewed/accessed by scrolling down. I'm trying to expand that view to another static number (e.g. to fit 8 options without scroll).
i found very similar question asked before:
Make multiple-select to adjust its height to fit options without scroll bar
however, it seems not to have any effect neither with "size" nor "ng-size"
here is my example:
<md-input-container>
<label>Providers</label>
<md-select ng-size="10" ng-model="vm.selectedProviders" ng-change="vm.prov()" multiple>
<md-optgroup label="Providers">
<md-option ng-value="provider.namep" ng-repeat="provider in vm.providers">{{provider.namep}}</md-option>
</md-optgroup>
</md-select>
</md-input-container>
Looking at the documentation of md-select, there doesn't seem to be an attribute that specifies the number of options to show.
So the other possible way is to change the maximum heights set by default in AngularJS Material. They're set like this:
md-select-menu, md-select-menu md-content {
max-height: 256px;
}
For me, it displays 5 options by default (not 4). So, I added this to my CSS:
md-select-menu, md-select-menu md-content {
max-height: 385px;
}
And it made all md-select tags fit 8 options instead of 5. The number doesn't have to be the same for you, so play with the height until you're satisfied.
Hope that helps.

Fixed header Table, on scroll using Jquery flickers in IE11 (internet explorer) on click of div scroll bar icon click.

FIXED HEADER TABLE ____When Clicking on scrollbar icon in ie11 flickers when using positioning as i cannot change the structure as it is dynamically coming from different sources and gets in table body structure
<tbody><tr></tr><tr></tr></tbody>
here is the fiddle attached works fine in chrome but when i check in ie it flickers horriblly when clicking on div vertical scrollbar below or above icon
Any Css or html solution is also acceptable until if there is no change in html structure
DEMOJs Fiddle Demo
JQUERY
$(document).ready(function() {
$('#theDiv').on('scroll', function () {
$('#headerRow td,#headerRow th').css({'position':'relative','background':'red','top':$('#theDiv').scrollTop()-1});
});
});
First we wrap #theDiv in a #theDivWrap (using jQuery) and use the css to style it...
The idea is to duplicate header row into a new div appended to #theDivWrap via JS
Now loop through table heading elements and create a div based similar styled heading which will come over table and is prepended to #theDivWrap and stays there forever even on scroll because wrap is not overflow auto...
https://jsfiddle.net/5dqnumh6/39/
Adjust negative margin bottom of .headerRow to suit your needs ;)
As Ie doesn't support overflow property for table group elements. So we can add a workaround to support the required behaviour. Add this css to your fiddle and try it will work.
tbody{display:block;height:auto;}
This will make your flicker go away in ie older versions. Although its a hack to make it work but there is no other pure css way. For more details and explanation you may want to read this link.
Updated fiddle is here.
But as you told me flickering not goes away.A workaround exists but it requires changing in ie settings. Go to internet options, navigate to advanced and scroll down until you see browsing section and uncheck "enable smooth scrolling". But I don't know whether it suits your requirement or not
This has been noted to be an IE11 bug, and according to this other SO question from 2014, shows up under the following conditions:
Three things can cause IE 11 flickering/choppy/delay for fixed
position element while scrolling:
If you have an "overflow: auto;" on the parent container element,
remove it.
Remove background-attachment:fixed; from the fixed position
element.
Remove border-radius from the fixed position element (mobile
IE only).
(Accepted answer by #Adamy)
Well, removing auto-overflow from your code takes away the whole purpose, so it's not the best solution here, and the others don't apply. What seems to work however (according to this MS Connect bug) is some HTML changes, separating the header row, and adding a custom scroll function to the actual table body. This JsFiddle page (kindly provided by folks that responded to the MS bug) has a working example:
https://jsfiddle.net/84y0vtyx/
(Including only part of the example with relevant comment. Full explanation requires reviewing the JsFiddle example.)
/* Only WinIE will fire this function. All other browsers scroll the TBODY element and not the DIV */
/* This is to hide the SELECT elements from scrolling over the fixed Header. WinIE only. */
/* toggleSelectBoxes added on 2005-01-28 */
/* Terence Ordona, portal[AT]imaputz[DOT]com */
window.onload = function() { addIEonScroll(); }
Hi here is my update based on your comment.
I copied the HTML part from your js Fiddle and just added this style tag to the above the table div and it works perfectly in microsoft edge and other browsers with no Jquery needed:
<style>
#headerRow
{
position: fixed !important;
top:0px;
background:Red;
}
</style>
////OLD
I apologies as you have mentioned that you cannot change the html table structure that comes down however see my old answer below which i wrote without this consideration. Can you consider using css to traverse the fixed table that comes down and apply a fixed position to the top header row? I have read that you can give a fixed position and a background color to a table row so that it remains fixed and the background prevents the text from overlapping How to make table row fixed at the top
You can use css to select the top row of the table:
Css:
table tr:first-child
{
position: fixed;
top:0px;
background:#FFF;
}
/// old answer:
Please may i suggest that you forget about using a document scroll event and just create a header with an absolute position if it is a div with an overflow scroll or a fixed position if it is just to remain fixed as the window scrolls. you can specify widths for your colums so that the fixed header lines up. so something along these lines (im just typing on my phone):
<table style="position:fixed; width:100% ">
<tr>
<th width="50%">
Test1
</th>
<th width="50%">
Test2
</th>
</tr>
</table>
<table style="margin-top:25px; width:100% ">
<tr>
<td width="50%">
a
</td>
<td width="50%">
b
</td>
</tr>
<tr>
<td width="50%">
c
</td>
<td width="50%">
d
</td>
</tr>
</table>
Especialy if we are talking cross browser compatibilty here- the simpler and most basic html/ css implementation the better. Css has provided us with a fixed class. There is no need to use jquery to watch your documents scroll.
I use this one my site:
https://raw.githubusercontent.com/jmosbech/StickyTableHeaders/master/js/jquery.stickytableheaders.min.js
Simply load it in your <head></head> section of the page and it will float the header of any table loaded on that page. It's cross-browser and gets the job done with no additional tricks, just plug & play.

Limit text size by lines in angular ng-repeat

I want to limit the number of lines that a <p> can have, based on a text in ng-repeat, my ng-repeat loop:
<ul class="list-unstyled">
<li ng-repeat="comment in ad.comments>
<p id="moreButton"> {{comment.text | limitTo: CommentTextLimit}}
<a ng-show="comment.text.length>25"> <span id="moreLess" span ng-click="changeLength(CommentTextLimit)" >{{moreLessText}}</span></a>
</p>
</li>
</ul>
I want to limit the comment.text field and if the user clicks on the show more button more lines will appear, the first problem is that any changes apples to all comments instead of one, the second one is that I want to limit by rows and not by comment.text.length
In the past I have used 2 different techniques to solve this. Sometimes I would just concatenate the length of the string according to a fixed length.
Since you said you don't want to use this technique, The other way I did it a few times, was adding the css style max-height and overflow:hidden to the bounding element.
Then you can create a directive that will detect the actual height of the element, and tell if part of the element is hidden because of the max-height.
(You can do this like this : https://stackoverflow.com/a/143889/230377)
If the element is "overflowing" then it means part of the text is hidden, and then I would display a "see more" link at the bottom right corner of the bounding element.
I would place this element in the bottom right corner by using css (and not just adding it inline)
The css of the "see more" element should look something like this :
.see-more-link {
position:absolute;
bottom:0; right:0;
}
You also need to set the bounding element to have position:relative.
Sorry, I wanted to add a link to a working example of this in one of my github repos, but I can't find it now... Hope this helps.
So you seem to have two problems here:
Limiting your no. of lines in the <p> tag: Well for this you can either try what has been suggested in the previous comment or maybe you can play with track by $index option in your ng-repeat.
Change getting applied to all the comments: In you ng-click method pass the id/object of the element you want to apply the changes to. Create/Define IDs using $index feature of ng-repeat.

Categories