Blazor help needed. How can i Validate datalist entries in a child component
I have written a Blazor testapp that has an EditForm with a child component in the parent component.
The child component consists of an input with type search and a datalist.
A method returns a result from the list on input. The selection is returned to the parent via EventCallback using @focusout and can be saved in an object with the other inputs in the parent using Submit.
As soon as the validation is active, I would check the return value of the child component and set Validation = true with string.NotEmptyOrWhitespace(value) == false.
Can someone please tell me how I can implement this?
Enclosed is my demo code
1 Reply
Parent:
@page "/newentry"
@inject DataService _dataService
<h3>New Entry</h3>
<div class="container-fluid">
<div class="raw">
<div class="col-2">
<EditForm EditContext="editContext" OnValidSubmit="HandleOnSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<label>
Value:
<InputNumber @bind-Value="inputRecipe.Value"/>
<ValidationMessage For="@(() => inputRecipe.Value)" />
</label>
<ComboBoxComponent OnCategorySelected="HandleCategorySelected"></ComboBoxComponent>
<ValidationMessage For="@(() => inputRecipe.Category)" />
<label>Comment:
<InputTextArea @bind-Value="inputRecipe.Comment"/>
<ValidationMessage For="@(() => inputRecipe.Comment)" />
</label>
<button class="btn btn-outline-success" type="submit">Save</button>
</EditForm>
</div>
</div>
</div>
@code {
EditContext? editContext;
protected override void OnInitialized()
{
editContext = new(inputRecipe);
}
private string returnCatValue = "";
DisplayRecipeModel inputRecipe = new();
private void HandleOnSubmit()
{
List<DisplayRecipeModel> test = new();
inputRecipe.Category = returnCatValue;
test.Add(inputRecipe);
}
private void HandleCategorySelected(string selectedCategory)
{
returnCatValue = selectedCategory;
} } Child: @using BlazorApp.Models <div class="row"> <div class="col-2"> <div> <label>Category:</label> </div> <input type="search" list="categorylist" @bind-value="searchTermCat" @oninput="GetCatResult" @onfocusout="HandleReturnCatValue"/> <datalist id="categorylist"> @foreach (var item in recipes!) { <option value="@item.Category" /> } </datalist> </div> </div> @code { private string? searchTermCat = ""; private List<DisplayRecipeModel> catResult = new(); [Parameter] public DisplayRecipeModel? recipe { get; set; } List<DisplayRecipeModel>? recipes = new() { new DisplayRecipeModel { Category = "Fun", Payment = "Cash" }, new DisplayRecipeModel { Category = "Cloth", Payment = "Card" }, new DisplayRecipeModel { Category = "Food", Payment = "Mastercard" } }; [Parameter] public EventCallback<string> OnCategorySelected { get; set; } private void GetCatResult() { if (string.IsNullOrEmpty(searchTermCat) == false) { recipes = catResult.Where(sq => sq.Category!.Contains(searchTermCat)).ToList(); StateHasChanged(); } } private void HandleReturnCatValue() { OnCategorySelected.InvokeAsync(searchTermCat); StateHasChanged(); } } Object class: namespace BlazorApp.Models; public class DisplayRecipeModel { public string? Id { get; set; } [Required] public double Value { get; set; } [Required] public string? Category { get; set; } public string? Payment { get; set; } public string? Buyer { get; set; } public DateTime PurchaseDate { get; set; } [StringLength(20, ErrorMessage = "comment to long")] public string? Comment { get; set; } } Thanks in advance
returnCatValue = selectedCategory;
} } Child: @using BlazorApp.Models <div class="row"> <div class="col-2"> <div> <label>Category:</label> </div> <input type="search" list="categorylist" @bind-value="searchTermCat" @oninput="GetCatResult" @onfocusout="HandleReturnCatValue"/> <datalist id="categorylist"> @foreach (var item in recipes!) { <option value="@item.Category" /> } </datalist> </div> </div> @code { private string? searchTermCat = ""; private List<DisplayRecipeModel> catResult = new(); [Parameter] public DisplayRecipeModel? recipe { get; set; } List<DisplayRecipeModel>? recipes = new() { new DisplayRecipeModel { Category = "Fun", Payment = "Cash" }, new DisplayRecipeModel { Category = "Cloth", Payment = "Card" }, new DisplayRecipeModel { Category = "Food", Payment = "Mastercard" } }; [Parameter] public EventCallback<string> OnCategorySelected { get; set; } private void GetCatResult() { if (string.IsNullOrEmpty(searchTermCat) == false) { recipes = catResult.Where(sq => sq.Category!.Contains(searchTermCat)).ToList(); StateHasChanged(); } } private void HandleReturnCatValue() { OnCategorySelected.InvokeAsync(searchTermCat); StateHasChanged(); } } Object class: namespace BlazorApp.Models; public class DisplayRecipeModel { public string? Id { get; set; } [Required] public double Value { get; set; } [Required] public string? Category { get; set; } public string? Payment { get; set; } public string? Buyer { get; set; } public DateTime PurchaseDate { get; set; } [StringLength(20, ErrorMessage = "comment to long")] public string? Comment { get; set; } } Thanks in advance