首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >blazor编辑上下文对单个字段的验证

blazor编辑上下文对单个字段的验证
EN

Stack Overflow用户
提问于 2022-09-07 16:48:51
回答 2查看 509关注 0票数 1

我有一个blazor组件,并使用带有数据注释的编辑上下文。我试图在字段上一次在keypress或onblur上验证,而不是验证整个表单。有谁能帮我解决这个问题吗?

下面是我的代码

代码语言:javascript
运行
复制
<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);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-08 05:19:35

下面的代码片段描述了如何订阅EditContext对象的EditContext事件并执行特定于给定字段(EmailAddress)的验证。当字段值更改时会引发OnFieldChanged事件(当您从输入文本框中导航时会发生这种情况,对吗?)代码模拟对数据库的调用,以验证数据库中不存在所提供的电子邮件。如果数据库中确实存在电子邮件地址,则会显示一条验证消息,以使您知道这一点。键入新的电子邮件地址后,输入通过验证,消息将被删除.如果输入文本enet.studio1@gmail.com,输入验证将失败,因为这是数据库中应该存在的en电子邮件地址。复制和测试:

代码语言:javascript
运行
复制
@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事件中执行的基本验证:

代码语言:javascript
运行
复制
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();
}

以下是完整的代码片段。副本和文本:

代码语言:javascript
运行
复制
@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遇到了挑战

你需要这个:

代码语言:javascript
运行
复制
<button disabled="@Disabled" type="submit">Save</button>

这是:

代码语言:javascript
运行
复制
protected string Disabled { get; set; } = "disabled";

这是:

代码语言:javascript
运行
复制
  // Note: The OnFieldChanged event is raised for each field 
  // in the model
    private void EditContext_OnFieldChanged(object sender, 
                                   FieldChangedEventArgs e)
    {
       
        SetSaveDisabledStatus(e);

    }

这是:

代码语言:javascript
运行
复制
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";
        }
    }

希望我没有错过任何东西,因为我从头到手指输入了这个代码.没有进行测试。

票数 0
EN

Stack Overflow用户

发布于 2022-09-07 18:14:07

在普通的Blazor输入控件上,当您退出控件时会发生更新。

要将它们连接到oninput事件,需要扩展现有控件。我添加了UpdateOnInput参数来控制将更新连接到哪个事件。

这是MyInputText

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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

这是我的考试表:

代码语言:javascript
运行
复制
@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):

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73639096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档