41

I was trying the todo-list example from Microsoft: https://learn.microsoft.com/en-us/aspnet/core/tutorials/build-a-blazor-app?view=aspnetcore-3.1

I want to add a todo item and instead of pressing the button with a mouse click I want to press the enter key. I'm not happy with using JS like in this solution: How to set the focus to an InputText element? And I try to trigger the method private void Enter(KeyboardEventArgs e) by this line of code:

<button @onclick="AddTodo" @onkeypress="@(e=>Enter(e)" tabindex="0"  >Add todo</button>

It didn't work.

    enter code here
    <input placeholder="Something todo" @bind="newTodo" />
    <button @onclick="AddTodo" @onkeypress="Enter" tabindex="0"  >Add todo</button>

    @code {
        private IList<TodoItem> todos = new List<TodoItem>();
        private string newTodo;
    
        private void AddTodo()
        {
            if (!string.IsNullOrWhiteSpace(newTodo))
            {
                todos.Add(new TodoItem { Title = newTodo });
                newTodo = string.Empty;
            }
        }
    
        //private void Enter(KeyboardEventArgs e)
            private void Enter()
        {
            //if (e.Key == "Enter")
            {
                if (!string.IsNullOrWhiteSpace(newTodo))
                {
                    todos.Add(new TodoItem { Title = newTodo });
                    newTodo = string.Empty;
                }
            }
        }
    }
Paul Carlton
  • 2,785
  • 2
  • 24
  • 42

6 Answers6

87

onkeypress is fired only for character keys. onkeydown will fire for all keys pressed. I found some explanation of differences between all key events here

Try it with onkeydown and it worked:

<input type="text" @onkeydown="@Enter" />

In the event handler you will have to do this (notice that I check for both Enter and NumpadEnter keys):

public void Enter(KeyboardEventArgs e)
{
    if (e.Code == "Enter" || e.Code == "NumpadEnter")
    {
         // ...
    }
}
Paul Carlton
  • 2,785
  • 2
  • 24
  • 42
Umair
  • 4,864
  • 3
  • 28
  • 47
  • I'm sorry that didn't solve it. onkeydown still doesn't trigger the Enter method – Diego Rodriguez Nava Sep 12 '20 at 19:15
  • I just tried it with enter key and works for me, see this screenshot in debug mode: https://i.imgur.com/870rtg8.png Also you will have to add both `Enter` and `NumpadEnter` for both enter keys. – Umair Sep 12 '20 at 20:24
  • I think he wants the Enter to trigger in a TextBox, not on the Button. – H H Sep 12 '20 at 20:29
  • Ah yes, didn't realize that I was using a button copied from question, but the event handler will work for both, I will update the answer. – Umair Sep 12 '20 at 20:36
  • 4
    I used @onkeyup="@Enter" instead to press enter key one time. I also was trying to do something like this: @onkeyup="@ (e=>e.Code=="Enter"?Enter(e))" but it didn't work. Great job. Congratulations, very knowledgeable... – Diego Rodriguez Nava Sep 13 '20 at 11:51
  • KeyboardEventArgs dont work fine when using Android. – Elyel Rubens da Rosa May 18 '23 at 20:36
32

If you use an HTML form, it is simple - no looking for keypresses, just let the browser do the work:

<form @onsubmit=Enter>
  <label for="todo">What to do?</label>
  <input id="todo" placeholder="Something todo" @bind="newTodo" />
  <button>Add todo</button>
</form>
<ul>
@foreach(var item in todos)
{
    <li @key=item>@item.Title</li>
}
</ul>
@code {
    private class TodoItem { public string Title { get; set; } }
    private IList<TodoItem> todos = new List<TodoItem>();
    private string newTodo;

    private void Enter()
    {
        if (!string.IsNullOrWhiteSpace(newTodo))
        {
            todos.Add(new TodoItem { Title = newTodo });
            newTodo = string.Empty;
        }
    }
}

You can try it out here: https://blazorrepl.com/repl/wPabvwlv138n6KMN23

Mister Magoo
  • 7,452
  • 1
  • 20
  • 35
2

We can achieve this by combining the two events

<input placeholder="Task Heading" @bind="title" id="todo"  @bind:event="oninput" @onkeydown="@Enter1" />


public async Task Enter1(KeyboardEventArgs e)
{
    if (e.Code == "Enter" || e.Code == "NumpadEnter")
    {
        await js.InvokeVoidAsync("foucusById", "desc");
    }

}
Sachith Wickramaarachchi
  • 5,546
  • 6
  • 39
  • 68
0

As mentioned Umair, you can use:

<input type="text" @onkeydown="@Enter" />

With handler

public void Enter(KeyboardEventArgs e)
{
    if (e.Code == "Enter" || e.Code == "NumpadEnter")
    {
         // ...
    }
}

but this solution does not cover "Enter press" on mobile device keyboards (tested on my Android). If you use e.Key instead of e.Code, then it covers also NumPad enter and the mobile device as well

public void Enter(KeyboardEventArgs e)
{
    if (e.Key == "Enter")// Covers: Enter + NumPad Enter + Mobile keyboard Go to(enter)
    {
         // ...
    }
}

Here is a nice web where you can test it: https://w3c.github.io/uievents/tools/key-event-viewer.html Just compare the UI Events Key and Code behaviour

0

These answers work great unless they are nested within an <EditForm>. Solutions using @onkeydown="@Enter" will also trigger the <EditForm> OnValidSubmit.

In this case, the best solution I've found is to nest another <EditForm> wrapped around the <input> and using it's OnValidSubmit to detect the enter key.

<EditForm EditContext="_editContext" OnValidSubmit="HandleValidFormSubmit">
    -- SOME OTHER FORM CONTROLS HERE ---
    <EditForm EditContext="_editContext" Context="entercontext" OnValidSubmit="Enter">
        <input type="text" />
    </EditForm>
</EditForm>

private void Enter()
{

}
clamchoda
  • 4,411
  • 2
  • 36
  • 74
-1

The browser will already do this if you add the type="submit" attribute to your button.

<button type="submit" @onclick="AddTodo" @onkeypress="Enter" tabindex="0"  >Add todo</button>
Jason Honingford
  • 540
  • 5
  • 17
  • 1
    This only works if both the textbox and the button are inside the same `
    ` element. As seen Mister Magoo's answer.
    – Martijn Oct 04 '21 at 11:35