dotCMS / dotCMS/core

Standardize field hint and required-error presentation in the new Edit Contentlet

Open
#37,464 0 comments 0 reactions 1 assignee View on GitHub

@adrianjm-dotCMS is already working on this.

Since Sep 16, 2026.

dotCMS: New Edit Contentlet Team : Falcon Type : Task
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Description

In the new Edit Contentlet, the hint and the required indicators need to follow a single, consistent design across every field type. Today each field component renders its own label/hint/error markup, in three different variants, with behavior that diverges from the target design.

Target design
Image

Four states, using a Date and time field as the example:

# State Presentation
1 No hint, no error Bold label + red asterisk (required), input
2 Hint present, no error Same, plus hint text below the input
3 No hint, error on save Red border on the input, This field is required in red below it — no icon
4 Hint present, error on save Red border, red required message below the input, then the hint below that

State 4 is the key behavioral change: the error message and the hint are shown together, error first, hint second. Today the hint is suppressed whenever an error is present.

Current gaps
  1. Hint is suppressed on error. Every field template guards the hint with !fieldHasError, so state 4 is unreachable.
  2. Hint sometimes renders as a tooltip icon, not text. dot-card-field-label accepts a hint input and renders a pi pi-info-circle tooltip next to the label. The Date/Time field routes the hint into that tooltip whenever a timezone is shown, and the Block Editor uses it unconditionally.
  3. Three duplicated markup variants, none shared:
    • <small class="p-field-error"> / <small class="p-field-hint"> — Text, Textarea, Select, Radio, Checkbox, Multi-select, Date/Time, Custom Field
    • <div class="error-message"> / <div class="hint-message"> — Tag, Host/Folder, JSON, Key-Value, WYSIWYG
    • Field-specific markup — Relationship (.error-message + own testid), File/Image/Binary, Category (no hint/error slot at all)
  4. .error-message / .hint-message have no styles anywhere in core-web. Those fields render their required message in default body color, not red. Only p-field-error / p-field-hint are styled (apps/dotcms-ui/src/style.css, scoped under .form).
  5. Error appears too early. BaseWrapperField sets $hasError from control.invalid && control.touched, so a required field turns red as soon as the user tabs out of it — before any save or publish attempt.
Relevant code
Concern Location
Error state signal core-web/libs/edit-content/src/lib/fields/shared/base-wrapper-field.ts
Card shell + error marker core-web/libs/edit-content/src/lib/fields/dot-card-field/dot-card-field.component.ts
Label + required asterisk + hint tooltip core-web/libs/edit-content/src/lib/fields/dot-card-field/components/dot-card-field-label/
Footer slot core-web/libs/edit-content/src/lib/fields/dot-card-field/components/dot-card-field-footer.component.ts
Per-field templates core-web/libs/edit-content/src/lib/fields/*/**.component.html
Required message key dot.edit.content.form.field.required
Required asterisk style core-web/libs/dotcms-scss/angular/dotcms-theme/_misc.scss (.p-label-input-required::after)
Error-scroll anchor dot-edit-content-form.component.tsquerySelectorAll('.field-error-marker')

Acceptance Criteria

Required indicator
  • A required field renders a red asterisk immediately after the label text, for every field type in the new Edit Contentlet.
  • A non-required field renders no asterisk.
  • The asterisk is decorative only — it is not announced separately by screen readers; the control carries required / aria-required.
Hint
  • When a field has a hint, it renders as plain text below the field control, for every field type.
  • The hint is never rendered as a tooltip or icon. The pi pi-info-circle tooltip in dot-card-field-label is removed, along with the hint input, and every caller is updated (Date/Time, Block Editor).
  • When a field has no hint, no empty hint element is rendered (no phantom spacing).
  • Hint text uses the shared secondary/muted style and is consistent in size and color across all field types.
Required error
  • The required error surfaces only after the user attempts to save or publish. Leaving an empty required field via blur or tab does not show a red border or a message.
  • On a save or publish attempt with one or more empty required fields, every offending field shows a red border on its control and the message This field is required below it.
  • The error message contains no icon — text only, in red.
  • The error message is rendered from the existing dot.edit.content.form.field.required key (translatable, not hardcoded).
  • A field's error clears as soon as the field holds a valid value — no second save attempt required.
  • The save/publish action is still blocked while any required field is empty, and the form still scrolls to the first field in error (the .field-error-marker anchor keeps working).
Error + hint together
  • When a field in error also has a hint, both are shown: required message first, hint immediately below it.
  • When the error clears, the hint stays visible in place with no layout jump.
Date and time (mock reference)
  • A required Date/Time field matches all four states in the mock.
  • When a Date/Time field has both a timezone line and a hint, only the hint is shown — the timezone line is dropped.
  • When a Date/Time field has a timezone and no hint, the timezone line renders as it does today.
Consistency across field types
  • One shared presentation is used by all field types — the three duplicated markup variants (p-field-error/p-field-hint, .error-message/.hint-message, and field-specific markup) are consolidated.
  • Composite widgets — Block Editor, WYSIWYG, File/Image/Binary, Relationship, Category, Key-Value, JSON, Tag, Host/Folder — render the same asterisk, hint, and required-error presentation. Where a red border on the control is not meaningful for the widget, the error border wraps the widget's outer container.
  • Category and File/Image/Binary fields, which currently have no hint slot, render hints.
  • The unstyled .error-message / .hint-message classes no longer appear in libs/edit-content.
  • Error and hint styles resolve without depending on an ancestor .form class.
Tests
  • Unit tests cover all four states (no hint/no error, hint/no error, error/no hint, error + hint) for a representative field, plus the asterisk-present and asterisk-absent cases.
  • A test asserts the required error does not appear on blur alone, and does appear after a save/publish attempt.
  • A test asserts the error clears when a valid value is entered, without a second save.
  • A test asserts the Date/Time timezone-plus-hint case shows the hint only.
  • Existing specs referencing small.p-field-error, hint-<variable> testids, and relationship-field-error are updated to the consolidated markup.

Priority

Medium

Additional Context

Design mock — four states of a Date and time field:

  1. No hint, no errorDate and time *, secondary line Coordinated Universal Time (UTC) under the label, empty input MM/DD/YYYY, HH:MM with calendar button.
  2. Hint present, no error — same, plus Use the date the meeting starts, not today below the input.
  3. No hint, error on save — red input border, This field is required in red below the input.
  4. Hint present, error on save — red border, red required message, then the hint below it.

The mock draws a circle-exclamation icon beside the error text. Omit it — the error message is text only.

Resolved during refinement:

Question Decision
Which field types? All field types in the new Edit Contentlet, including composite widgets
When does the error appear? Only after a save or publish attempt — not on blur
When does the error clear? As soon as the field has a valid value — no second save needed
Timezone line placement (the UTC line under the label in the mock) Out of scope — keep current placement; filed separately if it needs to move
Date/Time with both timezone and hint Show the hint only
Icons None — no icon on the error, and the label's info-circle hint tooltip is removed

Out of scope: moving the timezone line under the label; validation messages other than "required" (min/max, regex, custom validators) — those keep their current presentation and can adopt the same slot in follow-up work; the legacy (non-new) Edit Contentlet screen.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.