-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
[Autocomplete] Restrict selection to given set of items #3334
Comments
Could you give an example of how it would work? The menu wouldn't close unless you select something? |
@crisbeto, If the user began to type and left the input without selecting one of the options shown in the opened panel, it would clear the input (and any bound property). |
Thanks, that makes a bit more sense. |
Basically a hybrid between a selectbox and an autocomplete. Can be thought of as:
|
I've hacked around this by checking whether the model value is an object (given that my items are actually objects) on blur, if it's a string, it means autocomplete was blurred without selecting an option (the value will be a string). But it's nowhere near ideal, it requires |
@fxck I had forgotten to mention the |
i agree with @rosslavery in real world app md-select has avg > 50 elements therfore its more productive to use autocomplete that only allows values from the suggestion box. it heard breaking to see your users scrool al the way down to select element |
@badre429 @rosslavery there's a different feature for that #3211 here specifically you can see select filtering with async results fxck@f0dd2ec |
@fxck its a just a pull request |
Excuse me, how do you guys make a selection (from hundreds of options) without the discussed |
@gedclack, this is an example of a email search input. As the user types an email it goes to the database, grab the suggestions and shows them in the popup panel. If the user leaves the component without selecting one of them, it clears out the typed characters. style.css (top level file - nothing to do with template style file), not necessary since
Template:
Typescript code:
|
@julianobrasil thanks for showing me the codes 👍 Thanks in advance, I am new to Angular and Angular Material. |
@gedclack, yes, you can choose the approach of saving the user's bandwith by putting all in memory (as it is done in the material.angular.io). It depends on what type of machines you expect your clients to use and how much information is available to be placed and how often you expect the end users to make use of the feature. In my environment the most common type are PC's with low memory and Microsoft office applications running with lot's of small documents. They usually have a bad UI experience dispite of all efforts to make it better. I thought saving some memory was a good path to follow. By doing it I also have the benefit of delegating to the data server the work of filtering the array for me. And of course, data transfer rates is not a significant problem for the majority of my end users. You can change the code to use ngModelChange, but if you're going to contact the server over a network as I am, you'd have to add some extra code to do equivalent things as Both of your questions may be good for larger discussions. Try asking them on stackoverflow.com to get more help (I've already heard a lot of "here is not the right place for this kind of question" in many posts. Let's avoid get lectured by moderators). |
@julianobrasil yep, better not to do long discussions here :) , your approach makes sense for me, but I choose to use ngModelChange and filter the array of options I put in a variable as the page load for the first time because my end users will access this Web App via Android Devices from remote locations with weak signal coverage, so I need it to send or receive data as small as possible everytime they submit something without the need to reload the entire page. Nice chat 👍 |
Here is a solution that doesn't require setTimeout: this.trigger.panelClosingActions
.subscribe(e => {
if (!(e && e.source)) {
this.stateCtrl.setValue(null)
this.trigger.closePanel()
}
}) https://plnkr.co/edit/VWcGei7HxHYnncpzyYfW?p=preview
|
Much... much better... setTimeout always smelled like a fragile workaround to me. |
I've created a |
But I have to admit, the @willshowell solution is much better 👍 |
@jelbourn what are you thoughts api-wise for something like this?
|
@willshowell, is there a difference between Edited: BTW, I suggested |
Thanks @mustafarian and @vlio20, this version gets rid of the subscription management and timeout.
View
|
Thanks @mustafarian and @vlio20, thanks, this directive solved my problem. |
Because a directive should not be required, specially considering that such feature of |
Is there an official recommended method? |
@bfwg My work around was validate the object binded to the autocompelte, so in the submit if the object is not valid i show an error. |
@leblancmeneses I am running into a couple of issues with your directive.
From: https://material.angular.io/components/autocomplete/overview#adding-a-custom-filter
|
This feature is deadly needed... |
Thanks for this. This is probably I'm looking for. In my case instead of returning the value of input field to null,I just return the value the previous selected option in mat autocomplete. |
In the React Material-UI implementation of MatAutoComplete, if you type some value that does not exist in the list, the input is either reset or rebound to the last chosen value. |
What's the discussion that's needed here? It sounds like this is a sought after feature (although not necessary to have to implement). Is the discussion regarding what to do when a user does not choose an option? Why not use the same behavior as a select when a user does not select an option (do nothing a.k.a. keep the state the same). Surely the discussion is not to or to not implement it? Someone said 50% of the time you need to force a selection. From my experience it is 95% of the time. |
This solution seemed the best to have only valid data in the formControl, but it is only working in one way (view to model). In fact, when reseting the control or patching the value, displayed options are stuck to the ones matching last user interactions. @grant77 Do you have any idea to make it work both ways? I'm trying a different way with 2 formControls: one handling the clean data and another containing all user inputs. |
…panel Adds the `requireSelection` input to the autocomplete, which when enabled will clear the input value if the user doesn't select an option from the list. Fixes angular#3334.
…panel Adds the `requireSelection` input to the autocomplete, which when enabled will clear the input value if the user doesn't select an option from the list. Fixes angular#3334.
…panel Adds the `requireSelection` input to the autocomplete, which when enabled will clear the input value if the user doesn't select an option from the list. Fixes angular#3334.
…panel (angular#27423) Adds the `requireSelection` input to the autocomplete, which when enabled will clear the input value if the user doesn't select an option from the list. Fixes angular#3334.
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Bug, feature request, or proposal:
Request
What is the expected behavior?
md-autocomplete could have an option to force selection. I think it's not in the design doc, but near 50% of the autocompletes I've used must had to force selection.
EDITED: When the requested "force selection" option is set to true, it could clear the input (and any bound property) if the user types something in and moves the focus to other component without selecting one of the options shown on the opened panel (if there are no sugestions, the input is also cleared on the blur event).
What is the current behavior?
EDITED: The feature is not achievable direclty from the component. In one single project I'm working on, I have about 15 md-autompletes, and 11 of them must force selection. Currently I got this feature by two steps:
1. checking (in the intput's valueChanges observable) wether the value is an object - that I save in a private result property - or a regular string - that is ignored, by clearing up the same private result property (basically the input value is an object just when I select one option from the opened panel otherwise it is just a regular string that must be ignored)
2. in the blur event I verify wether the private result property is cleared or has a value (if it's cleared, I also clear the input).
Another way to do that is comparing what was typed to what came from the async server search - but I'm not sure if either of these aproaches is the best solution not wether it's suitable to the case of a search made directly in an in-memory array instead of bringing results fom a remote server. There are too many confusing workarounds to make it do what you want. I'm worried about the future, when I eventualy have to change anything in this code - it will be very time-consuming to remember all of this. There would be much less pain if, in a year from now I could just look at the component and see something like forceSelection="true".
The text was updated successfully, but these errors were encountered: