Form field

The form field component can be used to wrap input components like input fields to provide a label, errors or hints.

´ Loading interactive demo...
<dt-form-field> <dt-label>Some text</dt-label> <input type="text" dtInput placeholder="Please insert text" /> </dt-form-field> export class FormFieldDefaultExample {} <dt-form-field> <dt-label>Some text</dt-label> <input type="text" dtInput placeholder="Please insert text" /> </dt-form-field> export class FormFieldDefaultExample {}

Find more about form-fields and (live-)hints on the input fields page, see the validation pattern for more information about the error behavior.

Variants

Form-field with live hints

Live hints are used to provide feedback and suggestions immediately while users are typing.

They are used to e.g. show users if the password they entered fulfills all requirements, it is used to show users what they need to type in, etc

If errors occur, they will be displayed as soon as the input loses focus or after three seconds of inactivity.

´ Loading interactive demo...
<dt-form-field> <input type="text" required dtInput placeholder="Please insert text" [(ngModel)]="textValue" aria-label="Please insert text" /> <dt-error>A wild error appears</dt-error> </dt-form-field> export class FormFieldErrorExample { textValue: string; } <dt-form-field> <input type="text" required dtInput placeholder="Please insert text" [(ngModel)]="textValue" aria-label="Please insert text" /> <dt-error>A wild error appears</dt-error> </dt-form-field> export class FormFieldErrorExample { textValue: string; }

It is recommended that errors turn green once the issue is resolved. This helps the user understand that his changes were successful. This feature is currently not implemented yet.

Successful input validation

Live hints can also contain other content than error messages. For example password requirements.

Input with password requirements

Form-field with hint-text

Contrary to the live hints, normal hints are visible at all times. The hint is usually used to provide information that the user should know independent from their actions. The hint can be placed on the left or right side.

´ Loading interactive demo...
<dt-form-field> <input type="text" dtInput placeholder="Please insert text" aria-label="Please insert text" /> <dt-hint>Left hint</dt-hint> <dt-hint align="end">Right hint</dt-hint> </dt-form-field> export class FormFieldHintExample {} <dt-form-field> <input type="text" dtInput placeholder="Please insert text" aria-label="Please insert text" /> <dt-hint>Left hint</dt-hint> <dt-hint align="end">Right hint</dt-hint> </dt-form-field> export class FormFieldHintExample {}

<dt-form-field> is a component that wraps form input components like dtInput and provides functionality for a label (<dt-label>), errors (<dt-error>) and hints (<dt-hint>).

Imports

You have to import the DtFormFieldModule when you want to use the dt-form-field. The dt-form-field component component also requires Angular's BrowserAnimationsModule for animations. For more details on this see Step 2: Animations in the Getting started Guide. Because <dt-form-field> wraps a form input component, pls make sure that you have imported the specific component module (e.g. DtInputModule)

@NgModule({
  imports: [BrowserAnimationsModule, DtFormFieldModule],
})
class MyModule {}

Label

A label can be applied by adding a <dt-label> element. <dt-form-field> takes care of linking the label correctly to the form component by adding for="input-id" and the correct aria attributes.

´ Loading interactive demo...
<dt-form-field> <dt-label>Some text</dt-label> <input type="text" dtInput placeholder="Please insert text" /> </dt-form-field> export class FormFieldDefaultExample {} <dt-form-field> <dt-label>Some text</dt-label> <input type="text" dtInput placeholder="Please insert text" /> </dt-form-field> export class FormFieldDefaultExample {}

Hint labels

Hint labels are additional descriptive text that appears below the form field. A <dt-form-field> can have up to two hint labels: one start-aligned and one end-aligned.

Hint labels can be added with the <dt-hint> element inside the form field. Hints can be added to either side by setting the align property on <dt-hint> to either start or end. Attempting to add multiple hints to the same side will raise an error.

<dt-form-field> takes care of linking the hints correctly to the form component.

´ Loading interactive demo...
<dt-form-field> <input type="text" dtInput placeholder="Please insert text" aria-label="Please insert text" /> <dt-hint>Left hint</dt-hint> <dt-hint align="end">Right hint</dt-hint> </dt-form-field> export class FormFieldHintExample {} <dt-form-field> <input type="text" dtInput placeholder="Please insert text" aria-label="Please insert text" /> <dt-hint>Left hint</dt-hint> <dt-hint align="end">Right hint</dt-hint> </dt-form-field> export class FormFieldHintExample {}

Error messages & Validation

Error messages can be shown under the form field by adding <dt-error> elements inside the form field. By default errors are hidden initially and will be displayed on invalid form fields, after the user has interacted with the element or the parent form has been submitted. The errors will appear on top of the hint labels and will overlap them. If you want to show the errors at a different time you can customize this behaviour by passing an ErrorStateMatcher to the input used in the form field.

A form field can have more than one error, it is up to the consumer to toggle which messages should be displayed. This can be done with ngIf or ngSwitch.

´ Loading interactive demo...
<dt-form-field> <input type="text" required dtInput placeholder="Please insert text" [(ngModel)]="textValue" aria-label="Please insert text" /> <dt-error>A wild error appears</dt-error> </dt-form-field> export class FormFieldErrorExample { textValue: string; } <dt-form-field> <input type="text" required dtInput placeholder="Please insert text" [(ngModel)]="textValue" aria-label="Please insert text" /> <dt-error>A wild error appears</dt-error> </dt-form-field> export class FormFieldErrorExample { textValue: string; }

See the following example for custom validators working with the form field.

´ Loading interactive demo...
<form [formGroup]="passwordForm"> <dt-form-field> <input type="password" dtInput placeholder="Please insert super secure password" aria-label="Please insert super secure password" required formControlName="password" /> <dt-error *ngIf="passwordHasMinLengthError" >Password needs to be at least 4 characters long </dt-error> <dt-error *ngIf="passwordHasCustomError"> Password must include the string 'barista' </dt-error> </dt-form-field> </form> export class FormFieldErrorCustomValidatorExample { passwordFormControl = new FormControl('', [ // tslint:disable-next-line: no-unbound-method Validators.required, Validators.minLength(4), this.baristaValidator(), ]); passwordForm = new FormGroup({ password: this.passwordFormControl, }); get passwordHasMinLengthError(): boolean { return this.passwordFormControl.hasError('minlength'); } get passwordHasCustomError(): boolean { return this.passwordFormControl.hasError('barista'); } /** * Note that this validator function does not have to be part of the class * exporting/importing this function is preferred since it increases reusability */ baristaValidator(): ValidatorFn { // tslint:disable-next-line: no-any return (control: AbstractControl): { [key: string]: any } | null => { const required = !control.value.includes('barista'); return required ? { barista: { value: control.value } } : null; }; } } <form [formGroup]="passwordForm"> <dt-form-field> <input type="password" dtInput placeholder="Please insert super secure password" aria-label="Please insert super secure password" required formControlName="password" /> <dt-error *ngIf="passwordHasMinLengthError" >Password needs to be at least 4 characters long </dt-error> <dt-error *ngIf="passwordHasCustomError"> Password must include the string 'barista' </dt-error> </dt-form-field> </form> export class FormFieldErrorCustomValidatorExample { passwordFormControl = new FormControl('', [ // tslint:disable-next-line: no-unbound-method Validators.required, Validators.minLength(4), this.baristaValidator(), ]); passwordForm = new FormGroup({ password: this.passwordFormControl, }); get passwordHasMinLengthError(): boolean { return this.passwordFormControl.hasError('minlength'); } get passwordHasCustomError(): boolean { return this.passwordFormControl.hasError('barista'); } /** * Note that this validator function does not have to be part of the class * exporting/importing this function is preferred since it increases reusability */ baristaValidator(): ValidatorFn { // tslint:disable-next-line: no-any return (control: AbstractControl): { [key: string]: any } | null => { const required = !control.value.includes('barista'); return required ? { barista: { value: control.value } } : null; }; } }

Prefix & suffix

Custom content (like buttons, icons, loading-spinners) can be included before and after the input tag, as a prefix or suffix. It will be included within the visual container that wraps the form control. Adding the dtPrefix directive to an element inside the <dt-form-field> will designate it as the prefix. Similarly, adding dtSuffix will designate it as the suffix.

´ Loading interactive demo...
<dt-form-field> <input type="text" dtInput placeholder="Please insert amount" aria-label="Please insert amount" /> <dt-icon dtPrefix name="filter">$</dt-icon> <dt-loading-spinner dtPrefix></dt-loading-spinner> <button dt-icon-button dtSuffix variant="nested" aria-label="Submit changes" > <dt-icon name="checkmark"></dt-icon> </button> </dt-form-field> export class FormFieldPrefixSuffixExample {} <dt-form-field> <input type="text" dtInput placeholder="Please insert amount" aria-label="Please insert amount" /> <dt-icon dtPrefix name="filter">$</dt-icon> <dt-loading-spinner dtPrefix></dt-loading-spinner> <button dt-icon-button dtSuffix variant="nested" aria-label="Submit changes" > <dt-icon name="checkmark"></dt-icon> </button> </dt-form-field> export class FormFieldPrefixSuffixExample {}