Date Time Picker Form Cell¶
The date-time picker form cell lets users select a date, a time, or both.
Date Picker Form Cell:

Time Picker Form Cell:

Date Time Picker Form Cell:

Using the DateTimePickerFormCell¶
The DateTimePickerFormCell composable function displays a form cell. When clicked, it opens a dialog to select the date and/or time.
The API includes the following:
@Composable
fun DateTimePickerFormCell(
modifier: Modifier = Modifier,
mode: DateTimePickerMode = DateTimePickerMode.DATE_PICKER,
label: String,
required: Boolean = false,
helperText: String = "",
errorMessage: String = "",
dateValueFormatter: String = "MMM d, y",
timeValueFormatter: String = "h:mm a",
pickerFormatter: String = "E, MMM d",
rangeFormatter: String = "MMM d",
datePickerState: FioriDatePickerState = rememberFioriDatePickerState(),
timePickerState: TimePickerState = rememberTimePickerState(),
dateSupportText: String = stringResource(R.string.date_picker_support),
rangeSupportText: String = stringResource(R.string.date_picker_range_support),
timeSupportText: String = stringResource(R.string.time_picker_support),
useDateInput: Boolean = false,
useTimeInput: Boolean = false,
initialTimeCleared: Boolean = true,
isError: Boolean = false,
enabled: Boolean = true,
onDateClicked: ((Date, FioriDatePickerState, FioriCalendarState) -> Unit)? = null,
onDateCleared: ((FioriDatePickerState) -> Unit)? = null,
onDateNegativeButtonClicked: ((FioriDatePickerState) -> Unit)? = null,
onDatePositiveButtonClicked: ((FioriDatePickerState) -> Unit)? = null,
onDateCancel: ((FioriDatePickerState) -> Unit)? = null,
onTimeNegativeButtonClicked: ((TimePickerState) -> Unit)? = null,
onTimePositiveButtonClicked: ((TimePickerState) -> Unit)? = null,
dateColors: DatePickerColors = DatePickerDefaults.colors(),
dateTextStyles: DatePickerTextStyles = DatePickerDefaults.textStyles(),
dateStyles: DatePickerStyles = DatePickerDefaults.styles(),
timeColors: TimePickerColors = FioriTimePickerDefaults.colors(),
timeTextStyles: TimePickerTextStyles = FioriTimePickerDefaults.textStyles(),
timeStyles: TimePickerStyles = FioriTimePickerDefaults.styles()
)
API Parameters¶
Below, you'll find more detailed explanations of some of the parameters.
Date Time Picker Mode¶
The mode parameter specifies the type of date and time picker to use.
The available modes are: DATE_PICKER, TIME_PICKER, DATE_TIME_PICKER, and RANGE_PICKER. The default mode is DATE_PICKER.
Label¶
The label parameter sets the label at the top of the form cell. This parameter is required.
Required Field¶
The required parameter indicates if the cell should be marked as required. If set to true, an asterisk appears next to the label. The default value is false.
Helper Text¶
The helperText parameter displays text at the bottom of form cells. If a cell is in an error state, the error message replaces this text.
Error Message¶
Use the errorMessage parameter to display an error message at the bottom of the form cell when the isError parameter is set to true. This message replaces the helper text.
Format¶
Use the dateValueFormatter and timeValueFormatter parameters to format date and time values in the form cell. The pickerFormatter parameter formats the date in the date picker dialog. The rangeFormatter parameter formats the dates in the range picker dialog.
States¶
The datePickerState and timePickerState parameters let application developers modify the default values. Developers can also configure the picker dialogs according to their specific needs.
Support Text¶
You can use the dateSupportText, rangeSupportText, and timeSupportText parameters to set the support text displayed in the picker dialogs.
Input Mode¶
The useDateInput and useTimeInput parameters let you set whether the dialogs open in input mode. By default, both parameters are set to false.
Initial Time Cleared¶
Use the initialTimeCleared parameter to determine if the time picker starts with no time selected. By default, this parameter is set to true.
Error State¶
The isError parameter sets the error state of form cells. When set to true, the error message appears at the bottom of the form cell, replacing the helper text. The default value is false.
Enabled State¶
The enabled parameter sets whether form cells are enabled or disabled. If set to false, the form cells are disabled, preventing user interaction. The default value is true.
Callbacks¶
The following parameters are callback functions used to handle various events:
onDateClicked: This function is called when users click a date in the date picker dialog.onDateCleared: This function is called when users clear the date in the date picker dialog.onDateNegativeButtonClicked: This function is called when users click the negative button in the date picker dialog.onDatePositiveButtonClicked: This function is called when users click the positive button in the date picker dialog.onDateCancel: This function is called when users click the cancel button in the date range picker dialog.onTimeNegativeButtonClicked: This function is called when users click the negative button in the time picker dialog.onTimePositiveButtonClicked: This function is called when users click the positive button in the time picker dialog.
Colors and Styles¶
You can use the dateColors, dateTextStyles, and dateStyles parameters to customize the colors and styles of the date picker dialog. Similarly, the timeColors, timeTextStyles, and timeStyles parameters allow customization of the colors and styles in the time picker dialog.
Code Samples¶
Custom Range Selection Behavior¶
This code snippet shows how to create a date range picker form cell with custom behavior. The picker includes disabled dates that users can't select. Users must choose a range that doesn't cross any disabled dates.
var endDate by rememberSaveable { mutableStateOf(getDefaultStartEndDate(getCurrentLocale(), false)) }
val isDateDisabled: (Date) -> Boolean = {
var isDisabled = false
val currentCal = getCalendar(getCurrentLocale(), CalendarType.GREGORIAN)
currentCal.time = it
val disabledCal = getCalendar(getCurrentLocale(), CalendarType.GREGORIAN)
for (date in disabledDates) {
disabledCal.time = date
if (isSameDate(currentCal, disabledCal)) {
isDisabled = true
}
}
isDisabled || it > endDate
}
DateTimePickerFormCell(
mode = DateTimePicker.DateTimePickerMode.RANGE_PICKER,
label = "Custom Range Selection Behavior",
helperText = "Please select a range",
errorMessage = "Range should be multiple days",
datePickerState = FioriDatePickerState(
FioriCalendarData(
useRangeSelection = true,
isDateDisabled = isDateDisabled
)
),
rangeSupportText = "Select range without crossing disabled dates",
isError = isError,
onDateClicked = { date, state, _ ->
val nextDisabledDateIndex = findNextDisabledDateIndex(date, disabledDates)
endDate = if (state.rangePickOn.value) {
getDefaultStartEndDate(getCurrentLocale(), false)
} else {
if (nextDisabledDateIndex >= 0) {
disabledDates[nextDisabledDateIndex]
} else {
getDefaultStartEndDate(getCurrentLocale(), false)
}
}
},
onDateCleared = { state ->
endDate = getDefaultStartEndDate(state.data.locale, false)
scope.launch {
snackbarHostState.showSnackbar("Selection cleared")
}
},
onDateNegativeButtonClicked = { state ->
endDate = getDefaultStartEndDate(state.data.locale, false)
scope.launch {
snackbarHostState.showSnackbar("Selection canceled")
}
},
onDatePositiveButtonClicked = { state ->
endDate = getDefaultStartEndDate(state.data.locale, false)
helperText = if (state.selectedDateCleared.value) {
"Please select a date"
} else {
""
}
isError = state.selectedRange.value.size == 1
scope.launch {
snackbarHostState.showSnackbar("Selection saved")
}
},
onDateCancel = { state ->
endDate = getDefaultStartEndDate(state.data.locale, false)
scope.launch {
snackbarHostState.showSnackbar("Exiting picker")
}
}
)
fun findNextDisabledDateIndex(date: Date, disabledDates: List<Date>): Int {
if (disabledDates.isNotEmpty()) {
val cal = getCalendar(getCurrentLocale(), CalendarType.GREGORIAN)
cal.time = date
var low = 0
var mid = 0
var high = disabledDates.size - 1
while (low <= high) {
mid = (low + high) / 2
if (cal.time.after(disabledDates[mid])) {
low = mid + 1
} else if (cal.time.before(disabledDates[mid])) {
high = mid - 1
} else {
return mid
}
}
return if (cal.time.before(disabledDates[mid])) {
mid
} else {
if (mid + 1 < disabledDates.size) {
mid + 1
} else {
-1
}
}
} else {
return -1
}
}
Required Date Time Picker Form Cell¶
This code snippet shows how to create a date-time picker form cell. The cell is required and displays an error message if users don't select a date or time.
var isError by rememberSaveable { mutableStateOf(true) }
var isError2 by rememberSaveable { mutableStateOf(true) }
DateTimePickerFormCell(
mode = DateTimePicker.DateTimePickerMode.DATE_TIME_PICKER,
label = "Date Time Picker with Error Message",
required = true,
errorMessage = "Please make sure both date and time are selected",
isError = isError || isError2,
onDatePositiveButtonClicked = { state ->
isError = state.selectedDateCleared.value
},
onTimePositiveButtonClicked = {
isError2 = false
}
)