Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: search/filter in select #5697

Open
xuanshenbo opened this issue Jul 12, 2017 · 67 comments
Open

Feature request: search/filter in select #5697

xuanshenbo opened this issue Jul 12, 2017 · 67 comments
Labels
area: material/select feature This issue represents a new feature or feature request rather than a bug or bug fix P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent

Comments

@xuanshenbo
Copy link

Bug, feature request, or proposal:

Feature request

What is the expected behavior?

User able to search/filter the options in a select

What is the current behavior?

User must scroll the select to find the desired option

What is the use-case or motivation for changing an existing behavior?

When there is a long list of options, it's not easy to find an option

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Latest Angular Material as of 12 July 2017

Is there anything else we should know?

This is different from autocomplete, autocomplete is a free-text input field.

I haven't found anything in Material Design related to this, but this could be an important feature

@julianobrasil
Copy link
Contributor

julianobrasil commented Jul 12, 2017

@xuanshenbo, have you try a function to validate selection of the md-autocomplete at the (blur) event? I know it's not exactly the user experience that you're looking for, but I think it's a nice workaround: https://plnkr.co/edit/HzJNtcNLdctAbfeHbWCs?p=preview

@jelbourn jelbourn added the feature This issue represents a new feature or feature request rather than a bug or bug fix label Jul 13, 2017
@jelbourn
Copy link
Member

This is something we do plan on supporting eventually (similar to the md-select-header from AngularJS Material), but are still figuring out exactly how we want to implement it (the a11y is rather tricky).

@jelbourn jelbourn reopened this Jul 13, 2017
@lightheaded
Copy link

lightheaded commented Aug 3, 2017

This would be really useful, because currently md-select is veery poorly usable for long lists (e.g. country list) when compared to regular , because with the latter, you can hit the letter and jump to the items beginning with that letter. In md-select this is not an option and many developers are not willing to accept this as good UX in their applications :(

@angular angular deleted a comment from shyamal890 Aug 17, 2017
@nekkon
Copy link

nekkon commented Oct 30, 2017

Hey guys. Thanks for this great library of Material Components. Could you please add this feature in your roadmap? I believe it is important functionality, as most have already mentioned, and a must have in a long list. Also, it would be great if the filtering function could be defined by us (return true or false). @crisbeto @devversion @amcdnl @mmalerba @andrewseguin @jelbourn

@julianobrasil
Copy link
Contributor

@nekkon, it looks like it'll be possible soon: #7835

@jrood
Copy link
Contributor

jrood commented Dec 6, 2017

Indeed #7835 would be the way to implement search/filtering. @crisbeto is waiting for feedback before merging, so please give your feedback there if you have any.

@kylecordes
Copy link

I have implemented this capability as a wrapper around mat-autocomplete - and as a base class that can easily be reused to make visual variations. Repository and demo link below.

https://github.com/OasisDigital/angular-material-obs-autocomplete

https://oasisdigital.github.io/angular-material-obs-autocomplete/

I am very interested in ideas in how I could reshape this work, in to the form of a component or similar thing to offer as a PR. Maybe the pair-of-functions that my solution uses, could be reshaped to something more like a mat-grid's DataSource ?

@macjohnny
Copy link
Contributor

macjohnny commented Feb 12, 2018

Here is an implementation using mat-select:
https://mat-select-search.stackblitz.io
Code: https://stackblitz.com/edit/mat-select-search?file=app%2Fmat-select-search%2Fmat-select-search.component.ts

See https://github.com/bithost-gmbh/ngx-mat-select-search
image

@jelbourn @crisbeto might this be worth filing as a PR once #2812 / #7835 is ready?

@eyalhakim
Copy link

@macjohnny this is great! However, it has a strange behavior when using the "multiple" attribute of the mat-select. When filtering and then selecting a value from the filtered list, it overrides and removes the previously selected values, which is not the desired behavior.

Other then that it's great!

@macjohnny
Copy link
Contributor

macjohnny commented Feb 13, 2018

@eyalhakim Thanks for your feedback. I added an example with [multiple]=true and adapted the implementation of the mat-select-search to fix the behavior you described in #5697 (comment)

when using the "multiple" attribute of the mat-select. When filtering and then selecting a value from the filtered list, it overrides and removes the previously selected values, which is not the desired behavior.

so now it should also work correctly with [multiple]=true

@eyalhakim
Copy link

@macjohnny works perfectly! thank you.

I would also suggest using <mat-icon>close</mat-icon> for clearing the filter.

Would appreciate if you release this as an npm package.

@kanidjar
Copy link

@macjohnny Same here, I would be delighted to use your component if your release it as an NPM package while waiting for the official implementation by the Angular team.

@speddi
Copy link

speddi commented Feb 24, 2018

@macjohnny I am planning on using your mat-select-search component but I dont know how to use it to pre-select a value, for example, I already entered a value previously and when I try to show this component, I want to show the value preselected. I am able to filter the values, the dropdown shows only the filtered item but it doesnt show on the input unless I select the dropdown and select the value again. Any help would be much appreciated.

@macjohnny
Copy link
Contributor

macjohnny commented Feb 26, 2018

@eyalhakim thanks for your feedback. I adapted the code to use <mat-icon>close</mat-icon> for clearing the filter as you suggested.

@eyalhakim @kevin-anidjar I will try to publish it as an npm package this week.
Meanwhile, you can simply copy the code of the https://stackblitz.com/edit/mat-select-search?file=app%2Fmat-select-search%2Fmat-select-search.component.ts file together with its html / scss into your application.
See https://github.com/bithost-gmbh/ngx-mat-select-search

@speddi due to the use of the async pipe in the example <mat-option *ngFor="let bank of filteredBanks | async">, the initial value needs to be set after the filteredBanks observable emits and hence after the mat-option elements are present, because it is only possible to set a value of the `MatSelect that is available among the current options:

  ngOnInit() {
    // set initial selection
    this.bankCtrl.setValue(this.banks[1]);
    ...
  }

  ngAfterViewInit() {
    this.setInitialValue();
  }

  /**
   * Sets the initial value after the filteredBanks are loaded initially
   */
  private setInitialValue() {
    this.filteredBanks
      .pipe(take(1), takeUntil(this._onDestroy))
      .subscribe(() => {          
        // setting the compareWith property to a comparison function 
        // triggers initializing the selection according to the initial value of 
        // the form control (i.e. _initializeSelection())
        // this needs to be done after the filteredBanks are loaded initially 
        // and after the mat-option elements are available
        this.singleSelect.compareWith = (a: Bank, b: Bank) => a.id === b.id;
      });
  }

@speddi
Copy link

speddi commented Feb 26, 2018

Thank you @macjohnny for your time.

@artparks
Copy link

@macjohnny - would be useful to see this released formally with some sort of license. Can't really use it until then which is a shame as it's a solid looking implementation.

@macjohnny
Copy link
Contributor

macjohnny commented Feb 28, 2018

@artparks @speddi @eyalhakim @kevin-anidjar
I finally managed to bundle the code and publish it as an npm package:

npm install ngx-mat-select-search

See https://github.com/bithost-gmbh/ngx-mat-select-search for docs and issues / improvements.
Contributions are welcome, and I would be glad if at some point we could have an official implementation in the material library.

See it in action at https://stackblitz.com/github/bithost-gmbh/ngx-mat-select-search-example

@dreamid27
Copy link

@macjohnny thank for awesome code... it's helped me.

@joqkey
Copy link

joqkey commented Mar 17, 2018

@macjohnny Such an awesome work!
I saw @eyalhakim comment that there was a problem with the filtering for multi select and it was fixed.
However there is one more case where it doesn't work - if initially I have all values selected for multi select and then I filter and after that deselect a value, then previously selected values are removed again.

An example is shown here: https://stackblitz.com/edit/github-g1zbuf?embed=1&file=src/app/app.component.html
How to reproduce: Open multi select, type 'France', deselect one option (for example Bank C (France)) - the result is that all other previously selected values are removed.

Could you please check that case?

@macjohnny
Copy link
Contributor

@joqkey thanks for your feedback. could you please move your issue to https://github.com/bithost-gmbh/ngx-mat-select-search/issues ?

@WizardPC
Copy link

This feature will be added to angular material2 ? Or stay in ngx-mat-select-search ?

@irinelpascu
Copy link

Here is how i handled it. I used mat-autocomplete instead of mat-select https://stackblitz.com/edit/angular-v1b716
I used two form controls. One for the autocomplete and one for multiple selection which I managed manually.

@Aw3same
Copy link

Aw3same commented Dec 16, 2020

Very interested in this!

@nephi5
Copy link

nephi5 commented Dec 30, 2020

Would be great to have this feature please add it.

@andreialecu
Copy link

andreialecu commented Jan 2, 2021

I've been able to kind of hack this together through an autocomplete, but the exact functionality here would be so much better and easier!

Do you think you would mind sharing? I have been trying to do this, but to all of my attempts I have come up empty handed.

Thank you,
Zach

Recently needed this functionality as well. Here's how to hack around it using an autocomplete:

https://stackblitz.com/edit/angular-mm8n12?file=src/app/autocomplete-filter-example.ts

For a more full featured solution, check https://github.com/bithost-gmbh/ngx-mat-select-search

@AntonGrekov
Copy link

Kinda strange this feature is not yet implemented officially in the world of this great framework.

@MHillier98
Copy link

Agreed. This is a super helpful feature that I use a lot in an intranet application. I had originally gone with my own solution until I discovered that ngx-mat-select-search was the better approach.

https://www.npmjs.com/package/ngx-mat-select-search

https://github.com/bithost-gmbh/ngx-mat-select-search

@SanjanaRajasekar
Copy link

I have a usecase where i will select all in dropdown and i need to display only 3 options and rest it should show "4 More.."
How can i implement this in ngx-mat-select-search npm??

@omaracrystal
Copy link

omaracrystal commented May 6, 2021

I created a reusable SelectSearchDropdown component that utilizes Angular Material's select.
It can be set to Multi or Single.
Check it out here (and modify to meet your needs!) -->
https://stackblitz.com/edit/angular-mat-select-multi-with-formcontrol-x2tbvo?file=app%2Fselect-search-dropdown.component.html

@shafi-sahal
Copy link

I have made a reusable component 'MatSelectSearch' to select/filter the mat-options. It's easy to use.

https://www.npmjs.com/package/mat-select-search

See it in action here: https://stackblitz.com/github/shafi-sahal/MatSelectSearch

@Azbesciak
Copy link

I have made a reusable component 'MatSelectSearch' to select/filter the mat-options. It's easy to use.

https://www.npmjs.com/package/mat-select-search

See it in action here: https://stackblitz.com/github/shafi-sahal/MatSelectSearch

Nice but what for, if we have ngx-mat-select-search? mat prefix is reserved for material components I suppose. Also, there is a bug in your solution - just scroll the list and look for the search input at the top.

@shafi-sahal
Copy link

shafi-sahal commented Jul 13, 2021

I have made a reusable component 'MatSelectSearch' to select/filter the mat-options. It's easy to use.
https://www.npmjs.com/package/mat-select-search
See it in action here: https://stackblitz.com/github/shafi-sahal/MatSelectSearch

Nice but what for, if we have ngx-mat-select-search? mat prefix is reserved for material components I suppose. Also, there is a bug in your solution - just scroll the list and look for the search input at the top.

Thanks for your feedback!!
It's easy to use compared to ngx-mat-select-search. The searching logic is handled and optimized by the library, unlike ngx where you have to handle the logic.
It also supports multi-property search. For example, if there is a use case such that the user should be able to filter a list of countries using either the country code, dial code, or country name, just pass the keys of that properties to [searchProperties] as an array and it gives the result.
And yeah, even though the name is MatSelectSearch, the component is being called using <lib-mat-select-search>

And the scrolling is not meant to be a bug. It's useful sometimes, especially for mobile devices. If the input never scrolls up and if a user prefers scrolling, it's just a waste of space I think. Anyway, the input never loses focus and if you just hit a key the input reappears and searches.

Anyway, what I am thinking is to make an Input to the component to specify whether you want the input to be scrolled or not.

Feel free to tell me about any suggestions, problems, or feedback.

@starlimit
Copy link

starlimit commented Jul 16, 2021

I have made a reusable component 'MatSelectSearch' to select/filter the mat-options. It's easy to use.
https://www.npmjs.com/package/mat-select-search
See it in action here: https://stackblitz.com/github/shafi-sahal/MatSelectSearch

Nice but what for, if we have ngx-mat-select-search? mat prefix is reserved for material components I suppose. Also, there is a bug in your solution - just scroll the list and look for the search input at the top.

Thanks for your feedback!!
It's easy to use compared to ngx-mat-select-search. The searching logic is handled and optimized by the library, unlike ngx where you have to handle the logic.
It also supports multi-property search. For example, if there is a use case such that the user should be able to filter a list of countries using either the country code, dial code, or country name, just pass the keys of that properties to [searchProperties] as an array and it gives the result.
And yeah, even though the name is MatSelectSearch, the component is being called using <lib-mat-select-search>

And the scrolling is not meant to be a bug. It's useful sometimes, especially for mobile devices. If the input never scrolls up and if a user prefers scrolling, it's just a waste of space I think. Anyway, the input never loses focus and if you just hit a key the input reappears and searches.

Anyway, what I am thinking is to make an Input to the component to specify whether you want the input to be scrolled or not.

Feel free to tell me about any suggestions, problems, or feedback.

Thanks for this, it comes in handy when you have many dropdowns in a form ( individual handling of each dropdown becomes a lot of boilerplate). However, if you could include "select All" in the multiple selection that would bring it to perfection. Also , when using multiple, the checkbox and the labels do not align

@shafi-sahal
Copy link

shafi-sahal commented Jul 17, 2021

Thank you so much for the feedback!!!
Surely, I will be looking into the select all and the issue with alignment when using multiple.

@shafi-sahal
Copy link

I have made a reusable component 'MatSelectSearch' to select/filter the mat-options. It's easy to use.
https://www.npmjs.com/package/mat-select-search
See it in action here: https://stackblitz.com/github/shafi-sahal/MatSelectSearch

Nice but what for, if we have ngx-mat-select-search? mat prefix is reserved for material components I suppose. Also, there is a bug in your solution - just scroll the list and look for the search input at the top.

Thanks for your feedback!!
It's easy to use compared to ngx-mat-select-search. The searching logic is handled and optimized by the library, unlike ngx where you have to handle the logic.
It also supports multi-property search. For example, if there is a use case such that the user should be able to filter a list of countries using either the country code, dial code, or country name, just pass the keys of that properties to [searchProperties] as an array and it gives the result.
And yeah, even though the name is MatSelectSearch, the component is being called using <lib-mat-select-search>
And the scrolling is not meant to be a bug. It's useful sometimes, especially for mobile devices. If the input never scrolls up and if a user prefers scrolling, it's just a waste of space I think. Anyway, the input never loses focus and if you just hit a key the input reappears and searches.
Anyway, what I am thinking is to make an Input to the component to specify whether you want the input to be scrolled or not.
Feel free to tell me about any suggestions, problems, or feedback.

Thanks for this, it comes in handy when you have many dropdowns in a form ( individual handling of each dropdown becomes a lot of boilerplate). However, if you could include "select All" in the multiple selection that would bring it to perfection. Also , when using multiple, the checkbox and the labels do not align

A new version of MatSelectSearch is published with the requirements you have suggested.
The alignment problem happened only for that particular example. Anyway, it's also corrected.

MatSelectSearch 1.0.2 link: https://www.npmjs.com/package/mat-select-search

@zolakt
Copy link

zolakt commented Jun 3, 2022

Is there any 3rd party lib that uses mat-select internally, but functions as a blackbox?

By blackbox, I mean, that you can just specify it in the template, without the need to maintain the filteredItems subject manually in the ts file. Or having to do anything else in the ts file.

I know I can wrap ngx-mat-select-search or mat-select-search (or just mat-autocomplete) in my own component, and have an input binding with the list of all possible items, but that is not what I'm after. I want it to work with content projection, not input bindings, so it has the option to put whatever it needs in mat-option (additional divs, icons etc.)

Something like this:

<my-mat-search-select>
    <mat-option [value]="1">Option 1 <span>some suffix</span></mat-option>
    <mat-option [value]="2">Option 2 <mat-icon>home</mat-icon></mat-option>
    ...
</my-mat-search-select>

And that would be it. Similar to a normal mat-select. Without anything else needed in the ts file.

I guess, internally it would need to:

  1. get the original content projection with @ContentChildren without rendering it
  2. parse the content children (preserving the html) and store them to some internal list
  3. then use that list as a list of all possible options, and have an internal filteredItems subject which slices from that list

My point is, I don't want to repeatedly do the filteredItems subject manually, every time I want to use the component. And I don't want it wrapped in a way that it would use an input binding for the list of all possible options (or having to specify that list in the parent component). It should just work with content projection.

My actual use case is much more complex. I'm writing a wrapped lib that can dynamically switch out different UI libs (Angular Material, Ionic, ngPrime... whatever), with a combination of dynamic components and template outlets. So I need a clean "meta" interface, that doesn't rely on having lists and subjects in the ts files backing up the template. There are alternatives, of course, like doing the steps above myself. But if there is something already out there, it would save me a lot of time,

Also, it would need to support multiple selection and option groups.
I'm not asking for much, am I :)

@shafi-sahal
Copy link

shafi-sahal commented Jun 9, 2022

@zolakt I would like to consider that but I don't know about the concepts you mentioned in detail to implement them. Could you help with it :) ?

@zolakt
Copy link

zolakt commented Jun 20, 2022

@shafi-sahal I've implemented my approach, but my use case is complex. I don't have time right now to streamline it out into something simpler. I'll try to do it and post it when I have some time.

But in general, it's the approach I mentioned above:
First I get the content children without printing them to html (without ng-content in the template).
Then from those content children I create a list of objects that are used in the *ngFor of the template.

It's a little messy since I can't get the text of the mat-option cleanly. Instead I need to parse it from nativeElement. But it works.

@then3rdman
Copy link

then3rdman commented Nov 16, 2023

..... 6 years...... just saying

@zolakt
Copy link

zolakt commented Nov 16, 2023

..... 6 years...... just saying

Since no one has lifted a finger regarding this for a few years now, it will be at least 6 more...

They have removed the "under consideration" tag. That is the max effort they are willing to put in. As far as they are concerned they are safe for the next 5 years. Common pattern on way too many issue reports...

@cjsase and the gang, downvote away.... If you would spend half the time on fixing bugs as you spend on downvoting people, maybe you would actually fix a bug every once in a while

@laviealon
Copy link

laviealon commented Jan 17, 2024

Any update on this since 2018? This is such a fundamental feature I'm very surprised Angular has not taken care of this as it is an otherwise great framework.

I will be using ngx-mat-select-search for the time being.

@aljazdolenc
Copy link

Any movement or plans to move this forward?

@lance2k
Copy link

lance2k commented Apr 15, 2024

Same, will be using ngx-mat-select-search for the time being.

@jicedtea
Copy link

jicedtea commented Jul 8, 2024

7 years... for a basic function. It's not hard to see why angular is so bad these days

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: material/select feature This issue represents a new feature or feature request rather than a bug or bug fix P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
None yet
Development

Successfully merging a pull request may close this issue.