Forms¶
Forms are components designed to create and structure input masks, consisting of multiple input controls. They are configurable to fit various use cases and layouts.
Usage¶
A form is a set of related input controls that allow users to provide information.
Best practices¶
- Keep it short. Remove fields that collect redundant, untimely, or unnecessary information.
- Ask for information in a logical sequence.
- Visually group related fields.
- Match fields to the type and size of the expected input.
- When possible, use smart defaults and typeahead behavior.
- Don’t rely on placeholders; include a short and meaningful label.
- Distinguish optional and required fields. Required fields can be indicated using an asterisk.
- Make action buttons task-specific
Design¶
Elements¶
Forms can be comprised of some or all of the following elements:
- Title: A brief headline that indicates the form's purpose or the information it collects.
- Form body: Enable users to insert free or specific form text (e.g: text inputs, select, checkboxes, radio buttons, and more).
- Actions: Allow users to submit or quit a form.
States¶
The status of the form directly corresponds to the status of each of its individual fields.
Labels¶
Labels can be placed on top of fields or to the left (in RTL languages). All labels in a single form should use the same placement style. Prefer top placement of labels, since it provides a consistent left edge alignment, improving scannability.
Validation¶
Always display error states within the form and prioritize the use of inline validation.
- Inline validation: This validates user data while they fill out the form, being triggered immediately after a field loses focus.
- Post-submission validation: This assesses the entire form's data only after the user has submitted it, providing feedback through inline notifications.
Code¶
User input is one of the essential pillars of many applications. Read Forms in Angular as basis for working with forms.
The following are important yet repetitive tasks for every form control (e.g. input, textarea, checkbox) of a form:
- For accessibility, linking a
<label>
to its input usingid
/for
attributes or aria attributes. - the label must be correctly aligned for different types, e.g. text, checkbox, ...
- Display meaningfull validation error messages on input to guide and support the user.
- Group related form fields to a fieldset. For example, multiple radio checkbox inputs belong to one input and have one label.
Element provides components to shift repetitive and common tasks from the application developers to the framework. The si-form-item
component is a wrapper around a form control element that renders the associated label.
<si-form-item label="My form item">
<input [formControl]="angularControl" class="form-control">
</si-form-item>
The si-form-item
component adds and links a label to the control in compliance to WCAG v2.2, so that screen readers are able to guide users through the form.
Native controls like <input>
are only recognized by the si-form-item
if they are an angular control, meaning that they either have a formControl
, formControlName
or ngModel
attached. Custom controls of Element (e.g. si-select
) are automatically recognized by the si-form-item
.
Form feedback¶
Element form controls should provide user feedback on user input. Angular Forms handle valid and invalid form states automatically. In addition, Element supports setting form control states and feedback messages explicitly in the template:
<si-form-item label="Warning item">
<input class="form-control is-warning">
<span class="warning-feedback">Attention, this is a Warning!</span>
</si-form-item>
These states are available:
- valid -->
is-valid
- warning -->
ìs-waring
- error -->
is-error
For warning and error states, a respective icon is automatically added. Starting with Element v46, the feedback icon must not be added manually.
Error messages¶
si-form-item
is capable of showing errors from Angular's validation mechanism automatically. Element has a built-in resolution of standard errors like required
. On top of that, Element supports configuring the resolution mechanism. This enables applications to adjust existing messages and add new ones for custom validators.
Global error resolution¶
For a standalone app:
import {ApplicationConfig} from "@angular/core";
import {provideFormValidationErrorMapper} from "@siemens/element-ng/form";
export const appConfig: ApplicationConfig = {
providers: [
provideFormValidationErrorMapper(
{
maxlength: 'MY.CUSTOM.ERROR.MESSAGE.KEY', // when using ngx-translate one has access to the validation result as parameters (requiredLength and actualLength in this case)
minlength: ({ requiredLength }) => `This field must be at least ${requriredLength} characters long`,
myCustomError: ({ myCustomErrorResult }) => `My custom error message: ${myCustomErrorResult}`,
}
)
]
}
or for a module base app:
import {SiFormModule} from '@siemens/element-ng/form';
@NgModule({
imports: [
SiFormModule.withConfiguration({
validationErrorMapper: {
maxlength: 'MY.CUSTOM.ERROR.MESSAGE.KEY', // when using ngx-translate one has access to the validation result as parameters (requiredLength and actualLength in this case)
minlength: ({ requiredLength }) => `This field must be at least ${requriredLength} characters long`,
myCustomError: ({ myCustomErrorResult }) => `My custom error message: ${myCustomErrorResult}`,
},
})
],
})
Local error resolution¶
<si-form-item label="Required input" [formErrorMapper]="{required: 'This field is required'}">
...
</si-form-item>
Required detection¶
si-form-item
automatically detects whether a form control is required. It does this by checking if Angular's required validator is attached or if the control's validation feedback contains {required: true}
.
To have this check working, make sure that only the standard validators of Angular are used.
Form fieldset¶
Use a si-form-fieldset
to group multiple related si-form-item
. This is often required for radio inputs, but works for every other type as well.
<si-form-fieldset label="Radion options">
<si-form-item label="Radio option A">
<input type="radio" class="form-check-input">
</si-form-item>
<si-form-item label="Radio option B">
<input type="radio" class="form-check-input">
</si-form-item>
</si-form-fieldset>
Custom controls¶
si-form-item
provides an API for being linked to custom controls implemented by an application. Custom controls must implement the SiFormItemControl
interface and provide themselves as SI_FORM_ITEM_CONTROL
:
import { SI_FORM_ITEM_CONTROL, SiFormItemControl } from '@siemens/element-ng/form';
import { Component } from '@angular/core';
@Component({
providers: [{ provide: SI_FORM_ITEM_CONTROL, useExisting: CustomControlComponent}]
})
export class CustomControlComponent implements SiFormItemControl {
// Provide an automatically generated ID.
// If your component is only a wrapper around either an input, textarea or select,
// assign this ID to that element. Otherwise assign it to the host element.
private static idCounter = 0;
readonly id = `__app-custom-control-${CustomControlComponent.idCounter++}`;
// Set this only if the custom-control is NOT an input, textarea or select.
// It is required as the [for] attribute of an label only works for native inputs.
readonly labelledby = `${this.id}-label`;
// Set to true if, the control should be rendered like a checkbox. This only affects the positioning of the label.
// If false, this should be omitted.
readonly isFormCheck = false;
}
For HTML Elements that are marked as form-control
(--> input like appearance), icons are automatically included. If the form-control contains custom icons at the end, like the dropdown arrow for select, adjust the positioning of the feedback icon.
--si-feedback-icon-offset
contains the size of the currently shown feedback icon. Use this to shift the content within theform-control
so that it does not overlap the icon.- Set
--si-action-icon-offset
to move the feedback so that there is space for icons after it.
The example below shows how to create a wrapped input with an action icon:
<div class="form-control">
<input class="my-inner-input">
<i class="my-action-icon element-arrow-down icon"></i>
</div>
.form-control {
--si-action-icon-offset: 24px // size of my-action-icon
}
.my-inner-input {
margin-inline-end: var(--si-feedback-icon-offset);
}
// other styling
Si-Form-Container¶
The si-form-container
is an optional wrapper around a form. It provides additional responsive behavior for switching labels dependent on the available size from block
(label is on top the input) to inline
(label is on the same line).
Example¶
Angular Formly¶
Formly is a library for generating dynamic forms based on JSON input instead of pre-constructed HTML templates. Consider using formly for forms whose fields are not known at compile time and instead are created dynamically based on data. Element provides a built-in theming for formly which is part of the si-formly
component. See also Dynamic Forms.
Native HTML markup¶
Element does not recommend using native markup.
The Element theme includes a few CSS classes that are also internally used by the si-form-item
. Internally, a form item is basically structured like this:
<div>
<label class="form-label" for="input">Label</label>
<input class="form-control" id="input">
</div>
For checkboxes and radios, it uses form-check
instead of the form-control
class:
<div class="form-check">
<input class="form-check-input" id="input" type="checkbox|radio">
<label class="form-check-label" for="input">Label</label>
</div>
In both variants the feedback is included using a *-feedback
class. The feedback is either visible if an Angular state matches the feedback like .ng-invalid
or if the state is set manually by applying a class like .is-invalid
.
<div>
<label class="form-label" for="input">Label</label>
<input class="form-control is-invalid" id="input">
<div class="invalid-feedback">Invalid feedback</div>
</div>
SiFormContainerComponent API Documentation¶
si-form-container
Input Properties¶
Name | Type | Default | Description |
---|---|---|---|
contentContainerBreakpoints ¶ | Breakpoints | The container hosts the form within a siResizeContainer to configure the breakpoint for different screen sizes. Optionally, change the container breakpoints with the contentContainerBreakpoints input. | |
controlNameTranslateKeyMap ¶ | Map <string , string > | new Map<string, string>() | A map the maps from control names of the form to their translate keys. The initial map is empty and the user is responsible to add the required translate keys. |
disableContainerBreakpoints ¶ | boolean | false | In some scenarios, one may not want the form container to be responsible for the layout relevant si-container-[xs|...] classes, but let this be done by a different, nested component, e.g. by a group box. In these cases, the property should be set to true. |
disableErrorPrinting ¶ | boolean | false | Disables the automatic error printing in all nested SiFormItemComponent . Error printing will be enabled by default in v46. |
errorCodeTranslateKeyMap ¶ | (SiFormValidationErrorMapper | Map <string , string >) | Every validation error has an errorCode. This map holds translate keys for error codes. The keys can be used to display a translated message for each validation error. The defaults old english readable key defaults for the Angular standard validators of the Validators class like min , max or required .Use the input to set your own translate keys for the form validators you need. | |
form ¶ | FormGroup <TControl > | Set the form entity to the container to enable the overall form validation on in the form container edit panel. | |
labelWidth ¶ | string | A custom width value to be applied to all labels. Example: labelWidth="100px". | |
readonly ¶ | boolean | false | A form container in readonly mode is only displaying the form content without ability to change it. The edit panel with typically save and cancel buttons is hidden. Set to true to display the edit panel. |
Attributes and Methods¶
Name | Type | Default | Description |
---|---|---|---|
(readonly) invalidFormContainerMessage ¶ | boolean | Indicates whether the content editor message shall be styled as warning. Returns true , if SiFormContainerComponent.userInteractedWithForm is true and the form is invalid. | |
(readonly) userInteractedWithForm ¶ | boolean | Indicates whether the user interacted with the form. Returns true , if the user selected at least one form element and [blurred] https://developer.mozilla.org/en-US/docs/Web/API/Element/blur_event by losing focus again (e.g. by setting focus on another element), or by editing the content of a form element. Otherwise false . | |
(readonly) validFormContainerMessage ¶ | boolean | Indicates whether content editor message shall be styled as success. Returns true , if SiFormContainerComponent.userInteractedWithForm is true and the form is valid. | |
getValidationErrors(...) | (controlName: string ) => SiFormValidationError [] | Returns the validation errors of the form's control when the control name is provided. Otherwise, returns all validation errors of the form. Returns an empty arry when no form is available or if the name does not match to a control. Deprecated: The SiFormItemComponent is able to display validation errors automatically when siFormInput directive is used.Parameters
|
SiFormItemComponent API Documentation¶
si-form-item
Input Properties¶
Name | Type | Default | Description |
---|---|---|---|
disableErrorPrinting ¶ | boolean | false | Disables the automatic error printing. Error printing will be enabled by default in v46. |
formErrorMapper ¶ | SiFormValidationErrorMapper | ||
label ¶ | (null | string ) | The label to be displayed in the form item. It will be translated if a translation key is available. | |
labelWidth ¶ | (string | number ) | A custom width value to be applied to the label. A value of 0 is allowed as well to visually hide away the label area. Numbers will be converted to pixels. Using numbers is discouraged and might be dropped. Example: labelWidth="100px" | |
required ¶ | boolean | false | Defines that this form item is required for the overall form to be valid. |
inputId | string | Deprecated: property has longer an effect. SiFormItem detects IDs automatically | |
readonly | boolean | false | Deprecated: This input has no effect and can be removed. |
Types Documentation¶
|
Interface for form error mapper. It resolves a key to either a translatable string or function which is called with the validation error for its key and should return a translatable string. | |
---|---|
| |
|
|
Common interface for form item controls. Controls that should be connected to SiFormItemComponent must implement this interface and must be provided using the SI_FORM_ITEM_CONTROL token. | |||||
---|---|---|---|---|---|
|
Represents a translatable string. This can either be a translation key, e.g. ACTIONS.EDIT that will be automatically translated when displayed on the UI or a pre-translated string, e.g. Edit . Equivalent to a normal string in usage and functionality. |
---|
Variable |
---|
Translatable import imported from @siemens/element-translate-ng |
---|
| ||||||||||||
| ||||||||||||
|
Except where otherwise noted, content on this site is licensed under MIT License.