customtimepicker
A time-of-day picker with no calendar component. Use when the user picks only an hour and minute.
A time-of-day picker with no calendar component. Use when the user picks only an hour and minute.
Read Form Rules before using this component — keys, labels, required fields, expressions, visibility, and validation all follow shared conventions.
When to use
- Preferred contact time
- Daily operating hours, opening/closing times
- Reminder time, alarm time
- Any value that is just a time of day, not bound to a specific date
When NOT to use
Instead of customtimepicker, use… | For… |
|---|---|
customdatepicker | A calendar date with no time component |
customdatetimepicker | A combined date-and-time value |
input with pattern | A free-text duration like "2h30m" (not a clock time) |
Props
| Prop | Type | Required? | Description |
|---|---|---|---|
label | string | required | Visible label. Must be unique across the form. |
required | boolean | required | Always false. The expression controls the runtime value. |
defaultRequired | boolean | required | true for required fields, false for optional ones. |
placeholder | string | optional | Ghost text shown before a value is selected. |
startHour | number | optional | Earliest selectable hour in 24h format (e.g. 8 for 08:00). |
endHour | number | optional | Latest selectable hour in 24h format (e.g. 18 for 18:00). |
interval | number | optional | Minute interval between time slots (e.g. 15 for quarter-hour steps). |
disabled | boolean | optional | Default false. Disables the picker. |
readonly | boolean | optional | Default false. Renders the field as read-only. |
tooltip | string | optional | Help text shown as an icon tooltip next to the label. |
hint | string | optional | Help text rendered below the field, always visible. |
internalDescription | string | optional | Internal note; not rendered to end users. |
hideField | boolean | optional | Hides the field and excludes its value from submission. Toggle via expressions["props.hideField"]. |
className | string | optional | CSS class applied to the field wrapper. |
The required mechanism
Every customtimepicker field must include this exact expression, regardless of whether the field is required or optional.
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
}- To make a field required: set
defaultRequired: true. - To make a field optional: set
defaultRequired: false.
Examples
Minimal — optional time
{
"key": "PREFERRED_CONTACT_TIME",
"type": "customtimepicker",
"props": {
"label": "Preferred Contact Time",
"required": false,
"defaultRequired": false
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {}
}
}Required time field
{
"key": "PREFERRED_CONTACT_TIME",
"type": "customtimepicker",
"props": {
"label": "Preferred Contact Time",
"placeholder": "Select a time",
"required": false,
"defaultRequired": true
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {
"required": "Preferred Contact Time is required."
}
}
}Full example — working-hours window with half-hour intervals
{
"key": "PREFERRED_CONTACT_TIME",
"type": "customtimepicker",
"props": {
"label": "Preferred Contact Time",
"placeholder": "Select a time",
"required": false,
"defaultRequired": true,
"startHour": 8,
"endHour": 18,
"interval": 30
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {
"required": "Preferred Contact Time is required."
}
}
}Common mistakes
- Using
customtimepickerwhen a date component is also needed — usecustomdatetimepickerinstead. - Using
customtimepickerfor a date-of-birth or calendar date — usecustomdatepicker. - Setting
props.required: truedirectly — always usedefaultRequired: truewith the standard expression. - Using
validators: { validation: [...] }instead ofvalidation: { messages: {} }for required messages. - Setting
startHour/endHour/intervalas strings — they must be numbers. - Using
disabledto gate input — preferreadonlyand toggle it viaexpressions["props.readonly"].
Checklist
-
keyisUPPER_SNAKE_CASEand unique across the entire form -
props.labelis present, unique, and correctly cased - Field is nested at the correct depth:
sections > formly-group > block > customtimepicker -
required: falseis set (nevertrue) -
defaultRequiredis set -
expressions["props.required"]is present with the exact required expression -
validation.messages.requiredis present whendefaultRequired: true -
startHour,endHour, andintervalare numbers, not strings - Not using
customtimepickerfor date or date-and-time values
customsectionmessagewithlink
Inline banner that displays a styled message, optional HTML content, and clickable links within a form section.
customtininput
A TIN (Tax Identification Number) input that verifies the number against the RDB/RRA registry and auto-populates downstream fields from the response.