I'm creating a component to simplify the TextAreas in my application. I've setup the two-way binding and validation (using FluentValidation). My problem is that for each usage of the component, i'm calling the same property twice. I was wondering if there was a way to only reference the property once, while keeping the two-way binding and validation reference. Any other improvements or guidance on how I could get the <InputTextArea>
control working in this scenario would also be great.
Usage of my component:
<FormTextArea @bind-Value="User.FirstName" ValidationFor="() => User.FirstName" />
This is my FormTextArea.razor
component:
@using System.Linq.Expressions;
<div class="col-12">
<label class="form-label" for="@ID">@DisplayLabel</label>
<textarea @bind="CurrentValue" id="@ID" class="@ValidationCssClass" rows="2" />
<ValidationMessage For="ValidationFor" />
</div>
@code {
[Parameter]
public string Value { get; set; }
[Parameter]
public EventCallback<string> ValueChanged { get; set; }
protected string CurrentValue
{
get
{
return Value;
}
set
{
if (!EqualityComparer<string>.Default.Equals(value, Value))
{
IsModified = true;
Value = value;
ValueChanged.InvokeAsync(Value);
EditContext.Validate();
EditContext.NotifyValidationStateChanged();
StateHasChanged();
}
}
}
[CascadingParameter]
public EditContext EditContext { get; set; }
[Parameter]
public Expression<Func<string>> ValidationFor { get; set; }
[Parameter]
public string ID { get; set; } = Guid.NewGuid().ToString();
[Parameter]
public string Label { get; set; }
string DisplayLabel => string.IsNullOrEmpty(Label) ? PropertyHelper.GetDisplayName(ValidationFor) : Label;
// The <InputTextArea> Wasn't getting the correct validation class so had to do it manually
bool IsModified { get; set; } = false;
string ValidationCssClass => $"form-control {(IsModified ? "modified" : "")} {EditContext.FieldCssClass(ValidationFor)}";
}
You should be able to modify this:
[Parameter] public Expression<Func<string>> ValidationFor { get; set; }
to this:
[Parameter] public Expression<Func<string>> ValueExpression { get; set; }
And then the Razor compiler will then do the work for you.