projects/cobbler-frontend/src/app/common/text-autocomplete/text-autocomplete.component.ts

Implements

ControlValueAccessor OnInit OnChanges

Metadata

Relationships

Index

Properties
Methods
Inputs

Inputs

hint
Type : string
label
Type : string
Default value : ''
options
Type : string[]
Default value : []
readonly
Type : boolean
Default value : false

Methods

Private _filter
_filter(value: string)
Parameters :
Name Type Optional
value string No
Returns : string[]
ngOnChanges
ngOnChanges(changes: SimpleChanges)
Parameters :
Name Type Optional
changes SimpleChanges No
Returns : void
ngOnInit
ngOnInit()
Returns : void
registerOnChange
registerOnChange(fn: (value: string | null) => void)
Parameters :
Name Type Optional
fn function No
Returns : void
registerOnTouched
registerOnTouched(fn: () => void)
Parameters :
Name Type Optional
fn function No
Returns : void
setDisabledState
setDisabledState(isDisabled: boolean)
Parameters :
Name Type Optional
isDisabled boolean No
Returns : void
writeValue
writeValue(value: string)
Parameters :
Name Type Optional
value string No
Returns : void

Properties

filteredOptions
Type : Observable<string[]>
innerControl
Type : unknown
Default value : new FormControl('')
isDisabled
Type : unknown
Default value : false
onChange
Type : function
Default value : () => {...}
onTouched
Type : function
Default value : () => {...}
import { Component, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { Input } from '@angular/core';
import {
  ControlValueAccessor,
  FormControl,
  NG_VALUE_ACCESSOR,
  ReactiveFormsModule,
} from '@angular/forms';
import { Observable } from 'rxjs';
import { MatInput } from '@angular/material/input';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { AsyncPipe } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { map, startWith } from 'rxjs';
import { HelpButtonComponent } from '../help-button/help-button.component';

@Component({
  selector: 'cobbler-text-autocomplete',
  imports: [
    MatInput,
    MatAutocompleteModule,
    ReactiveFormsModule,
    AsyncPipe,
    MatFormFieldModule,
    HelpButtonComponent,
  ],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      multi: true,
      useExisting: TextAutocompleteComponent,
    },
  ],
  templateUrl: './text-autocomplete.component.html',
  styleUrl: './text-autocomplete.component.scss',
})
export class TextAutocompleteComponent
  implements ControlValueAccessor, OnInit, OnChanges
{
  @Input() label: string = '';
  @Input() options: string[] = [];
  @Input() readonly = false;
  @Input() hint?: string;

  innerControl = new FormControl('');
  filteredOptions: Observable<string[]>;

  isDisabled = false;
  onChange: (value: string | null) => void = () => {};
  onTouched: () => void = () => {};

  ngOnInit(): void {
    this.filteredOptions = this.innerControl.valueChanges.pipe(
      startWith(''),
      map((value) => this._filter(value || '')),
    );

    this.innerControl.valueChanges.subscribe((value) => {
      this.onChange(value);
      this.onTouched;
    });
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes['options'] && !changes['options'].firstChange) {
      this.innerControl.updateValueAndValidity;
    }
  }

  private _filter(value: string): string[] {
    const filterValue = value.toLowerCase();
    return this.options.filter((option) =>
      option.toLowerCase().includes(filterValue),
    );
  }

  writeValue(value: string): void {
    this.innerControl.setValue(value ?? '', { emitEvent: false });
  }

  registerOnChange(fn: (value: string | null) => void): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: () => void): void {
    this.onTouched = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    this.isDisabled = isDisabled;
    if (isDisabled) {
      this.innerControl.disable({ emitEvent: false });
    } else {
      this.innerControl.enable({ emitEvent: false });
    }
  }
}
<mat-form-field class="form-field-full-width">
  <mat-label>{{ label }}</mat-label>
  <input
    type="text"
    matInput
    [formControl]="innerControl"
    [readonly]="readonly"
    [matAutocomplete]="auto"
  />
  <mat-autocomplete #auto="matAutocomplete">
    @for (option of filteredOptions | async; track option) {
      <mat-option [value]="option">{{ option }}</mat-option>
    }
  </mat-autocomplete>
  @if (hint) {
    <cobbler-help-button matSuffix [hint]="hint" />
  }
</mat-form-field>

./text-autocomplete.component.scss

:host {
  display: flex;
  flex-direction: column;
  width: 100%;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""