# DateTimeInput
*Capture dates and times with intuitive picker [interfaces](../../01_Onboarding/02_Concepts/02_Views.md) supporting calendar selection, time input, and combined date-time entry.*
The `DateTimeInput` [widget](../../01_Onboarding/02_Concepts/03_Widgets.md) provides a comprehensive date and time picker interface with support for different variants. It allows users to select dates from a calendar, times from a time selector, or both date and time together, making it ideal for scheduling, event creation, and [form](../../01_Onboarding/02_Concepts/08_Forms.md) inputs.
## Basic Usage
Here's a simple example of a DateTimeInput that allows users to select a date:
```csharp
public class BasicDateUsageDemo : ViewBase
{
public override object? Build()
{
var dateState = UseState(DateTime.Today);
var daysBetween = dateState.Value.Subtract(DateTime.Today).Days;
return Layout.Vertical()
| dateState.ToDateInput()
.WithField()
.Label("When is your birthday?")
| Text.Html($"<i>That's <b>{daysBetween}</b> days from now!");
}
}
```
## Variants
`DateTimeInput` supports three variants: Date, DateTime, and Time. The following extension methods are available for each:
- `ToDateInput()`: Calendar picker for dates only.
- `ToDateTimeInput()`: Calendar picker with time input.
- `ToTimeInput()`: Time picker only.
The following demo shows all of these in action:
```csharp
public class DateTimeVariantsDemo : ViewBase
{
public override object? Build()
{
var dateState = UseState(DateTime.Today.Date);
var timeState = UseState(DateTime.Now);
var dateTimeState = UseState(DateTime.Today);
return Layout.Vertical()
| dateState.ToDateInput()
.Format("dd/MM/yyyy")
.WithField()
.Label("Date")
| dateTimeState.ToDateTimeInput()
.Format("dd/MM/yyyy HH:mm:ss")
.WithField()
.Label("DateTime")
| timeState.ToTimeInput()
.WithField()
.Label("Time");
}
}
```
## Supported State Types
`DateTimeInput` supports various date and time types:
- `DateTime` and `DateTime?`
- `DateTimeOffset` and `DateTimeOffset?`
- `DateOnly` and `DateOnly?`
- `TimeOnly` and `TimeOnly?`
- `string` (for ISO format)
## Event Handling
`DateTimeInput` can handle change and blur events:
```csharp
var dateState = UseState(DateTime.Now);
var onChangeHandler = (Event<IInput<DateTime>, DateTime> e) =>
{
dateState.Set(e.Value);
};
return dateState.ToDateTimeInput().OnChange(onChangeHandler);
```
## Format
`DateTimeInput` can be customized with various formats. So the captured value can be
expressed in any format as supported by .NET.
```csharp
public class FormatDemo : ViewBase
{
public override object? Build()
{
var monthDateYear = UseState(DateTime.Today.Date);
var yearMonthDate = UseState(DateTime.Today.Date);
return Layout.Vertical()
| monthDateYear.ToDateInput()
.Format("MM/dd/yyyy")
.WithField()
.Label("MM/dd/yyyy")
| yearMonthDate.ToDateInput()
.Placeholder("yyyy/MMM/dd")
.Format("yyyy/MMM/dd")
.WithField()
.Label("yyyy/MMM/dd");
}
}
```
## API
[View Source: DateTimeInput.cs](https://github.com/Ivy-Interactive/Ivy-Framework/blob/main/src/Ivy/Widgets/Inputs/DateTimeInput.cs)
### Constructors
| Signature |
|-----------|
| `new DateTimeInput<TDate>(IAnyState state, string placeholder = null, bool disabled = false, DateTimeInputs variant = DateTimeInputs.Date)` |
| `new DateTimeInput<TDate>(TDate value, Func<Event<IInput<TDate>, TDate>, ValueTask> onChange, string placeholder = null, bool disabled = false, DateTimeInputs variant = DateTimeInputs.Date)` |
| `new DateTimeInput<TDate>(TDate value, Action<Event<IInput<TDate>, TDate>> onChange, string placeholder = null, bool disabled = false, DateTimeInputs variant = DateTimeInputs.Date)` |
| `new DateTimeInput<TDate>(string placeholder = null, bool disabled = false, DateTimeInputs variant = DateTimeInputs.Date)` |
| `ToDateInput(IAnyState state, string placeholder = null, bool disabled = false, DateTimeInputs variant = DateTimeInputs.Date)` |
| `ToDateTimeInput(IAnyState state, string placeholder = null, bool disabled = false, DateTimeInputs variant = DateTimeInputs.DateTime)` |
| `ToTimeInput(IAnyState state, string placeholder = null, bool disabled = false)` |
### Supported Types
| Group | Type | Nullable |
|-------|------|----------|
| Date/Time | `DateTime` | `DateTime?` |
| Date/Time | `DateOnly` | `DateOnly?` |
| Date/Time | `DateTimeOffset` | `DateTimeOffset?` |
| Date/Time | `TimeOnly` | `TimeOnly?` |
### Properties
| Name | Type | Setters |
|------|------|---------|
| `Disabled` | `bool` | `Disabled` |
| `Format` | `string` | `Format` |
| `Height` | `Size` | - |
| `Invalid` | `string` | `Invalid` |
| `Nullable` | `bool` | `Nullable` |
| `Placeholder` | `string` | `Placeholder` |
| `Scale` | `Scale?` | - |
| `Value` | `TDate` | - |
| `Variant` | `DateTimeInputs` | `Variant` |
| `Visible` | `bool` | - |
| `Width` | `Size` | - |
### Events
| Name | Type | Handlers |
|------|------|----------|
| `OnBlur` | `Func<Event<IAnyInput>, ValueTask>` | `HandleBlur` |
| `OnChange` | `Func<Event<IInput<TDate>, TDate>, ValueTask>` | - |