EditForm-如何防止按回车键提交

时间:2020-05-27 23:45:04

标签: blazor

我已经找到了this article,但是我很难理解如何防止任何<input>的情况下单独通过“ enter”键提交

<EditForm Model="exampleModel" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <InputText id="name" @bind-Value="exampleModel.Name" />
    <InputText id="name2" @bind-Value="exampleModel.Name2" />

    <button type="submit">Submit</button>
</EditForm>
@code {
    private ExampleModel exampleModel = new ExampleModel();

    private void HandleValidSubmit()
    {
        Console.WriteLine("OnValidSubmit");
    }

    public class ExampleModel
    {
         [Required]
         [StringLength(10, ErrorMessage = "Name is too long.")]
         public string Name { get; set; }
         public string Name2 {get; set;}
    }
}

用例

Enter键在HTML表单上,如果您要填写文本框,然后按Enter键,即使您尚未完成其余信息的填写,它也会提交表单。有许多使用此功能的网站,例如当您按Enter键时将提交Google搜索框。之所以可行,是因为您只需要填写一个文本框,但是如果要填写的字段不止一个,则您不希望在Enter键上提交表单。

5 个答案:

答案 0 :(得分:2)

Leonardo Lurci,这是一个完全用C#实现的完整解决方案,没有JSInterop。事实证明,微软已经提供了此功能,但是他们没有提供足够的示例来演示如何使用它。

事实证明,我不能将@onkeypress="@KeyHandler"@onkeypress:preventDefault对与诸如InputText之类的Forms组件一起使用,但是将这些指令应用于Html标签是可行的,并且效果很好。例如,请参见如何将这些指令应用于“提交”按钮。

因此,我将基类InputBase子类化,该类是InputText组件所派生的类,它通过添加输入元素来覆盖默认视图呈现,我可以在其中添加新功能的指令。

TextBox.razor(代替InpuText)

@inherits InputBase<string>

<input type="text" value="@CurrentValueAsString" id="Id" class="@CssClass" 
   @onkeydown="KeyDownHandler" @onkeypress="KeyPressHandler" 
                                               @onkeypress:preventDefault/>

 @code{

protected override bool TryParseValueFromString(string value, out string 
                                  result, out string validationErrorMessage)
{
    result = value;
    validationErrorMessage = null;
    return true;
}

void KeyDownHandler(KeyboardEventArgs args)
{
    if (args.Key == "Backspace" && CurrentValueAsString.Length >=1)
    {
        CurrentValueAsString = CurrentValueAsString.Substring(0, 
                                   CurrentValueAsString.Length - 1);
    }
}

 void KeyPressHandler(KeyboardEventArgs args)
 {

    if (args.Key == "Enter")
    {
        return;
    }
    var key = (string)args.Key;
    CurrentValueAsString += key;
 }
}

用法

<p>Leave me a comment</p>

<EditForm Model="Model" OnValidSubmit="HandleValidSubmit" >
<DataAnnotationsValidator />

 <div class="form-group">
    <label for="name">Name: </label>
    <TextBox Id="name" Class="form-control" @bind-Value="@Model.Name" >
    </TextBox>
    <ValidationMessage For="@(() => Model.Name)" />

 </div>
 <div class="form-group">
    <label for="body">Text: </label>
    <InputTextArea Id="body" Class="form-control" @bind-Value="@Model.Text" > 
    </InputTextArea>
    <ValidationMessage For="@(() => Model.Text)" />
 </div>
 <p>
    <button type="submit" @onkeypress="KeyHandler" @onkeypress:preventDefault>
        Submit
    </button>
 </p>
</EditForm>


@code
{
    private Comment Model = new Comment();

    private void HandleValidSubmit()
    {
         Console.WriteLine("Submit...");
    }


    void KeyHandler(KeyboardEventArgs args)
    {
        if (args.Key == "Enter")
        {
           return;
         }
    }

    public class Comment
    {
        public string Name { get; set; } = "Jeff";
        public string Text { get; set; } = "I'm Jeff. I'm from Canada";
    }

}

请不要犹豫,问任何问题

希望这对您有帮助...

答案 1 :(得分:1)

正如Enet在评论中建议的那样,该用例没有完整的Blazor(Csharp)解决方案。您必须与JavaScript交互。

目前,我已通过以下解决方法解决了此问题:

火辣的一面

@inject IJSRuntime JS
<EditForm id="askQuestionForm" Model="exampleModel" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <InputText id="name" @bind-Value="exampleModel.Name" />
    <InputText id="name2" @bind-Value="exampleModel.Name2" />

    <button type="submit">Submit</button>
</EditForm>
@code {
    private ExampleModel exampleModel = new ExampleModel();

    private void HandleValidSubmit()
    {
        Console.WriteLine("OnValidSubmit");
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender) 
        {
            JS.InvokeVoidAsync("PreventEnterKey", "askQuestionForm");
        }
    }

    public class ExampleModel
    {
         [Required]
         [StringLength(10, ErrorMessage = "Name is too long.")]
         public string Name { get; set; }
         public string Name2 {get; set;}
    }
}

interop.js

function PreventEnterKey(id) {
    $(`#${id}`).keydown(function (event) {
        if (event.keyCode == 13) {
            event.preventDefault();
            return false;
        }
    });
}

我希望微软将来会开发此功能。

感谢Enet。

答案 2 :(得分:1)

将事件处理程序添加到您的输入并提交如下元素:

<InputText id="name" @bind-Value="exampleModel.Name" @onkeydown="PreventSubmit"/>
<button type="submit" @onclick="ShouldISubmit">Submit</button>

将此添加到您的@code块:

    public bool shouldsubmit { get; set; }

    public bool entersubmit { get; set; }

    public void PreventSubmit(KeyboardEventArgs ev)
    {
        if (ev.Key == "Enter")
            entersubmit = true;
    }

    public void ShouldISubmit()
    {
        if (entersubmit)
            shouldsubmit = false;
        else
            shouldsubmit = true;
        entersubmit = false;
    }

将您的提交功能更改为此

    private void HandleValidSubmit()
    {
        if (shouldsubmit) {
            Console.WriteLine("OnValidSubmit");
        }
    }

答案 3 :(得分:0)

首先,您应该了解浏览器在这种情况下的行为。 如果表单中有 <button type="submit">,并且用户按下 Enter,浏览器将模拟按钮上的 click 事件。

而不是取消按键事件,您可以使用 addEventListenercapture: true 来阻止点击事件。

只需添加以下javascript:

//prevent submit on enter
document.body.addEventListener('keypress', e => {
    if (e.which == ENTER && !e.target.matches('button[type=submit]')) {

        /** @type {HTMLFormElement} */
        const form = e.composedPath().find(e => e.matches('form'))

        /** @type {HTMLButtonElement} */
        const submitButton = form && form.querySelector('button[type=submit]:enabled');

        if (submitButton) {
            const preventSubmit = (e2) => {
                e2.preventDefault();
                return false;
            }
            // Browser emulates submit button click, when enter key is pressed, so we need to prevent that.
            form.addEventListener('click', preventSubmit, { once: true, capture: true });
            setTimeout(() => form.removeEventListener('click', preventSubmit, { capture: true }), 0); // better clear the eventlistener despite once:true in case the keypress propagation has been stopped by some other eventhandler
        }
        
    }
});

它适用于 Blazor Server 和 Blazor WebAssembly,您无需修改​​现有代码。

此处演示:https://blazorrepl.com/repl/mvYgPhPx007ySOGe03

答案 4 :(得分:-1)

保持简单的方法:

  1. 将一个项目添加到您的项目的类定义中,以执行以下操作:

    public string WhatToDo { get; set; }
    
  2. 添加一个不可见的按钮作为提交按钮中的第一个按钮,并且

  3. 在您的OnSubmit方法中测试其值。如果用户仅按Enter,则将返回此按钮的值。

如果它的值是(在我的情况下为“ DoNothing”),则只需返回即可。

<EditForm..... with OnSubmit parameters>
...

   <button type="submit" @onclick="@(()=> selectedItem.WhatToDo = "DoNothing")" class="btn btn-primary" style="display:none;">Do Nothing</button>
    <button type="submit" @onclick="@(()=> selectedItem.WhatToDo = "Save")" class="btn btn-primary">Save</button>
    <button type="submit" @onclick="@(()=> selectedItem.WhatToDo = "ExitWOSave")" class="btn btn-primary">Exit w/o Saving</button>
</EditForm>

@code {
  private async Task InsertOrUpdateItem()
    {
        Console.WriteLine("WhatToDo is XX" + selectedItem.WhatToDo + "XX");

        if (selectedItem.WhatToDo == "ExitWOSave")   //test for this first
        {
            // Navigate away…
            return;
        };

        if (selectedItem.WhatToDo == "DoNothing")
        { return; }

        if (selectedItem.WhatToDo == "Save")
        { //do your save…
    return; 
}

}