Reputation: 1670
I have the following custom date input:
<input type="date"
class="@CssClass"
@bind=CurrentValue
@attributes=AdditionalAttributes />
@if (ValidationFor is not null)
{
<ValidationMessage For="@ValidationFor" />
}
@using System.Linq.Expressions
@inherits InputBase<DateTime?>
@code {
[Parameter] public Expression<Func<DateTime>>? ValidationFor { get; set; }
protected override bool TryParseValueFromString(string? value, out DateTime? result, out string validationErrorMessage)
{
result = CurrentValue;
validationErrorMessage = "";
return true;
}
}
<CustomInputDate @bind-Value="FooDate" ValidationFor="() => FooDate"></CustomInputDate>
public DateTime? FooDate { get; set; }
However, I get errors:
How can I modify my CustomDateInput
to allow for a Validation parameter to show a ValidationMessage?
Upvotes: 1
Views: 1279
Reputation: 30485
The component. I've lifted the BuildRenderTree
code from InputDate
and added in the ValidationMessage
component. You need to do it this way as I don't know a way to do the For
binding in Razor. I've tied the For
directly into the ValueExpression
property of InputBase
. You'll probably need to add a bit of formatting/css to prettify it.
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Rendering;
using System;
namespace Blazor.Starter.Components.TestComponents
{
public class CustomDate : InputDate<DateTime?>
{
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, "input");
builder.AddMultipleAttributes(1, AdditionalAttributes);
builder.AddAttribute(2, "type", "date");
builder.AddAttribute(3, "class", CssClass);
builder.AddAttribute(4, "value", BindConverter.FormatValue(CurrentValueAsString));
builder.AddAttribute(5, "onchange", EventCallback.Factory.CreateBinder<string?>(this, __value => CurrentValueAsString = __value, CurrentValueAsString));
builder.CloseElement();
builder.OpenComponent<ValidationMessage<DateTime?>>(6);
builder.AddAttribute(7, "For", this.ValueExpression);
builder.CloseComponent();
}
}
}
And a demo page. There's a button to manually set an error message in the validationMessageStore
.
@page "/editortest"
<h3>EditorTest</h3>
<EditForm EditContext="editContext">
<div>
<CustomDate @bind-Value="model.Date"></CustomDate>
</div>
</EditForm>
<div class="m-3 p-3"><input @bind-value="_errormessage"><button class="btn btn-dark ms-2" @onclick="SetError">Set Error</button></div>
@code {
private dataModel model { get; set; } = new dataModel();
private EditContext editContext;
private string _errormessage { get; set; } = "Error in date";
protected override Task OnInitializedAsync()
{
this.editContext = new EditContext(model);
return base.OnInitializedAsync();
}
private void SetError( MouseEventArgs e)
{
var validationMessageStore = new ValidationMessageStore(this.editContext);
validationMessageStore.Clear();
var fi = new FieldIdentifier(this.model, "Date");
validationMessageStore.Add(fi, _errormessage);
}
public class dataModel
{
public string Email { get; set; }
public DateTime? Date { get; set; }
}
}
Upvotes: 2
Reputation: 2032
I have different way to reach the same result, you can try it!:
[Parameter] public bool ShowError { get; set; } = false;
<input type="date"
class="@CssClass"
@bind=CurrentValue
@attributes=AdditionalAttributes @onfocus="@(() => ShowError =true)"/>
@if(ShoError)
{
foreach(var msg in EditCotext.GetValidationMessages(FieldIdententifier))
{
<div class="alidation-message">@msg</div>
}
}
you need aslo to keep you code TryParseValueFromString
Upvotes: 0