typescript 如何停止 mat-autocomplete 以将自定义用户输入值与给定选项分开?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49425706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to stop mat-autocomplete to take custom user input values apart from given options?
提问by Talk is Cheap Show me Code
I am using mat-auto complete component from material.angular.io. The default behavior is user can input any value as well as it gives options to choose from. Also you can add your input to chosen values. You can check example here. https://stackblitz.com/angular/ngmvgralayd?file=app%2Fautocomplete-simple-example.html
我正在使用 material.angular.io 中的 mat-auto 完整组件。默认行为是用户可以输入任何值,并提供可供选择的选项。您也可以将输入添加到所选值。您可以在此处查看示例。 https://stackblitz.com/angular/ngmvgralayd?file=app%2Fautocomplete-simple-example.html的
here is the code I am using for generating auto complete input field.
这是我用于生成自动完成输入字段的代码。
<form class="example-form">
<mat-form-field class="example-full-width">
<input type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto" disabled="true">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of options" [value]="option">
{{ option }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
But I want the form field to take only values from the given option and want to prevent from entering any values by users apart from given option. How to achieve this? It is like select input with auto complete feature.
但我希望表单字段仅从给定选项中获取值,并希望防止用户输入除给定选项之外的任何值。如何实现这一目标?这就像选择具有自动完成功能的输入。
回答by Ketan Akbari
You can do something like this
你可以做这样的事情
Markup:
标记:
<md-input-container class="full-width">
<input mdInput [mdAutocomplete]="autoData"
#searchMyData
formControlName="myControl"
(keyup)="changeMyControl()">
</md-input-container>
<md-autocomplete #autoData="mdAutocomplete">
<md-option
*ngFor="let option of options"
[value]="option.name"
(onSelectionChange)="onSelectedOption($event.source.selected, option.id);">
{{ option.name }}
</md-option>
</md-autocomplete>
Component:
零件:
selectedOption;
changeMyControl(): void {
if (isUndefined(this.selectedOption) {
// also check selected item and entered text are not same
this.myForm.get('myControl').setErrors({'incorrect': true});
}
}
onSelectedOption(isSelected: boolean, id: number): void {
if (isSelected) {
setTimeout(() => {
const option = this.options.filter(bt => bt.id === id);
if (option.length > 0) {
this.selectedOption= option[0];
// patch formcontrol value here
}
}, 200);
}
}
回答by Arno 2501
Found this solution on githubit may provide a simple alternative to those who end up here.
在github上找到了这个解决方案,它可能为那些最终来到这里的人提供了一个简单的替代方案。
Create a custom validator:
创建自定义验证器:
private requireMatch(control: FormControl): ValidationErrors | null {
const selection: any = control.value;
if (this.options && this.options.indexOf(selection) < 0) {
return { requireMatch: true };
}
return null;
}
Attach it to your control (we need to bind it to this so that our validator can access our options in our component's scope)
将它附加到您的控件上(我们需要将它绑定到 this 以便我们的验证器可以访问我们组件范围内的选项)
myControl = new FormControl(undefined, [Validators.required, this.requireMatch.bind(this)]);
Optionally show error:
可选显示错误:
<mat-error *ngIf="myControl.errors?.requireMatch">Value need match available options</mat-error>
Example here -----------> https://stackblitz.com/edit/angular-hph5yz
此处示例 -----------> https://stackblitz.com/edit/angular-hph5yz
回答by David Votrubec
As already suggested in comment by @trichetriche this is a use case for select.
正如@trichetrice 在评论中已经建议的那样,这是 select 的一个用例。
You can use material version of select, like this
您可以使用选择的材料版本,就像这样
<mat-form-field>
<mat-select placeholder="Favorite food">
<mat-option *ngFor="let food of foods" [value]="food.value">
{{ food.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
If you need filter above the select, than I suggest to you PrimeNg Dropdown https://www.primefaces.org/primeng/#/dropdown
如果您需要选择上方的过滤器,我建议您 PrimeNg Dropdown https://www.primefaces.org/primeng/#/dropdown
回答by adamdport
The Material demo for chips autocompleteshows bindings on both the input
and to the mat-autocomplete
:
芯片自动完成的材料演示显示了input
和 的绑定mat-autocomplete
:
<input (matChipInputTokenEnd)="add($event)">
<mat-autocomplete (optionSelected)="selected($event)"></mat-autocomplete>
If you only want to allow options from the autocomplete, just omit the add
function from the input.
如果您只想允许来自自动完成的选项,只需add
从输入中省略该功能。
回答by Mark
I think there is a UI/UX question here - in what way do we prevent the user from typing something that is not in the list of options, but still allow them to filter by a string?
我认为这里有一个 UI/UX 问题——我们如何防止用户输入不在选项列表中的内容,但仍然允许他们按字符串过滤?
I see a couple of potential options. First one is to just display an error "Invalid entry" when the option isn't in the list adjacent to the input. The second option would be to actually prevent the entry of characters that no longer match any options. So if there is a single option "foo" and a user types "for", only "fo" would be accepted, and the 'r' gets thrown out.
我看到了几个潜在的选择。第一个是才能在邻近输入的列表中显示错误时显示错误“无效条目”。第二个选项是实际防止输入不再匹配任何选项的字符。因此,如果只有一个选项“foo”并且用户键入“for”,则只会接受“fo”,而“r”将被丢弃。
The PrimeNgsolution is not quite the same as a text field that allows a user to start typing on focus. The user needs to first click to open a search, and there appears to be no keyboard accessibility. I don't really see why they haven't implemented it such that display and the search are the same, except they've got logos displayed.
该PrimeNg解决方案是不完全一样的文本字段,允许用户在聚焦开始打字。用户需要先单击才能打开搜索,而且似乎没有键盘可访问性。我真的不明白为什么他们没有实现它,以便显示和搜索是相同的,除非他们显示了徽标。