Home > OS >  How to call a method after hitting Enter in a Razor Component?
How to call a method after hitting Enter in a Razor Component?

Time:07-08

I have a razor component with the following text field

<input @bind=nameToAdd @onsubmit="AddName" />

I want to call the AddName method after user hits the enter button from the textbox. How can I achieve that?

CodePudding user response:

You can accomplish this with the onkeypress event handler. This event handler fires for every keypress, so you'll need to look for the enter key specifically, which is Key = 13, or Code = Enter. You can search 'KeyboardEventArgs' for the list of keys and codes.

Component.razor

<h3>Component</h3>

<input @bind=nameToAdd @onkeypress="HandleKeyPress" @onsubmit="AddName" />

@code {
    public string nameToAdd { get; set; } = string.Empty;

    public void AddName()
    {
        //Add Name logic here
        //..
        //Clear the input box when done
        nameToAdd = string.Empty;
    }

    private void HandleKeyPress(KeyboardEventArgs keyboardEventArgs)
    {
        if (keyboardEventArgs.Code == "Enter")
        {
            AddName();
        }
    }
}

CodePudding user response:

Not sure where you got onsubmit, but here's the basic concept using onchange and oninput.

@page "/"

<div >
    <h3>On enter/loose focus</h3>
    <input value=@nameToAdd @onchange="AddName" />
    <div>
        value: @nameToAdd
    </div>
</div>
<div >
    <h3>On keystroke</h3>
    <input value=@nameToAdd2 @oninput="AddName2" />
    <div>
        value2: @nameToAdd2
    </div>
</div>

@code {
    private string? nameToAdd;
    private string? nameToAdd2;

    private void AddName(ChangeEventArgs e)
    {
        nameToAdd = e.Value?.ToString() ?? string.Empty;
    }

    private void AddName2(ChangeEventArgs e)
    {
        nameToAdd2 = e.Value?.ToString() ?? string.Empty;
    }
}

Copy and paste into index.razor in a new solution.

@onsubmit does nothing on an input. @bind sets value to the specified property and @onchange to an anonymous method that updates the specified property.

CodePudding user response:

This is what I use for a similar purpose in many projects. On enter it resets the focus to the input. It uses the templates bootstrap 5.

Usage:

<SendBox OnSend=SomeMethod />

@code {
    void SomeMethod(string input)
    {
        ...
    }
}

SendBox.razor

<EditForm Model="@SendBoxViewModel" OnValidSubmit="@Send">

    <DataAnnotationsValidator />
    <div >
        <input @ref="@inputBox"
               @bind-value="SendBoxViewModel.InputMessage"
               @bind-value:event="oninput"
               type="text"
               aria-label="@Placeholder"
               placeholder="@Placeholder"
               
               aria-describedby="button-send"
               disabled=@Disabled>

        <button 
                type="submit"
                id="button-send"
                disabled=@Disabled>
            @Label
        </button>

    </div>
    <ValidationMessage For=@(() => SendBoxViewModel.InputMessage) />

</EditForm>

Note: OnSubmit can be used here. The use of the DataAnnotationsValidator and ValidationMessage is not required for the functionality your after. The button can be hidden if required however some people use touch screens ;).

I use the code behind approach:

SendBox.razor.cs

public partial class SendBox : ComponentBase
{
    private ElementReference inputBox;

    [Parameter]
    public string Label { get; set; } = "Send";

    [Parameter]
    public string Placeholder { get; set; } = "Type a new message here.";

    [Parameter]
    public string DivClass { get; set; } = "input-group";

    [Parameter]
    public string InputClass { get; set; } = "form-control";

    [Parameter]
    public string ButtonClass { get; set; } = "btn btn-outline-primary";

    [Parameter]
    public bool Disabled { get; set; }

    [Parameter]
    public EventCallback<string> OnSend { get; set; }

    public SendBoxViewModel SendBoxViewModel { get; set; } = new SendBoxViewModel();

    private bool MessageInputInvalid => string.IsNullOrWhiteSpace(SendBoxViewModel.InputMessage);

    private async Task Send()
    {
        if (!MessageInputInvalid)
        {
            await OnSend.InvokeAsync(SendBoxViewModel.InputMessage);
            SendBoxViewModel.InputMessage = string.Empty;
            await inputBox.FocusAsync();
        }
    }
}

public class SendBoxViewModel
{
    [MinLength(length: 1)]
    [MaxLength(length: 1024)]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Empty messages are not allowed!")]
    public string InputMessage { get; set; } = string.Empty;
}

  • Related