我有一个blazor组件,并使用带有数据注释的编辑上下文。我试图在字段上一次在keypress或onblur上验证,而不是验证整个表单。有谁能帮我解决这个问题吗?
下面是我的代码
<EditForm EditContext="@editContext">
<DataAnnotationsValidator />
<div class="custom-group">
<label class="custom-label">Year Of Birth: </label>
<InputText @bind-Value="model.YearOfBirth" @onkeypress="KeyboardEventHandler" @onfocus="onFocusEvent" @onblur="onBlurEvent" class="customInputTextBox"/>
<ValidationMessage For="() => model.YearOfBirth" />
</div>
<div class="custom-group">
<label class="custom-label"> Drivers License Id:</label>
<InputText @bind-Value="model.DriversLicenseId" @onkeypress="KeyboardEventHandler" @onfocus="onFocusEvent" @onblur="onBlurEvent" class="customInputTextBox"/>
<ValidationMessage For="() => model.DriversLicenseId" />
</div>
</EditForm>
private EditContext editContext {get; set;}
private Model model = new () {};
protected override void OnInitialized()
{
editContext = new(model);
}
发布于 2022-09-08 05:19:35
下面的代码片段描述了如何订阅EditContext
对象的EditContext
事件并执行特定于给定字段(EmailAddress)的验证。当字段值更改时会引发OnFieldChanged
事件(当您从输入文本框中导航时会发生这种情况,对吗?)代码模拟对数据库的调用,以验证数据库中不存在所提供的电子邮件。如果数据库中确实存在电子邮件地址,则会显示一条验证消息,以使您知道这一点。键入新的电子邮件地址后,输入通过验证,消息将被删除.如果输入文本enet.studio1@gmail.com
,输入验证将失败,因为这是数据库中应该存在的en电子邮件地址。复制和测试:
@page "/"
@using System.ComponentModel.DataAnnotations
<EditForm EditContext="@EditContext" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<div class="form-group">
<label for="name">Name: </label>
<InputText Id="name" Class="form-control" @bind-Value="@Model.Name"></InputText>
<ValidationMessage For="@(() => Model.Name)" />
</div>
<div class="form-group">
<label for="body">Text: </label>
<InputText Id="body" Class="form-control" @bind-Value="@Model.Text"></InputText>
<ValidationMessage For="@(() => Model.Text)" />
</div>
<div class="form-group">
<label for="body">Email: </label>
<InputText Id="body" Class="form-control" @bind-Value="@Model.EmailAddress" ></InputText>
<ValidationMessage For="@(() => Model.EmailAddress)" />
</div>
<p>
<button type="submit">Save</button>
</p>
</EditForm>
@code
{
private EditContext EditContext;
private Comment Model = new Comment();
ValidationMessageStore messages;
protected override void OnInitialized()
{
EditContext = new EditContext(Model);
EditContext.OnFieldChanged += EditContext_OnFieldChanged;
messages = new ValidationMessageStore(EditContext);
}
// Note: The OnFieldChanged event is raised for each field in the model
private async void EditContext_OnFieldChanged(object sender,
FieldChangedEventArgs e)
{
await Task.Yield();
var propertyValue = Model.EmailAddress;
var emailExist = await EmailExist(propertyValue);
if (emailExist)
{
messages.Clear(e.FieldIdentifier);
messages.Add(e.FieldIdentifier, "Email already exists...");
}
else
{
messages.Clear(e.FieldIdentifier);
}
EditContext.NotifyValidationStateChanged();
}
// Simulate a database call to verify that the provided email does not exist in the database
private async Task<bool> EmailExist(string emailAddress)
{
await Task.Yield();
if(emailAddress == "enet.studio1@gmail.com")
return true;
return false;
}
public async Task HandleValidSubmit()
{
await Task.Run(() =>
{
Console.WriteLine("Saving...");
Console.WriteLine(Model.Name);
Console.WriteLine(Model.Text);
Console.WriteLine(Model.EmailAddress);
});
}
public class Comment
{
[Required]
[MaxLength(10)]
public string Name { get; set; }
[Required]
public string Text { get; set; }
[Required]
[EmailAddress]
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }
}
}
还不清楚要在keypress
事件中执行什么验证,所以我将只关注如何执行验证,而忽略了此事件的复杂性。下面是在keypress
事件中执行的基本验证:
void KeyHandler(KeyboardEventArgs args)
{
// Read a key pressed at a time
var propertyValue = args.Key;
var fieldIdentifier = new FieldIdentifier(Model, "EmailAddress");
// if the key "x" was pressed
if (propertyValue == "x")
{
messages.Clear();
messages.Add(fieldIdentifier, "Do not use `x` in your email
address.");
}
else
{
messages.Clear();
}
EditContext.NotifyValidationStateChanged();
}
以下是完整的代码片段。副本和文本:
@page "/"
@using System.ComponentModel.DataAnnotations
<EditForm EditContext="@EditContext" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<div class="form-group">
<label for="name">Name: </label>
<InputText Id="name" Class="form-control" @bind-Value="@Model.Name"></InputText>
<ValidationMessage For="@(() => Model.Name)" />
</div>
<div class="form-group">
<label for="body">Text: </label>
<InputText Id="body" Class="form-control" @bind-Value="@Model.Text"></InputText>
<ValidationMessage For="@(() => Model.Text)" />
</div>
<div class="form-group">
<label for="body">Email: </label>
<InputText Id="body" Class="form-control" @bind-Value="@Model.EmailAddress" @onkeypress="KeyHandler"></InputText>
<ValidationMessage For="@(() => Model.EmailAddress)" />
</div>
<p>
<button type="submit">Save</button>
</p>
</EditForm>
@code
{
private EditContext EditContext;
private Comment Model = new Comment();
ValidationMessageStore messages;
protected override void OnInitialized()
{
EditContext = new EditContext(Model);
messages = new ValidationMessageStore(EditContext);
}
void KeyHandler(KeyboardEventArgs args)
{
// Read a key pressed at a time
var propertyValue = args.Key;
var fieldIdentifier = new FieldIdentifier(Model, "EmailAddress");
// if the key "x" was pressed
if (propertyValue == "x")
{
messages.Clear();
messages.Add(fieldIdentifier, "Do not use `x` in your email
address.");
}
else
{
messages.Clear();
}
EditContext.NotifyValidationStateChanged();
}
public async Task HandleValidSubmit()
{
await Task.Run(() =>
{
Console.WriteLine("Saving...");
Console.WriteLine(Model.Name);
Console.WriteLine(Model.Text);
Console.WriteLine(Model.EmailAddress);
});
}
public class Comment
{
[Required]
[MaxLength(10)]
public string Name { get; set; }
[Required]
public string Text { get; set; }
[Required]
[EmailAddress]
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }
}
}
我正在尝试基于错误消息启用/禁用submit按钮。在没有错误消息和表单时启用按钮是有效的。尝试做这个按键或onblur..but遇到了挑战
你需要这个:
<button disabled="@Disabled" type="submit">Save</button>
这是:
protected string Disabled { get; set; } = "disabled";
这是:
// Note: The OnFieldChanged event is raised for each field
// in the model
private void EditContext_OnFieldChanged(object sender,
FieldChangedEventArgs e)
{
SetSaveDisabledStatus(e);
}
这是:
private void SetSaveDisabledStatus(FieldChangedEventArgs e)
{
// Each time a field changes this code is executed.
// EditContext.Validate() returns true if
// validation succeeded; that is, all the fields pass
// validation, in which case we assign the value null
// to the property Disabled, and thus enabling the Save
// button.
if (EditContext.Validate())
{
Disabled = null;
}
else
{
Disabled = "disabled";
}
}
希望我没有错过任何东西,因为我从头到手指输入了这个代码.没有进行测试。
发布于 2022-09-07 18:14:07
在普通的Blazor输入控件上,当您退出控件时会发生更新。
要将它们连接到oninput
事件,需要扩展现有控件。我添加了UpdateOnInput
参数来控制将更新连接到哪个事件。
这是MyInputText
public class MyInputText : InputText
{
[Parameter] public bool UpdateOnInput { get; set; } = false;
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, "input");
builder.AddMultipleAttributes(1, AdditionalAttributes);
if (!string.IsNullOrWhiteSpace(this.CssClass))
builder.AddAttribute(2, "class", CssClass);
builder.AddAttribute(3, "value", BindConverter.FormatValue(CurrentValue));
if (this.UpdateOnInput)
builder.AddAttribute(4, "oninput", EventCallback.Factory.CreateBinder<string?>(this, __value => CurrentValueAsString = __value, CurrentValueAsString));
else
builder.AddAttribute(5, "onchange", EventCallback.Factory.CreateBinder<string?>(this, __value => CurrentValueAsString = __value, CurrentValueAsString));
builder.AddElementReferenceCapture(6, __inputReference => Element = __inputReference);
builder.CloseElement();
}
}
原件在这里:https://github.com/dotnet/aspnetcore/blob/main/src/Components/Web/src/Forms/InputText.cs
和MyInputNumber
public class MyInputNumber<TValue> : InputNumber<TValue>
{
[Parameter] public bool UpdateOnInput { get; set; } = false;
private static readonly string _stepAttributeValue = GetStepAttributeValue();
private static string GetStepAttributeValue()
{
// Unwrap Nullable<T>, because InputBase already deals with the Nullable aspect
// of it for us. We will only get asked to parse the T for nonempty inputs.
var targetType = Nullable.GetUnderlyingType(typeof(TValue)) ?? typeof(TValue);
if (targetType == typeof(int) ||
targetType == typeof(long) ||
targetType == typeof(short) ||
targetType == typeof(float) ||
targetType == typeof(double) ||
targetType == typeof(decimal))
{
return "any";
}
else
{
throw new InvalidOperationException($"The type '{targetType}' is not a supported numeric type.");
}
}
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, "input");
builder.AddAttribute(1, "step", _stepAttributeValue);
builder.AddMultipleAttributes(2, AdditionalAttributes);
builder.AddAttribute(3, "type", "number");
if (!string.IsNullOrWhiteSpace(this.CssClass))
builder.AddAttribute(4, "class", CssClass);
builder.AddAttribute(5, "value", BindConverter.FormatValue(CurrentValueAsString));
if (this.UpdateOnInput)
builder.AddAttribute(6, "oninput", EventCallback.Factory.CreateBinder<string?>(this, __value => CurrentValueAsString = __value, CurrentValueAsString));
else
builder.AddAttribute(7, "onchange", EventCallback.Factory.CreateBinder<string?>(this, __value => CurrentValueAsString = __value, CurrentValueAsString));
builder.AddElementReferenceCapture(8, __inputReference => Element = __inputReference);
builder.CloseElement();
}
}
原版- https://github.com/dotnet/aspnetcore/blob/main/src/Components/Web/src/Forms/InputNumber.cs
这是我的考试表:
@page "/"
@using System.ComponentModel.DataAnnotations;
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
<EditForm EditContext=this.editContext>
<DataAnnotationsValidator />
<div class="row my-2">
<div class="col">
<div class="form-label">Value:</div>
<MyInputNumber UpdateOnInput=true class="form-control" @bind-Value=this.model.Value />
<ValidationMessage For="() => this.model.Value" />
</div>
</div>
<div class="row my-2">
<div class="col">
<div class="form-label">First Name:</div>
<InputText class="form-control" @bind-Value=this.model.FirstName />
<ValidationMessage For="() => this.model.FirstName" />
</div>
</div>
<div class="row my-2">
<div class="col">
<div class="form-label">Last Name:</div>
<MyInputText UpdateOnInput=true class="form-control" @bind-Value=this.model.LastName />
<ValidationMessage For="() => this.model.LastName" />
</div>
</div>
<div class="row my-2">
<div class="col">
<div class="alert alert-primary mt-3">
First Name: @this.model.FirstName - Last Name: @this.model.LastName - Value : @this.model.Value
</div>
</div>
</div>
<div class="row my-2">
<div class="col text-end">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</EditForm>
@code {
private MyModel model = new MyModel { FirstName = "Shaun", LastName="Curtis" };
private EditContext? editContext;
protected override void OnInitialized()
{
editContext = new EditContext(model);
base.OnInitialized();
}
public class MyModel
{
[StringLength(10, ErrorMessage = "Too long (10 character limit).")]
public string FirstName { get; set; } = string.Empty;
[StringLength(10, ErrorMessage = "Too long (10 character limit).")]
public string LastName { get; set; } = string.Empty;
[Range(1, 10, ErrorMessage = "Wrong! (1-10).")]
public int Value { get; set; }
}
}
基于这些,您应该能够找到其他控件的代码并自己进行扩展。如果你遇到困难,请告诉我,我会看看具体的控制。
下面是一个在Value控件中使用游标的示例(刚刚添加了0):
https://stackoverflow.com/questions/73639096
复制相似问题