First, this is my customInputText component:
@inherits InputBase<string>@inject CustomValidatorService CustomValidatorService;<input class="@ClassCss" placeholder="@PlaceHolder" @oninput="@HandleOnInput" @onchange="@HandleOnChange" type="text" required="@IsRequired"/><CustomValidatorMessenger ValidationMessage="@_validateMessage"/>@code { [Parameter] public string? ClassCss { get; set; } [Parameter] public string? PlaceHolder { get; set; } [Parameter] public string? FieldToValidate { get; set; } [Parameter] public EventCallback OnChange { get; set; } [Parameter] public bool IsRequired { get; set; } = true; private string? _validateMessage; protected override void OnParametersSet() { Console.WriteLine(FieldToValidate); } private void Validate() { var validateResult = CustomValidatorService.Validate(this, FieldToValidate ?? nameof(Value)); var validationResults = validateResult.ToList(); if (validationResults.Any()) { _validateMessage = validationResults.First().ErrorMessage; } } private void HandleOnInput(ChangeEventArgs e) { Value = e.Value?.ToString(); ValueChanged.InvokeAsync(Value); Validate(); } private async Task HandleOnChange() { if (OnChange.HasDelegate) { await OnChange.InvokeAsync(); } } protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out string result, [NotNullWhen(false)] out string? validationErrorMessage) { result = value; validationErrorMessage = _validateMessage; return string.IsNullOrEmpty(validationErrorMessage); }}And my CustomValidatorService:
public class CustomValidatorService{ public IEnumerable<ValidationResult> Validate(object model, string? propertyName = default) { var validationResults = new List<ValidationResult>(); var context = new ValidationContext(model); if (propertyName is null) { Validator.TryValidateObject(model, context, validationResults, true); return validationResults; } var property = model.GetType().GetProperty(propertyName); if (property is null) { return validationResults; } property.GetValue(model); context.MemberName = property.Name; return validationResults; }}And this is how I use it:
<EditForm Model="RegisterModel" OnValidSubmit="HandleValidSubmit"><DataAnnotationsValidator/><div class="mb-4 flex justify-between"><CustomInputText bind-Value="@FirstName" PlaceHolder="First Name" ValueExpression="@(() => FirstName)" ClassCss="form-control mt-1 block w-[48%] px-6 py-4 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm" OnChange="HandleUsernameInput" FieldToValidate="@(nameof(RegisterModel.Username))"/><CustomInputText bind-Value="@LastName" PlaceHolder="Last Name" ValueExpression="@(() => FirstName)" ClassCss="form-control mt-1 block w-[48%] px-6 py-4 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm" OnChange="HandleUsernameInput" FieldToValidate="@nameof(RegisterModel.Username)"/></div></EditForm>The first problem is the input value is passed to the customInput, but the parent is not binding, it's like 1 way binding.
The second problem is that the validate is not working, I have tried console.writeline and it's empty, and I do not know why.
How can I fix or improve it?