I'm working on a Blazor server app where user information is collected in several steps. Parent page creates a model(let's call it MainModel), which is a collection of data from models used in child components, parent passes this model to children as a cascading parameter and children collect more info and fill in matching parameters in that model.
When the component is loaded, it loads its own model. When an input is modified, I need to check ChildModel and add it to MainModel if it passes the validation. Based on Blazor documentation, I used FieldChanged event for EditContext.
<EditForm EditContext="editContext">
<DataAnnotationsValidator/>
<div class="col-md-6">
<label for="FirstName" class="form-label">First Name</label>
<InputText type="text" @bind-Value="Model.FirstName" class="form-control"
name="FirstName"/>
<ValidationMessage For="@(() => Model.FirstName)" />
</div>
<div class="col-md-3">
<label for="LastName" class="form-label">Last Name</label>
<InputText type="text" @bind-Value="Model.LastName" class="form-control"
name="LastName"/>
<ValidationMessage For="@(() => Model.LastName)" />
</div>
<div class="col-md-3">
<label for="Age" class="form-label">Age</label>
<InputText type="text" @bind-Value="Model.Age" class="form-control" name="Age"/>
<ValidationMessage For="@(() => Model.Age)" />
</div>
</EditForm>
@code{
[CascadingParameter]
public MainModel MainModel { get; set; }
private ChildModel Model {get; set; }
private EditContext editContext;
protected override async Task OnInitializedAsync()
{
editContext = new EditContext(Model);
editContext.OnFieldChanged += EditContext_OnFieldChanged;
base.OnInitialized();
}
private async void EditContext_OnFieldChanged(object sender, FieldChangedEventArgs e)
{
if(editContext.Validate()) //<-- this shows validation messages
{
//copy child model to main model here
}
}
}
The problem is, as soon as a field is modified, this event is fired, as expected, and the model is validated which fires up the validation messages for all inputs because at that point none of the other required fields are filled in.
Is there a way to validate a model without triggering validation messages?
Maybe I need to do something with ValidationMessageStore but I haven't figured it out yet. I can toggle individual validation messages by looking at their input sibling's modified and invalid classes but I'm sure Blazor has a solution for this.
So far I don't have an answer for it so my current implementation is this:
When the EditContext.Validate() is called, I'm hiding the messages with css initially and show them only when inputs are modified and invalid:
.validation-message {
display: none;
}
input.modified.invalid {
border: 1px solid red;
position: relative;
}
input.modified.invalid + .validation-message {
position: absolute;
margin-top: -10px;
color: red;
background: #fdf2f2;
border: 1px solid #ffdede;
padding: 5px;
display: block;
z-index: 1;
}