Components

customdatepicker

A date-only picker. Use when the user selects a calendar date with no time component.

A date-only picker. Use when the user selects a calendar date with no time component.

Read Form Rules before using this component — keys, labels, required fields, expressions, visibility, and validation all follow shared conventions.

When to use

  • Date of birth, issue date, expiry date, appointment date — any single calendar date

When NOT to use

Instead of customdatepicker, use…For…
customdatetimepickerDate AND time selection
customtimepickerTime only

Props

PropTypeRequired?Description
labelstringrequiredVisible label. Must be unique across the form.
requiredbooleanrequiredAlways false. The expression controls the runtime value.
defaultRequiredbooleanrequiredtrue for required fields, false for optional ones.
placeholderstringoptionalGhost text shown before a date is selected.
minDateobjectoptionalEarliest selectable date as { "year": N, "month": N, "day": N }. Not a string or ISO date.
maxDateobjectoptionalLatest selectable date as { "year": N, "month": N, "day": N }. Not a string or ISO date.
addRemoveTimeMinDatestringoptionalRuntime offset applied to today for minDate. Format: "N:d" where N is days (negative = past, positive = future). e.g. "0:d" = today, "-30:d" = 30 days ago.
addRemoveTimeMaxDatestringoptionalRuntime offset applied to today for maxDate. Same format as addRemoveTimeMinDate.
dateFormatstringoptionalDisplay format, e.g. "DD MM YYYY", "MM DD YYYY".
delimeterstringoptionalDate part separator, e.g. "/", "-".
allowedDaysOfTheWeeknumber[]optionalDays the user may select. 1 = Monday … 7 = Sunday. Omit to allow all days.
eventCodestringoptionalEvent code for loading available booking dates from the backend.
eventDatesMaxSizestringoptionalMaximum number of event dates to load. Must be a string, e.g. "5".
tooltipstringoptionalHelp text shown as an icon tooltip next to the label.
hintstringoptionalHelp text rendered below the field, always visible.
hideFieldbooleanoptionalHides the field and excludes its value from submission. Toggle via expressions["props.hideField"].

Validation messages

KeyWhen shown
requiredField is empty and required
invalidValue is not a valid date
minDateSelected date is before minDate
maxDateSelected date is after maxDate
dayOfWeekIsNotAllowedSelected day is not in allowedDaysOfTheWeek
unavailableSlotsSelected date has no available slots (used with eventCode)

Examples

Required date field — no future dates

addRemoveTimeMaxDate: "0:d" limits selection to today or earlier.

{
  "key": "DATE_OF_BIRTH",
  "type": "customdatepicker",
  "props": {
    "label": "Date of Birth",
    "placeholder": "Select date",
    "required": false,
    "defaultRequired": true,
    "addRemoveTimeMaxDate": "0:d"
  },
  "expressions": {
    "props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
  },
  "validation": {
    "messages": {
      "required": "Date of Birth is required.",
      "invalid": "Please enter a valid date."
    }
  }
}

Appointment date — future only, weekdays only

{
  "key": "APPOINTMENT_DATE",
  "type": "customdatepicker",
  "props": {
    "label": "Appointment Date",
    "placeholder": "Select appointment date",
    "required": false,
    "defaultRequired": true,
    "addRemoveTimeMinDate": "1:d",
    "addRemoveTimeMaxDate": "30:d",
    "allowedDaysOfTheWeek": [1, 2, 3, 4, 5],
    "dateFormat": "DD MM YYYY",
    "delimeter": "/"
  },
  "expressions": {
    "props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
  },
  "validation": {
    "messages": {
      "required": "Appointment Date is required.",
      "invalid": "Please enter a valid date.",
      "minDate": "Appointment date cannot be in the past.",
      "maxDate": "Appointment date cannot exceed 30 days from today.",
      "dayOfWeekIsNotAllowed": "Appointments are only available on weekdays."
    }
  }
}

Fixed date range

Use minDate/maxDate objects (not strings) for hardcoded bounds.

{
  "key": "ISSUE_DATE",
  "type": "customdatepicker",
  "props": {
    "label": "Issue Date",
    "placeholder": "Select issue date",
    "required": false,
    "defaultRequired": true,
    "minDate": { "year": 2020, "month": 1, "day": 1 },
    "maxDate": { "year": 2030, "month": 12, "day": 31 }
  },
  "expressions": {
    "props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
  },
  "validation": {
    "messages": {
      "required": "Issue Date is required.",
      "invalid": "Please enter a valid date.",
      "minDate": "Issue date cannot be before 2020.",
      "maxDate": "Issue date cannot be after 2030."
    }
  }
}

Common mistakes

  • Setting minDate/maxDate as ISO strings (e.g. "2024-01-01") — they must be objects: { "year": 2024, "month": 1, "day": 1 }.
  • Setting addRemoveTimeMinDate/addRemoveTimeMaxDate as plain numbers — they must be strings in "N:d" format.
  • Setting eventDatesMaxSize as a number — it must be a string (e.g. "5").
  • Setting allowedDaysOfTheWeek with day names (e.g. "Monday") — it must be an array of numbers (1–7).
  • Using customdatepicker when a time component is also needed — use customdatetimepicker instead.
  • Setting props.required: true directly — always use defaultRequired + the expression.

Checklist

  • key is UPPER_SNAKE_CASE and unique across the entire form
  • props.label is present, unique, and correctly cased
  • Field is nested at the correct depth: sections > formly-group > block > customdatepicker
  • required: false is set (never true)
  • defaultRequired is set
  • expressions["props.required"] is present with the exact required expression
  • validation.messages.required is present
  • minDate/maxDate, if used, are objects not strings
  • addRemoveTimeMinDate/addRemoveTimeMaxDate, if used, are "N:d" strings not numbers
  • allowedDaysOfTheWeek, if used, is an array of integers 1–7
  • Validation messages present for all active constraints (minDate, maxDate, dayOfWeekIsNotAllowed, etc.)

On this page