I have a generic component that is used by three different pages in the code. Its called Food:
<div>
<label for="foodName">Food</label>
<div class="select">
<InputSelect id="foodName"
@bind-Value="FoodId"
@oninput="@(async (args) => await OnFoodSelectAsync(args?.Value?.ToString() ?? string.Empty))">
</InputSelect>
<span class="focus"></span>
</div>
<ValidationMessage For="@(() => FoodId)"/>
</div>
@code {
[Parameter]
public EventCallback<string> OnFoodSelect { get; set; }
[Parameter]
public int? FoodId { get; set; }
async Task OnFoodSelectAsync(string selectedFood)
{
if (OnFoodSelect.HasDelegate)
{
await OnFoodSelect.InvokeAsync(selectedFood);
}
}
}
Those pages use it like so:
<Food OnFoodSelect="OnFoodSelectAsync" FoodId="PerishableFoods.FoodId"/>
or
<Food OnFoodSelect="OnFoodSelectAsync" FoodId="HotFoods.FoodId"/>
I want the validation of FoodId from HotFoods or PerishableFoods to work in the child component. The annotation in the classes look like:
public class HotFoods
{
[Required(ErrorMessage = "Food selection required")]
public int? FoodId { get; set; }
}
or
public class PerishableFoods
{
[Required(ErrorMessage = "Food selection required")]
public int? FoodId { get; set; }
}
However, the ValidationMessage doesn't work right now. The only thing that works is ValidationSummary and I don't want a list kind of functionality. Each error message should show up right after its input. Are there edits I can make to make this validation work?
I have also tried ValidateComplexType with ObjectGraphDataAnnotationsValidator but I can't get that to work either.
I've taken the liberty of rewriting your select component to demonstrate how you can incorporate binding so it has the standard Blazor input functionality. And you get back simple object validation. I've also added a little extra functionality for dealing with null/zero values.
I'm not sure what the
<span class="focus"></span>is for, and yourInputSelecthas no content.The modified component:
And a page to demostrate the control, editing and validation in action: