core/forms/input-group-editable.component.ts
Inline editable input field that displays a value as plain text and switches to an edit mode with save and cancel actions.
Use this component when a value should be editable in place without navigating
away from the current view. Supports small and large size variants and
announces state changes to screen readers via an aria-live region.
Implements ControlValueAccessor so it can be used with ngModel,
formControl, or formControlName. The value is propagated to the form
control only when the user confirms an edit (save), not on every keystroke.
Supports synchronous and asynchronous validators via the validators and
asyncValidators inputs. Validation errors are shown while the user is
editing; saving is blocked when the typed value is invalid or a validator
is pending.
Custom error messages can be projected as <c8y-message> children:
<c8y-input-group-editable
[ngModel]="name"
(ngModelChange)="saveName($event)"
[validators]="[myValidator]"
ariaLabel="Name"
>
<c8y-message name="myError" text="Value is invalid."></c8y-message>
</c8y-input-group-editable>
ControlValueAccessor
OnInit
AfterContentInit
OnDestroy
| changeDetection | ChangeDetectionStrategy.OnPush |
| host | { |
| providers |
)
|
| selector | c8y-input-group-editable |
| standalone | true |
| imports |
ReactiveFormsModule
C8yTranslatePipe
IconDirective
MessagesComponent
FormGroupComponent
|
| templateUrl | ./input-group-editable.component.html |
Properties |
|
Methods |
|
Inputs |
Outputs |
Accessors |
constructor()
|
| ariaLabel |
Type : string
|
| Required : true |
|
Accessible label applied via |
| asyncValidators |
Type : AsyncValidatorFn | AsyncValidatorFn[] | null
|
Default value : null
|
|
Asynchronous validators evaluated against the live typed value. |
| name |
Default value : ''
|
|
The |
| placeholder |
Default value : ''
|
|
Placeholder text shown inside the input when the value is empty. |
| size |
Type : 'sm' | 'lg' | ''
|
Default value : ''
|
|
Controls the size of the input group. Use |
| validators |
Type : ValidatorFn | ValidatorFn[] | null
|
Default value : null
|
|
Synchronous validators evaluated against the live typed value. |
| cancel |
Type : void
|
|
Emitted when the user cancels an edit via the cancel button or the Escape key. |
| save |
Type : string
|
|
Emitted when the user confirms an edit. Provides the new string value. |
| ngAfterContentInit |
ngAfterContentInit()
|
|
Returns :
void
|
| ngOnDestroy |
ngOnDestroy()
|
|
Returns :
void
|
| ngOnInit |
ngOnInit()
|
|
Returns :
void
|
| Protected onCancel |
onCancel()
|
|
Returns :
void
|
| Protected onEscape | ||||||
onEscape(inputEl: HTMLInputElement)
|
||||||
|
Parameters :
Returns :
void
|
| Protected onSave | ||||||
onSave(inputEl: HTMLInputElement)
|
||||||
|
Parameters :
Returns :
void
|
| registerOnChange | ||||||
registerOnChange(fn: (value: string) => void)
|
||||||
|
Parameters :
Returns :
void
|
| registerOnTouched | ||||||
registerOnTouched(fn: () => void)
|
||||||
|
Parameters :
Returns :
void
|
| setDisabledState | ||||||
setDisabledState(isDisabled: boolean)
|
||||||
|
Parameters :
Returns :
void
|
| writeValue | ||||||
writeValue(value: string)
|
||||||
|
Parameters :
Returns :
void
|
| Protected Readonly customErrorMessages |
Type : QueryList<MessageDirective>
|
Decorators :
@ContentChildren(MessageDirective)
|
|
Custom |
| Protected errors |
Type : ValidationErrors | null
|
Default value : null
|
|
Validation errors to display; non-null only while the user is actively editing and the value is invalid. |
| Protected Readonly internalControl |
Type : unknown
|
Default value : new FormControl('')
|
|
Internal form control used to run sync and async validators against the live typed value. |
| Protected liveMessage |
Type : string
|
Default value : ''
|
|
Message broadcast to the aria-live region after save or cancel ('Saved' / 'Cancelled'). |
| isSaveDisabled |
getisSaveDisabled()
|
|
Whether the save action should be blocked.
Returns :
boolean
|
<c8y-form-group [status]="!!errors ? 'error' : ''">
<div
class="input-group input-group-editable"
[class.input-group-sm]="size() === 'sm'"
[class.input-group-lg]="size() === 'lg'"
[attr.aria-label]="ariaLabel() | translate"
role="group"
>
<input
class="form-control"
[attr.aria-label]="ariaLabel() | translate"
[attr.name]="name() || null"
[placeholder]="(placeholder() | translate) || ''"
[formControl]="internalControl"
(keydown.enter)="onSave(inputEl)"
(keydown.escape)="onEscape(inputEl)"
#inputEl
/>
<!-- Edit mode indicator hook used by _input-groups.scss -->
<span aria-hidden="true"></span>
@if (!internalControl.disabled) {
<div class="input-group-btn">
<button
class="btn btn-clean"
[title]="'Cancel' | translate"
[attr.aria-label]="'Cancel' | translate"
type="button"
(click)="onCancel()"
>
<i
c8yIcon="times"
aria-hidden="true"
></i>
</button>
<button
class="btn btn-clean text-primary"
[title]="'Save' | translate"
[attr.aria-label]="'Save' | translate"
type="button"
[disabled]="isSaveDisabled"
(click)="onSave(inputEl)"
>
<i
c8yIcon="check"
aria-hidden="true"
></i>
</button>
</div>
}
<span
class="sr-only"
aria-live="polite"
aria-atomic="true"
>{{ liveMessage | translate }}</span
>
</div>
<c8y-messages
[show]="errors"
[additionalMessages]="customErrorMessages"
></c8y-messages>
</c8y-form-group>