core/forms/input-group-editable.component.ts

Description

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. When noSaveButton is true, every keystroke propagates instead.

The model update (onChange) happens before the (save) event fires, so (save) handlers can read the committed value directly from the bound form control or ngModel.

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:

Example :
<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>

Implements

ControlValueAccessor OnInit AfterContentInit OnDestroy

Example

Metadata

Relationships

<c8y-form-group
  [class]="formGroupClass()"
  [status]="!!errors ? 'error' : ''"
>
  <div
    class="input-group input-group-editable"
    [class.input-group-sm]="size() === 'sm'"
    [class.input-group-lg]="size() === 'lg'"
    [class.input-group-editable--no-actions]="noSaveButton()"
    [attr.aria-label]="ariaLabel() | translate"
    role="group"
  >
    @if (multiline()) {
      <textarea
        class="form-control no-resize"
        [style.max-height]="maxHeight() || null"
        [attr.aria-label]="ariaLabel() | translate"
        data-cy="c8y-input-group-editable--input"
        #inputEl
        [attr.maxlength]="maxLength()"
        [attr.name]="name() || null"
        [placeholder]="(placeholder() | translate) || ''"
        [formControl]="internalControl"
        (keydown.control.enter)="noSaveButton() ? null : onSave()"
        (keydown.escape)="onEscape($event)"
        c8y-textarea-autoresize
      ></textarea>
    } @else {
      <input
        class="form-control"
        [attr.aria-label]="ariaLabel() | translate"
        data-cy="c8y-input-group-editable--input"
        #inputEl
        [attr.maxlength]="maxLength()"
        [attr.name]="name() || null"
        [attr.autocomplete]="autocomplete()"
        [placeholder]="(placeholder() | translate) || ''"
        [formControl]="internalControl"
        (keydown.enter)="noSaveButton() ? null : onSave()"
        (keydown.escape)="onEscape($event)"
        data-1p-ignore
        data-lpignore="true"
        data-bwignore
      />
    }
    <!-- Edit mode indicator hook used by _input-groups.scss -->
    <span aria-hidden="true"></span>
    @if (!internalControl.disabled && !noSaveButton()) {
      <div class="input-group-btn min-width-0">
        <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()"
        >
          <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>

results matching ""

    No results matching ""