I've found this article but I'm having a hard time to understand how can I prevent submit on "enter" key independently by any <input>
<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 key On HTML forms if you are filling out a text box and press the enter key it will submit the form, even if you haven't finished filling in the rest of the information. There are many websites which use this feature such as Google search box will submit when you press the enter key. This works because you only have one text box to fill out, but if there are more than one field to fill in you don't want the form to submit on the enter key.
Leonardo Lurci, here's a complete solution implemented purely in C#, no JSInterop. As it turned out, Microsoft has already provided this feature, but they did not provide enough samples to demonstrate how to use it.
As it turned out, I cannot use the pair @onkeypress="@KeyHandler"
and @onkeypress:preventDefault
with the Forms components such as InputText, but applying these directives to Html tags is viable and works perfectly well. See for instance how I apply these directives to the "submit" button.
Consequently, I subclass the base class InputBase, this is the class from which the InputText components derive, overrides the default view rendering by adding an input element to which I can add the directives of the new feature.
TextBox.razor (this comes instead of 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;
}
}
Usage
<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";
}
}
Please, don't hesitate to ask any questions
Hope this helps...
As Enet suggested in the comments, there isn't a full Blazor (Csharp) solution for this use-case. You have to interact with JavaScript.
Currently, I solved with this workaround:
blazor-side
@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;
}
});
}
I hope Microsoft will develop this feature in the future.
Thanks to Enet.
Add event handlers to your input and submit elements like this:
<InputText id="name" @bind-Value="exampleModel.Name" @onkeydown="PreventSubmit"/>
<button type="submit" @onclick="ShouldISubmit">Submit</button>
Add this to your @code block:
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;
}
Change your submit function to this
private void HandleValidSubmit()
{
if (shouldsubmit) {
Console.WriteLine("OnValidSubmit");
}
}
I found a simple solution that I think is the easiest option. Create a custom component that will be your submit button:
<button type="button" @onclick="OnClick" @attributes="UnmatchedAttributes">@Text</button>
@code {
[Parameter]
public string Text { get; set; }
[Parameter]
public Func<Task> OnValidSubmitAsync { get; set; }
[Parameter]
public Action OnValidSubmit { get; set; }
[CascadingParameter]
public EditContext EditContext { get; set; }
[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, object> UnmatchedAttributes { get; set; }
private async Task OnClick() {
if (EditContext != null) {
if (EditContext.Validate()) {
if (OnValidSubmit != null) {
OnValidSubmit();
} else {
if (OnValidSubmitAsync != null) {
await OnValidSubmitAsync();
}
}
}
}
}
}
This component acts as a submit button, but since its type is not submit, an enter won't trigger it. It accepts a cascading parameter of type EditContext which allows it to validate the form. It also accepts a delegate which will be triggered when it is clicked and the form state is valid.
Usage example:
<EditForm Model="model">
<input type="text" @bind="model.Value" />
@* Add the custom submit component*@
<EditFormSubmit Text="Submit" OnValidSubmit="Submit" class="btn btn-primary"></EditFormSubmit>
</EditForm>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With