我已经找到了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键上提交表单。
答案 0 :(得分:2)
Leonardo Lurci,这是一个完全用C#实现的完整解决方案,没有JSInterop。事实证明,微软已经提供了此功能,但是他们没有提供足够的示例来演示如何使用它。
事实证明,我不能将@onkeypress="@KeyHandler"
和@onkeypress:preventDefault
对与诸如InputText之类的Forms组件一起使用,但是将这些指令应用于Html标签是可行的,并且效果很好。例如,请参见如何将这些指令应用于“提交”按钮。
因此,我将基类InputBase子类化,该类是InputText组件所派生的类,它通过添加输入元素来覆盖默认视图呈现,我可以在其中添加新功能的指令。
@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
事件。
而不是取消按键事件,您可以使用 addEventListener
和 capture: 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,您无需修改现有代码。
答案 4 :(得分:-1)
保持简单的方法:
将一个项目添加到您的项目的类定义中,以执行以下操作:
public string WhatToDo { get; set; }
添加一个不可见的按钮作为提交按钮中的第一个按钮,并且
在您的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;
}
}