I have a very simple model with a starttime and endtime:
public class OutputModel
{
public event Action<double> OnStartChanged;
public event Action<double> OnEndChanged;
public double Start { get; private set; }
public double End { get; private set; }
public string StartProxy { get; set; }
public string EndProxy { get; set; }
}
I'm using an EditForm to display inputboxes in which the user can edit these times. The inputboxes are bind to the StartProxy and EndProxy properties in such a way that I can trigger the events whenever a valid time is entered in either the start or end box.
<EditForm Model="@Model">
<div class="m-2 selector">
<FluentValidationValidator @ref="Model.Validator" />
<div class="info-group mb-1">
<label for="start">Start</label>
<InputText id="start" class="form-control form-control-sm" Value="@Model.StartProxy" ValueChanged="Model.StartChanged" ValueExpression="() => Model.StartProxy" />
</div>
<ValidationMessage For="() => Model.StartProxy" />
<div class="info-group mb-1">
<label for="end">Einde</label>
<InputText id="end" class="form-control form-control-sm" Value="@Model.EndProxy" ValueChanged="Model.EndChanged" ValueExpression="() => Model.EndProxy" />
</div>
<ValidationMessage For="() => Model.EndProxy" />
<div class="info-group mb-1">
<label for="duration">Duur</label>
<input id="duration" disabled="true" class="form-control form-control-sm" @bind="Model.Duration">
</div>
</div>
</EditForm>
Doing this also requires me to validate things manually. So I have created 4 rulesets which I call manually when either StartProxy or EndProxy changes:
- A ruleset to check the format of StartProxy
- A ruleset to check the format of EndProxy
- A ruleset to check if Start is before End
- A ruleset to check if End is after Start
I have 3 and 4 because I want different messages at the startbox and endbox depending on the box that is currently used by the user.
The code that validates the start is this (the end is more or less the same, but different properties):
public void StartChanged(string value)
{
StartProxy = value;
var validator = new OutputModelValidator();
// First check the format of the start
var result = validator.Validate(this, options => options.IncludeRuleSets(OutputModelValidator.StartFormatRules));
if (result.Errors.Any())
{
return;
}
// Start can be set if the format is ok
Start = StartProxy.ToTimeSpan().Value.TotalSeconds;
StartProxy = TimeSpan.FromSeconds(Start).ToString(TimeFormat);
SetDuration();
// Check if end is correct
if (validator.Validate(this, options => options.IncludeRuleSets(OutputModelValidator.EndFormatRules)).Errors.Any())
{
// End contains errors, so were done here
return;
}
// Start and end are 'format valid', now check their combination from an end perspective
if (!validator.Validate(this, options => options.IncludeRuleSets(OutputModelValidator.StartBeforeEndRules)).Errors.Any())
{
// Start is good and end is good so propagate the values
OnStartChanged?.Invoke(Start);
OnEndChanged?.Invoke(End);
}
}
So first I'm checking the format of the box that is changed. When valid I check if the 'other' box contains errors (because both can be wrong ofcourse). When good, then I check the combination for start and end.
In basic this works fine, but the problem is the following:
- The endbox shows: '00:25.200'
- I type '00:30.123' in the startbox
- The code validates and gives an error at the startbox: 'Start not after end'
- I now type '00:35.200' in the endbox
- The code validates and everything is fine.
- My startbox still shows the message: 'Start not after end'
So my question is: how can I clear the messages for the 'other' property. Or do I need a completely different approach. Suggestions are welcome ofcourse.
Many thanks in advance