Blazor input onkeydown - how to remove a specific character pressed

Posted 3 years ago by xicoJosue
Edited 3 years ago
0

- Blazor input onkeydown - how to remove a specific character pressed?

- InputNumber blazor remove "e" and "-"

    <input type="number" class="form-control" @bind="@CurrentValue" @onkeydown="KeyboardEventHandler"/>

@code {

  

   string KeyPressed = "";

   string EventInfo = "";

   private void KeyboardEventHandler(KeyboardEventArgs args)

   {

       KeyPressed = "Key Pressed is " + args.Key;

       EventInfo = "Event Type " + args.Type;

       if(args.Key.In("e",","))

       {

           //TODO: remove current key pressed

       }

   }

}

THANK YOU

  • 0

    Give this a try

    <input type="text" class="form-control" @bind="@CurrentValue" @onkeypress="KeyBoardEventHandler" @onkeypress:preventDefault />
    
    <p>@KeyPressed</p>
    
    <p>@EventInfo</p>
    
    @code {
        string KeyPressed = "";
        string EventInfo = "";
        string CurrentValue;
    
        private void KeyBoardEventHandler(KeyboardEventArgs args)
        {
            KeyPressed = "Key Pressed is " + args.Key;
            EventInfo = "Event Type " + args.Type;
            string[] invalidStringsArray = { "e", "-", "z", "" };
    
            if (invalidStringsArray.Contains(args.Key))
            {
                args.Key = string.Empty;
            }
    
            CurrentValue += args.Key;
        }
    }
    Posted 3 years ago by selliott Edited 3 years ago
  • 0

    Hello,
    Thank you for the reply selliot.
    Sorry but that won't work.
    My CurrentValue is of type T inherited by inputBase<T>.
    I can send you my CustomInputNumber component code:

    @using System.Linq.Expressions
    @using System.Globalization;
    
    @typeparam T
    @inherits CustomInputBase<T>
    @inject IJSRuntime JSRuntime
    
    <div class="form-control-wrapper">
       @if (!string.IsNullOrWhiteSpace(Label))
       {
           <label class="form-control-label" for="@Id">@Label</label>
       }  
    
       <input type="number" class="form-control txtNumero" id="@Id" @bind="@CurrentValue" placeholder="@PlaceHolder" aria-label="@AriaLabel" @ref="inputElement"  
              @onkeypress="KeyBoardEventHandler" @onkeypress:preventDefault/>
    
    </div>
    
    @code {
       [Parameter] public string Id { get; set; }
       [Parameter] public string Label { get; set; }
       [Parameter] public Expression<Func<T>> ValidationFor { get; set; }
       [Parameter] public RenderFragment ChildContent { get; set; }
       [Parameter] public bool ShowDefaultOption { get; set; } = true;
       [Parameter] public string PlaceHolder { get; set; }
       [Parameter] public string AriaLabel { get; set; }
       private ElementReference inputElement;
       
       string KeyPressed = "";
       string EventInfo = "";
    
       private void KeyBoardEventHandler(KeyboardEventArgs args)
       {
           KeyPressed = "Key Pressed is " + args.Key;
           EventInfo = "Event Type " + args.Type;
           string[] invalidStringsArray = { "e", "-", "z", "" };
    
           if (invalidStringsArray.Contains(args.Key))
           {
               args.Key = string.Empty;
           }
    
           CurrentValue += args.Key;
       }
    }

     

     

    Posted 3 years ago by xicoJosue Edited 3 years ago
  • 0

    I suspect one of your main issues is that you have your input type set as "number" instead of "text". Although, based on your naming convention, it looks like you're wanting it to input numbers...but I don't see why there'd be a need to prevent an "e" or "-" entered if that was the case, so I'm assuming you're wanting to input text? 

    Either way, here are some adjustments that should generally answer your question and have it functioning, then you can tweak it from there.

    It looks like you must have a CustomInputBase.cs file, so adjust it like this:

    public class CustomInputBase : InputBase<string>
    {
        [Parameter] public string Id { get; set; }
        [Parameter] public string Label { get; set; }
        [Parameter] public string PlaceHolder { get; set; }
        [Parameter] public string AriaLabel { get; set; }
        [Parameter] public bool ShowDefaultOption { get; set; } = true;
        [Parameter] public Expression<Func<string>> ValidationFor { get; set; }
    
        protected override bool TryParseValueFromString(string value, out string result, out string validationErrorMessage)
        {
            result = value;
            validationErrorMessage = null;
            return true;
        }
    }

    CustomInputNumber.razor (I also added a way to detect when backspace was entered)

    @inherits CustomInputBase
    @inject IJSRuntime JSRuntime
    
    <div class="form-control-wrapper">
        @if (!string.IsNullOrWhiteSpace(Label))
        {
            <label class="form-control-label" for="@Id">@Label</label>
        }
    
        <input type="text" class="form-control txtNumero" id="@Id" @bind="@CurrentValue" placeholder="@PlaceHolder" aria-label="@AriaLabel" @ref="inputElement"
               @onkeydown="KeyBoardEventHandler" @onkeydown:preventDefault />
        <div class="form-control-validation">
            <ValidationMessage For="@ValidationFor" />
        </div>
    </div>
    
    <p>@KeyPressed</p>
    
    <p>@EventInfo</p>
    
    @code {
        private ElementReference inputElement;
        string KeyPressed = "";
        string EventInfo = "";
    
        void KeyBoardEventHandler(KeyboardEventArgs args)
        {
            KeyPressed = "Key Pressed is " + args.Key;
            EventInfo = "Event Type " + args.Type;
            string[] invalidStringsArray = { "e", "-" };
    
            if (args.Key == "Backspace")
            {
                CurrentValue = CurrentValue.Remove(CurrentValue.Length - 1);
            }
            else
            {
                if (invalidStringsArray.Contains(args.Key))
                {
                    args.Key = string.Empty;
                }
    
                CurrentValue += args.Key;
            }
        }
    }

    Then enter it into a component like this. Now it will not enter and "e" or "-".

    <EditForm Model="model">
        <CustomInputNumber @bind-Value="model.CurrentValue" ValidationFor="(() => model.CurrentValue)" Label="My Label" />
    </EditForm>
    
    
    @code {
        SomeModel model = new SomeModel();
    
        public class SomeModel
        {
            public string SomeString { get; set; }
            public string CurrentValue { get; set; }
        }
    }
    Posted 3 years ago by selliott Edited 3 years ago
  • 0

    Thank you for yout answer again,

    Yes i want an input type Number that only allow to enter numbers only. the Default input type "Number" is letting me to enter " e ", " , " and " - ", and i dont want that.

    Posted 3 years ago by xicoJosue Edited 3 years ago
  • 0

    Adjusting your CustomInputNumber component like this may work for you then. It sounds like you just need to filter out anything that isn't a number, for cases where a browser isn't limiting the input to only numbers.

    @using System.Text.RegularExpressions
    @inherits CustomInputBase
    @inject IJSRuntime JSRuntime
    
    <div class="form-control-wrapper">
        @if (!string.IsNullOrWhiteSpace(Label))
        {
            <label class="form-control-label" for="@Id">@Label</label>
        }
    
        <input type="number" class="form-control txtNumero" id="@Id" @bind="@CurrentValue" placeholder="@PlaceHolder" aria-label="@AriaLabel" @ref="inputElement"
               @onkeydown="KeyBoardEventHandler" @onkeydown:preventDefault />
        <div class="form-control-validation">
            <ValidationMessage For="@ValidationFor" />
        </div>
    </div>
    
    <p>@KeyPressed</p>
    
    <p>@EventInfo</p>
    
    @code {
        private ElementReference inputElement;
        string KeyPressed = "";
        string EventInfo = "";
    
        void KeyBoardEventHandler(KeyboardEventArgs args)
        {
            KeyPressed = "Key Pressed is " + args.Key;
            EventInfo = "Event Type " + args.Type;
            Regex regex = new Regex(@"^[0-9]+$");
    
            if (args.Key == "Backspace")
            {
                CurrentValue = CurrentValue.Remove(CurrentValue.Length - 1);
            }
            else
            {
                if (regex.IsMatch(args.Key))
                {
                    CurrentValue += args.Key;
                }
            }
        }
    }
    Posted 3 years ago by selliott
  • 0

    I think the problem is in the CurrentValue because when I enter " e " the CurrentValue becomes null.

     

    When i enter your code it is not compiling because CurrentValue is of type T? (T nullable)

    the current value belongs to the abstact class InputBase<TValue> and is a property like:

    protected TValue? CurrentValue { get; set; }
    Posted 3 years ago by xicoJosue
  • 0

    The code I posted is compiling and working for me. I set it up to use InputBase<string>. Please try creating a new project with my code from my last two posts (using the most recent CustomInputNumber component code from my last post) and see if it works for you.

    Posted 3 years ago by selliott
  • 0

    The "@onkeydown:preventDefault" dont let me writte anything

    Posted 3 years ago by xicoJosue
  • 0

    What browser are you using? If you aren't using Firefox or the latest Microsoft Edge, see if you get the same results with those.

    Posted 3 years ago by selliott Edited 3 years ago
  • 0

    Chrome

    The inputBase cannot be of type string because the binding property is of type int?

    I have solved it, thanks for your time.

    The solution:

    @using System.Linq.Expressions
    @using System.Text.RegularExpressions
    
    @inherits CustomInputBase<int?>
    @inject IJSRuntime JSRuntime
    
    <div class="form-control-wrapper">
        @if (!string.IsNullOrWhiteSpace(Label))
        {
            <label for="@Id">@Label</label>
        }
    
        <input type="number" class="form-control txtNumero @fixClassNames(CssClass)" id="@Id" @bind="@CurrentValueAsString" placeholder="@PlaceHolder" aria-label="@AriaLabel" @ref="inputElement"
               @onkeydown="KeyBoardEventHandler" @onkeydown:preventDefault />
    
        @if (ValidationFor != null)
        {
            <div class="form-control-validation">
                <CustomValidationMessage For="@ValidationFor" Class="@ValidationMessageCssClass" />
            </div>
        }
    </div>
    @code {
        [Parameter] public string Id { get; set; }
        [Parameter] public string Label { get; set; }
        [Parameter] public Expression<Func<int?>> ValidationFor { get; set; }
        [Parameter] public RenderFragment ChildContent { get; set; }
        [Parameter] public bool ShowDefaultOption { get; set; } = true;
        [Parameter] public string PlaceHolder { get; set; }
        [Parameter] public string AriaLabel { get; set; }
        [Parameter] public string ValidationMessageCssClass { get; set; } = "validation-message";
    
        private ElementReference inputElement;
    
        void KeyBoardEventHandler(KeyboardEventArgs args)
        {
            Regex regex = new Regex(@"^[0-9]+$");
    
            if (args.Key == "Backspace" && !CurrentValueAsString.NullOuVazio())
            {
                string numeros = CurrentValueAsString.Remove(CurrentValueAsString.Length - 1);
                if (numeros.NullOuVazio())
                    CurrentValueAsString = null;
                else if (regex.IsMatch(numeros))
                    CurrentValueAsString = numeros;
            }
            else
            {
                if (regex.IsMatch(args.Key))
                {
                    CurrentValueAsString += args.Key;
                }
            }
        }
    }
    
    Posted 3 years ago by xicoJosue Edited 3 years ago
Someone is typing...

Post a Reply

You must be logged in to add a new post.
Number of online users: 1
An error has occurred. This application may no longer respond until reloaded. Reload 🗙