I need to display validation messages if a nested-component is not properly filled in. The component is consumed by other parent-components and they need to get feedback on whether there are validation issues.
I have tried the following code for the nested-component and used the CanSubmit
method. While the method correctly tells if there are validation problems the validation messages are not showing.
All the code below can be tested on blzorrepl: https://blazorrepl.com/repl/GvOQlvvv1789ra1G37
@if(editContext != null) {
<EditForm EditContext="@editContext">
<input type="text" @bind="testModel.Name" />
<DataAnnotationsValidator />
<ValidationSummary />
</EditForm>
}
@code {
[Parameter]
public TestModel testModel
{
get { return (TestModel)editContext?.Model; }
set { editContext = new EditContext(value); }
}
EditContext editContext;
public bool CanSubmit()
{
return editContext.Validate();
}
}
This is my parent-component code, a bit reduced but reproducing the problem:
<ChildComponent @ref="myTestComponent" testModel="testModel" />
<input type="button" @onclick="buttonClick" value="validate programmatically" />
<div>@testMessage</div>
@code {
TestModel testModel = new TestModel();
ChildComponent myTestComponent;
string testMessage;
void buttonClick()
{
testMessage = "not passed validation";
if (myTestComponent.CanSubmit())
{
testMessage = "passed validation!";
}
}
}
The testMessage
is only used to show the validation status.
What can I do to make parent-component cause the nested-component to show validation messages? I can only place the submit
in the parent-component.
As it was requested, here is a more complete example of what I am doing, a list of items which can be edited inline as well as a form to add more instances. https://blazorrepl.com/repl/mlYwlQPm34bekYE824
I'll try to explain why your approach is not working and then suggest ways to solve it. I hope I understand your intentions correctly.
First you need to change the <input type="text" ...>
to <InputText @bind-Value="..." />
When your method buttonClick
is finished in your parent component, Blazor will call StateHasChanged
on your component. It's part of the built-in logic of an EventHandler
. This will trigger the component life cycle of your child component. During that cycle, the setter of your child component property testModel
will be called, again. Blazor doesn't make any test for equality. (The only mighty check engine is the DiffierentialRenderTree
at the end of a render cycle). That means a new EditContext
will be created. This context, though, doesn't know about the validation error. Hence the message disappears. To prove that point, set a counter variable inside the setter and display it on the page. You will see this result.
To avoid this scenario, you create the EditContext
once, when the parameters are set, for instance.
@code {
[Parameter]
public TestModel testModel { get; set; }
EditContext editContext;
protected override void OnParametersSet()
{
base.OnParametersSet();
if(editContext == null)
{
editContext = new EditContext(testModel);
}
}
public bool CanSubmit()
{
return editContext.Validate();
}
}
If you need to update the model but preserve the validation state, write a comment, and we can go from there.