I am working on a custom components library, and we have a custom autocomplete component with chips. I want to be able to disable the input control when the disabled property in config object is true. I tried to do that in ngOnInit, but it didn't work. HTML
<div [formGroup]="group" *ngIf="config && !config.hideInput">
<label *ngIf="config.overLabel" style="font-weight: 500;">{{ config.overLabel }}</label>
<mat-form-field class="form-input" [appearance]="config.appearance ? config.appearance : 'standard'">
<mat-chip-list #chipList>
<mat-icon *ngIf="config.showIconOnAutocomplete" class="material-icons-outlined positionAbsolute" [class]="config.iconOnAutocompleteClass ? config.iconOnAutocompleteClass : ''">{{ config.showIconOnAutocomplete ? config.iconOnAutocomplete : '' }}</mat-icon>
<mat-chip
[class]="config.styleClass"
*ngFor="let option of (config.value ? config.value : options); let i = index"
selectable="true"
removable="true"
(removed)="remove(option.value, i)"
>
{{ option.value }}
<mat-icon *ngIf="!config.removeChipIcon && option.type === 'field' && !config.disabled" matChipRemove>cancel</mat-icon>
</mat-chip>
<input
#optionInput
matInput
type="text"
[placeholder]="
config.placeholder ? (config.placeholder | translate) : ''
"
[formControl]="optionCtrl"
[matAutocomplete]="auto"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
(matChipInputTokenEnd)="add($event)"
/>
</mat-chip-list>
<mat-autocomplete
#auto="matAutocomplete"
(optionSelected)="selected($event)"
[displayWith]="functionFn"
>
<mat-option
*ngFor="
let option of filteredOptions | async;
trackBy: trackByIndex
"
[value]="option"
>
{{
config.fieldToShowAutocomplete
? option[config.fieldToShowAutocomplete]
: option
}}
</mat-option>
</mat-autocomplete>
<errors-field-form
[config]="config"
[group]="group"
></errors-field-form>
</mat-form-field>
</div>
ts
export class FormAutocompleteMultiConditionsComponent implements Field, OnInit {
separatorKeysCodes: number[] = [ENTER, COMMA];
optionCtrl = new FormControl();
@ViewChild('optionInput') optionInput!: ElementRef<HTMLInputElement>;
config!: AutocompleteConditionsFieldConfig;
group!: FormGroup;
listAutocompleteCopy: {type: 'field' | 'condition' | 'operator' | 'value'; value: string; isCompound?: boolean}[] | undefined = [];
objectKeys = Object.keys;
options: {type: 'field' | 'condition' | 'operator' | 'value'; value: string; isCompound?: boolean}[] = [];
filteredOptions: Observable<any[] | undefined> | undefined;
functionFn = this.displayFn.bind(this);
constructor() { }
ngOnInit(): void {
if(this.config.disabled) {
this.optionCtrl.disable();
}
this.options = this.config.value;
this.listAutocompleteCopy = this.config.listAutocomplete?.slice();
this.filteredOptions = this.optionCtrl.valueChanges.pipe(
startWith(''),
debounceTime(150),
map((value) => {
if (value) {
return typeof value === 'string' ||
!this.config.fieldToShowAutocomplete
? value
: value[this.config.fieldToShowAutocomplete];
}
}),
map((field) =>
field && this.listAutocompleteCopy ? this._filter(field, true) : []
)
);
}
}
here is a demo https://stackblitz.com/edit/angular-ivy-uwnyev, as the ts code has more code than I have shown here.
Why disable()
function in form control doesn't work?
You need to disable the input after the view is initialized. Otherwise, you're disabling a DOM element that hasn't been created yet. Working StackBlitz.
ngAfterViewInit() {
if (this.config.disabled) {
this.optionCtrl.disable();
}
}