dotCMS / dotCMS/core

Improve Date, Time, and Date-and-Time field width, clearing, and picker footer in the new Edit Contentlet

Open
#37,465 1 comment 0 reactions 1 assignee View on GitHub

@adrianjm-dotCMS is already working on this.

Since Sep 15, 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

The Date, Time, and Date and time fields in the new Edit Contentlet need three presentation improvements: they should fill the width of their column, they should be clearable directly from the field, and the picker overlay's footer should show the timezone on the left with a Today button on the right.

1. Field does not fill its column

The date/time control is narrower than its column while every other field type stretches to the full column width.

Cause: calendar-field.component.scss sets display: inline-flex on the p-datepicker wrapper, so the control sizes to its content instead of its container. Sibling fields do stretch — e.g. the Text field puts class="w-full" on its <input>.

// core-web/libs/edit-content/src/lib/fields/dot-edit-content-calendar-field/components/calendar-field/calendar-field.component.scss
:host ::ng-deep p-datepicker {
    // Use PrimeNG's default datepicker sizing
    display: inline-flex;   // <-- keeps the field from filling the column
    ...
}
2. No clear control on the field

showClear is hardcoded to the content type's expire-date field only, so every other date/time field has no way to empty a value once set:

<!-- calendar-field.component.html -->
[showClear]="$isExpireDateField()"

The mock shows a clear (X) icon between the value and the calendar button on an ordinary Posting Date field.

3. Picker footer

[showButtonBar]="true" renders PrimeNG's default button bar — Today on the left, Clear on the right. The target footer is:

Slot Content Style
Left Timezone Gray, muted text — not a button
Right Today (Now for Time-only) Secondary button, outlined

The Clear button leaves the footer entirely — clearing is now the on-field X from #2.

Interaction with #37464

The timezone currently renders under the input as <small class="p-field-hint">{{ systemTimezone.label }}</small> in dot-edit-content-calendar-field.component.html. This issue moves it into the picker footer and removes the under-input line.

That supersedes part of #37464, which left timezone placement out of scope and specified "when a Date/Time field has both a timezone and a hint, show the hint only". Once the timezone lives in the picker, the timezone-vs-hint collision disappears and the field footer carries hint and required-error text only. Whichever issue lands second should drop the now-moot criterion from the other.

Relevant code
Concern Location
Picker markup, showClear, showButtonBar core-web/libs/edit-content/src/lib/fields/dot-edit-content-calendar-field/components/calendar-field/calendar-field.component.html
inline-flex width, focus-ring styling .../components/calendar-field/calendar-field.component.scss
$isExpireDateField, onCalendarChange, value handling .../components/calendar-field/calendar-field.component.ts
Per-type config (showTime / timeOnly / icon) .../components/calendar-field/calendar-field.util.tsCALENDAR_OPTIONS_PER_TYPE
Under-input timezone line (to be removed) .../dot-edit-content-calendar-field.component.html
Server time helper getCurrentServerTime(...) in calendar-field.util.ts
Message bundle dotCMS/src/main/webapp/WEB-INF/messages/Language.properties

All three field types route through the same component — DATE, TIME, and DATE_AND_TIME all map to dot-edit-content-calendar-field in dot-edit-content-field.component.html — so one fix covers all three.

Acceptance Criteria

Width
  • Date, Time, and Date and time fields fill 100% of the width of the column they are rendered in, matching sibling field types (Text, Select, etc.).
  • The input and the calendar/clock trigger button remain visually joined as one control at full width — the trigger stays flush to the right edge.
  • The focus ring still encloses input and trigger button as a single unit (the behavior calendar-field.component.scss deliberately implements today).
  • Width is correct in single-column and multi-column form layouts, and at narrow viewport widths.
Clear on the field
  • A clear (X) control renders inside the field, between the value and the calendar/clock trigger, for all three field types.
  • The X is shown only when the field holds a value, and is not rendered when the field is empty.
  • Clicking the X empties the field: the display value clears, the form control is set to null, and the control is marked touched/dirty so validation reacts.
  • Clearing a required field leaves it empty and invalid — the X is not suppressed on required fields, and the required error appears per the rules in #37464.
  • The X is not rendered when the field is disabled or read-only.
  • The expire-date field keeps working: its Never Expires placeholder still shows when cleared, and it does not end up with two clear controls.
  • The X is keyboard reachable and has an accessible label (e.g. Clear), not an icon-only unlabelled button.
Picker footer — timezone
  • Opening the picker on a Date and time or Time field shows the timezone as gray, muted, non-interactive text in the left of the footer.
  • Opening the picker on a Date-only field shows no timezone text — the footer holds the button only.
  • The timezone text is the same value shown today (systemTimezone.label), and renders nothing (no empty footer slot, no layout shift) when the timezone is unavailable.
  • The under-input <small class="p-field-hint"> timezone line is removed from dot-edit-content-calendar-field.component.html.
Picker footer — Today / Now button
  • The footer's right slot holds a single button, styled as secondary with an outline, using the shared PrimeNG button styling (not bespoke CSS).
  • The button reads Today on Date and Date and time fields, and Now on Time-only fields.
  • On a Date and time field, the button sets today's date plus the current server time.
  • On a Date-only field, the button sets today's date.
  • On a Time-only field, Now sets the current server time.
  • The value the button sets respects the server timezone — it goes through the existing getCurrentServerTime / convertServerTimeToUtc path, not the browser's local clock.
  • After clicking the button the field shows the new value, the form control updates, and the control is marked touched/dirty.
  • PrimeNG's default Clear button no longer appears in the footer for any of the three field types.
  • Button and timezone labels come from Language.properties keys (new keys needed — no today / now key exists under the edit.content.form.field.calendar.* namespace today) and are not hardcoded strings.
Regression
  • Existing timezone conversion behavior is unchanged: values still store as UTC timestamps, Date-only as UTC midnight, Time-only against a consistent date base.
  • field.defaultValue handling (now and fixed dates) still works.
  • The picker still does not close on time selection (hideOnDateTimeSelect is false) and still appends to body.
  • The error border on the control in the invalid state still renders (:host.ng-invalid.ng-touched).
Tests
  • Unit tests cover: X hidden when empty, X shown when a value is set, X clears the value and marks the control touched.
  • Unit tests cover the footer per field type — timezone present for Date and time and Time-only, absent for Date-only.
  • Unit tests cover the button label (Today vs Now) and the value it sets for each of the three field types.
  • A test asserts PrimeNG's Clear button is absent from the picker footer.
  • Existing dot-edit-content-calendar-field.component.spec.ts assertions on the calendar-field-timezone testid are updated for the new placement.

Priority

Medium

Additional Context

Mock 1 — the field. A Posting Date field showing 09/04/2026 09:33, with a clear X and the calendar trigger to its right. A red line extends to the right of the field toward the column edge, marking the width the field should occupy.

Mock 2 — the open picker. Month/year header with prev/next arrows, day grid (the 4th selected), divider, hour/minute spinner (09 : 33), then the footer. Red annotations: "TimeZone: text gray" on the left of the footer and "Today button sec with outline" on the right. The current build's footer — Today left, Clear right — is what the annotations replace.

Resolved during refinement:

Question Decision
Does the picker footer keep a Clear button? No — removed; clearing is the on-field X
When is the on-field X visible? Only when the field holds a value
Does the under-input timezone line stay? No — moved into the picker footer
Which field types show the timezone in the footer? Date and time + Time-only; not Date-only
What does Today set on a Date and time field? Today's date + the current time
What does the Time-only footer show? A Now button, same secondary-outline styling and position

Out of scope: hint and required-error presentation (covered by #37464); moving the timezone to a secondary line under the label; changing the stored value format or the timezone conversion logic; 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.