@page "/"
@using Microsoft.Extensions.Logging
@inject ILogger<Index> Logger
@using System.ComponentModel.DataAnnotations
<EditForm EditContext="editContext" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
<label>
From Date:
<InputDate TValue="DateTime?"
Value="exampleModel.FromDate"
ValueChanged="HandleFromDateChanged"
ValueExpression="() => exampleModel.FromDate" />
</label>
<ValidationMessage For="() => exampleModel.FromDate" />
</p>
<p>
<label>
To Date:
<InputDate TValue="DateTime?"
Value="exampleModel.ToDate"
ValueChanged="HandleToDateChanged"
ValueExpression="() => exampleModel.ToDate" />
</label>
<ValidationMessage For="() => exampleModel.ToDate" />
</p>
<button type="submit">Submit</button>
</EditForm>
@code {
#nullable enable
private EditContext? editContext;
private DateTimeModel exampleModel = new DateTimeModel();
protected override void OnInitialized()
{
editContext = new EditContext(exampleModel);
}
private void HandleFromDateChanged(DateTime? fromDate)
{
exampleModel.FromDate = fromDate;
if (editContext != null && exampleModel.ToDate != null)
{
FieldIdentifier toDateField = editContext.Field(nameof(DateTimeModel.ToDate));
editContext.NotifyFieldChanged(toDateField);
}
}
private void HandleToDateChanged(DateTime? toDate)
{
exampleModel.ToDate = toDate;
if (editContext != null && exampleModel.FromDate != null)
{
FieldIdentifier fromDateField = editContext.Field(nameof(DateTimeModel.FromDate));
editContext.NotifyFieldChanged(fromDateField);
}
}
private void HandleValidSubmit()
{
Logger.LogInformation("HandleValidSubmit called");
// Process the valid form
}
public class DateTimeModel
{
[Required]
[DateMustBeBefore(nameof(ToDate))]
[DataType(DataType.Date)]
public DateTime? FromDate { get; set; }
[Required]
[DateMustBeAfter(nameof(FromDate))]
[DataType(DataType.Date)]
public DateTime? ToDate { get; set; }
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DateMustBeAfterAttribute : ValidationAttribute
{
public DateMustBeAfterAttribute(string targetPropertyName)
=> TargetPropertyName = targetPropertyName;
public string TargetPropertyName { get; }
public string GetErrorMessage(string propertyName) =>
$"'{propertyName}' must be after '{TargetPropertyName}'.";
protected override ValidationResult? IsValid(
object? value, ValidationContext validationContext)
{
var targetValue = validationContext.ObjectInstance
.GetType()
.GetProperty(TargetPropertyName)
?.GetValue(validationContext.ObjectInstance, null);
if ((DateTime?)value < (DateTime?)targetValue)
{
var propertyName = validationContext.MemberName ?? string.Empty;
return new ValidationResult(GetErrorMessage(propertyName), new[] { propertyName });
}
return ValidationResult.Success;
}
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DateMustBeBeforeAttribute : ValidationAttribute
{
public DateMustBeBeforeAttribute(string targetPropertyName)
=> TargetPropertyName = targetPropertyName;
public string TargetPropertyName { get; }
public string GetErrorMessage(string propertyName) =>
$"'{propertyName}' must be before '{TargetPropertyName}'.";
protected override ValidationResult? IsValid(
object? value, ValidationContext validationContext)
{
var targetValue = validationContext.ObjectInstance
.GetType()
.GetProperty(TargetPropertyName)
?.GetValue(validationContext.ObjectInstance, null);
if ((DateTime?)value > (DateTime?)targetValue)
{
var propertyName = validationContext.MemberName ?? string.Empty;
return new ValidationResult(GetErrorMessage(propertyName), new[] { propertyName });
}
return ValidationResult.Success;
}
}
}