File

libs/ui/search/src/lib/search/search.component.ts

Description

A presentational component to render a search form

Implements

OnInit

Example

<ts-search
  [autoSubmit]="true"
  initialValue="My starting value"
  inputHint="Enter at least 17 characters"
  inputLabel="Search for a tactic"
  [isDisabled]="false"
  [isFocused]="false"
  [isSubmitting]="false"
  theme="primary"
  buttonTheme="default"
  [userCanClear]="true"
  (changed)="doSomething($event)"
  (cleared)="doSomething()"
  (submitted)="doSomething($event)"
></ts-search>

<example-url>https://getterminus.github.io/ui-demos-release/components/search</example-url>

Metadata

changeDetection ChangeDetectionStrategy.OnPush
encapsulation ViewEncapsulation.None
exportAs tsSearch
host {
}
selector ts-search
styleUrls ./search.component.scss
templateUrl ./search.component.html

Index

Properties
Methods
Inputs
Outputs
Accessors

Constructor

constructor(formBuilder: FormBuilder)
Parameters :
Name Type Optional
formBuilder FormBuilder No

Inputs

autoSubmit
Default value : false

Define if the input should automatically submit values as typed

buttonTheme
Type : TsButtonThemeTypes
Default value : 'default'

Define the button theme

initialValue
Type : string | undefined

Define an initial value for the search input

inputHint
Default value : 'Enter at least two letters.'

Define the hint text below the input

inputLabel
Default value : 'Search'

Define the primary label for the input

isDisabled
Default value : false

Define if the search should be disabled

isFocused
Default value : false

Define if the search input should be focused initially

isSubmitting
Default value : false

Define if the search is currently submitting a query

noValidationOrHint
Default value : false

Define whether formControl needs a validation or a hint

theme
Type : TsStyleThemeTypes
Default value : 'primary'

Define the input theme

userCanClear
Default value : true

Define if the user can clear the search input

Outputs

changed
Type : EventEmitter

The event to emit when the internal input value is changed

cleared
Type : EventEmitter

The event to emit when the internal input value is cleared

submitted
Type : EventEmitter

The event to emit when the form is submitted

Methods

Public keyup
keyup()

Fire events as needed after keyup events

Returns : void

Properties

Public buttonAction
Type : TsButtonActionTypes
Default value : 'Submit'

Define the button action label

Public buttonType
Type : TsButtonFunctionTypes
Default value : 'search'

Define the button type

Public debouncedEmit
Default value : debounce<TsSearchComponent>(this.emitSubmit, INPUT_DEBOUNCE_DEFAULT_MS)

Define a debounced method to emit the submission event

Public icon
Default value : faSearch

Define the icon name

Public inputPatternRegex
Type : string
Default value : '[a-zA-Z0-9_ ]*'

Define the regular expression to validate the query

Public query
Type : string
Default value : ''

Store the search query

Public queryMinLength
Default value : INPUT_MINIMUM_LENGTH

Define the minimum length of a valid query

Public searchForm
Type : FormGroup
Default value : this.formBuilder.group({ query: [ null, [Validators.pattern(this.inputPatternRegex)], ], })

Initialize the form

Accessors

searchFormControl
getsearchFormControl()

Get a reference to the search form control

Returns : FormControl | null
currentQuery
getcurrentQuery()

Define a helper to return the current query string. If current form value length below minimum length, set the query to empty string

Returns : string
import {
  ChangeDetectionStrategy,
  Component,
  EventEmitter,
  Input,
  OnInit,
  Output,
  ViewEncapsulation,
} from '@angular/core';
import {
  FormBuilder,
  FormControl,
  FormGroup,
  Validators,
} from '@angular/forms';
import { faSearch } from '@fortawesome/pro-solid-svg-icons/faSearch';

import { debounce } from '@terminus/fe-utilities';
import {
  TsButtonActionTypes,
  TsButtonFunctionTypes,
  TsButtonThemeTypes,
} from '@terminus/ui-button';
import { TsStyleThemeTypes } from '@terminus/ui-utilities';


/**
 * Define the user object interface
 */
export interface TsSearchResponse {
  /**
   * The search query
   */
  query: string;
}

const INPUT_DEBOUNCE_DEFAULT_MS = 200;
const INPUT_MINIMUM_LENGTH = 2;


/**
 * A presentational component to render a search form
 *
 * @example
 * <ts-search
 *              [autoSubmit]="true"
 *              initialValue="My starting value"
 *              inputHint="Enter at least 17 characters"
 *              inputLabel="Search for a tactic"
 *              [isDisabled]="false"
 *              [isFocused]="false"
 *              [isSubmitting]="false"
 *              theme="primary"
 *              buttonTheme="default"
 *              [userCanClear]="true"
 *              (changed)="doSomething($event)"
 *              (cleared)="doSomething()"
 *              (submitted)="doSomething($event)"
 * ></ts-search>
 *
 * <example-url>https://getterminus.github.io/ui-demos-release/components/search</example-url>
 */
@Component({
  selector: 'ts-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.scss'],
  host: { class: 'ts-search' },
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  exportAs: 'tsSearch',
})
export class TsSearchComponent implements OnInit {
  /**
   * Define the button action label
   */
  public buttonAction: TsButtonActionTypes = 'Submit';

  /**
   * Define the button type
   */
  public buttonType: TsButtonFunctionTypes = 'search';

  /**
   * Get a reference to the search form control
   */
  public get searchFormControl(): FormControl | null {
    return this.searchForm.get('query') as FormControl;
  }

  /**
   * Define a helper to return the current query string. If current form value length below minimum length, set the query to empty string
   */
  public get currentQuery(): string {
    return this.searchForm.value.query
      && this.searchForm.value.query.length >= this.queryMinLength ? this.searchForm.value.query.trim() : '';
  }

  /**
   * Define a debounced method to emit the submission event
   */
  public debouncedEmit = debounce<TsSearchComponent>(this.emitSubmit, INPUT_DEBOUNCE_DEFAULT_MS);

  /**
   * Define the icon name
   */
  public icon = faSearch;

  /**
   * Define the regular expression to validate the query
   */
  public inputPatternRegex = '[a-zA-Z0-9_ ]*';

  /**
   * Define the minimum length of a valid query
   */
  public queryMinLength = INPUT_MINIMUM_LENGTH;

  /**
   * Initialize the form
   */
  public searchForm: FormGroup = this.formBuilder.group({
    query: [
      null,
      [Validators.pattern(this.inputPatternRegex)],
    ],
  });

  /**
   * Store the search query
   */
  public query = '';

  /**
   * Define if the input should automatically submit values as typed
   */
  @Input()
  public autoSubmit = false;

  /**
   * Define an initial value for the search input
   */
  @Input()
  public initialValue: string | undefined;

  /**
   * Define the hint text below the input
   */
  @Input()
  public inputHint = 'Enter at least two letters.';

  /**
   * Define the primary label for the input
   */
  @Input()
  public inputLabel = 'Search';

  /**
   * Define if the search should be disabled
   */
  @Input()
  public isDisabled = false;

  /**
   * Define if the search input should be focused initially
   */
  @Input()
  public isFocused = false;

  /**
   * Define if the search is currently submitting a query
   */
  @Input()
  public isSubmitting = false;

  /**
   * Define whether formControl needs a validation or a hint
   */
  @Input()
  public noValidationOrHint = false;

  /**
   * Define the input theme
   */
  @Input()
  public theme: TsStyleThemeTypes = 'primary';

  /**
   * Define the button theme
   */
  @Input()
  public buttonTheme: TsButtonThemeTypes = 'default';

  /**
   * Define if the user can clear the search input
   */
  @Input()
  public userCanClear = true;

  /**
   * The event to emit when the internal input value is changed
   */
  @Output()
  public readonly changed = new EventEmitter<string>();

  /**
   * The event to emit when the internal input value is cleared
   */
  @Output()
  public readonly cleared = new EventEmitter<boolean>();

  /**
   * The event to emit when the form is submitted
   */
  @Output()
  public readonly submitted = new EventEmitter<TsSearchResponse>();

  constructor(private formBuilder: FormBuilder) {}

  /**
   * Seed the value if needed on initialization
   */
  public ngOnInit(): void {
    // istanbul ignore else
    if (this.initialValue) {
      this.searchForm.patchValue({ query: this.initialValue });
    }
  }

  /**
   * Fire events as needed after keyup events
   */
  public keyup(): void {
    this.changed.emit(this.currentQuery);

    // NOTE: We need to check for a valid query here.
    if (this.autoSubmit && this.searchForm.valid) {
      this.debouncedEmit(this);
    }
  }

  /**
   * Emit the submitted event
   *
   * NOTE: This wrapper is needed so that we can pass the query value to the emitter
   */
  private emitSubmit(): void {
    this.submitted.emit({ query: this.currentQuery });
  }
}

result-matching ""

    No results matching ""