Blazor - How do you prevent non-numeric characters in a Textbox (InputText)?
Asked Answered
C

8

9

I have an InputText in blazor and I want to prevent non-numeric characters, what is the basic razor and c# code to do that? here is how I need it to work, a user enters a character and it refuses the entry all together AND displays a validation message that says only Numbers are allowed. So far I've tried datanotations range attribute using regex but that does not refuse nonnumeric characters.

Churl answered 23/2, 2021 at 20:59 Comment(0)
R
10

It's actualy a html/javascript thing. Adding

onkeypress="return (event.charCode !=8 && event.charCode ==0 || (event.charCode >= 48 && event.charCode <= 57))"

to your html input element will prevent user from typing in non-numerics. If you need to display a validation message, i would rather use something like

@oninput="async () => await isInputNumeric()"

in this element then create funtion

private async Task isInputNumeric() { // call javascript to check the what is inside you input element (what is the last character) and act accordingly -> show message and delete the non-numeric character OR carry on if input is numeric }

You would have to use javascript since blazor does not yet have the c# way of accessing the html elements.

Rolandrolanda answered 9/3, 2021 at 9:6 Comment(5)
You saved me hours namastePredation
thanks. I implemented this using javascript interop as I didn't have direct access to the input elementSchock
Work for me, thanks. Why do you allow the NUL char (event.charCode ==0)?Helbonnah
As written in https://unixpapa.com/js/key.html, it says that keypress would not be fired for those cases where event.char is null.Rolandrolanda
Can be done without JavaScript using solution below with preventDefaultInteroffice
Z
6

dinozaver answered your question well, but I want to add some (I think very important) advice: you aren't obligated to use Blazor's custom controls, which mainly handle validation.

If you want a numeric input, I recommend just using one:

<input type="number" @bind="MyImportantNumber" />

@code 
{
     int MyImportantNumber { get; set; }
}

You can get more info Here. HTML number inputs allow you to set min/max values, the step amount of the spinner control and so on. Also, using an html number control on a mobile device will popup a numerical keypad, which users might find convenient.

Zorine answered 9/3, 2021 at 9:33 Comment(7)
Very helpful hint about mobile users!Pushing
note that number inputs still accept the letter eHonkytonk
@Honkytonk I didn't know that. Do you mean "e" as in "exponent", as in a base of 10?Zorine
@Zorine yes "e" for "exponent" to shorten long numbersHonkytonk
Do mobile devices have some button for that as well? I don't recall having seen it.Zorine
type=“number” is not always a good option. Read: technology.blog.gov.uk/2020/02/24/…Vanburen
@Vanburen Thanks for the link, that was interesting to read. I suppose it depends on context. I don't think most people using Blazor are likely to take accessibility as a top concern. As for me-- if I wanted to make a site more accessible, I'd probably go with more than changing input types. I'd probably go with STT voice input running through an AI engine. (I'm already well into developinog with this stuff on my English site). That being said, Tim Corey did a great video recently about the importance of new perspectives on engineering: youtube.com/watch?v=eEtgNdLZ6LgZorine
D
4

I know it's been a while, but I solved this problem using only html + cs. You don't need any js. If anyone still needs to enter data using only letters, check it out, it's worth using this simple solution.

Explanation:

Since the OnKeyDown method executes before the OnInput method, PreventDefault will be specified there to display or not display a character other than letters or spaces. I used Regular Expressions to check the correctness of the entered character.

Solution:

You need to take care of 4 things:

  • binding Value to your input
  • handle the @oninput method
  • handle the @onkeydown method
  • handle the @onkeydown:preventDefault property

The html section should looks like this:

<input @bind=@Value
       @onkeydown=OnKeyDown 
       @onkeydown:preventDefault=@PreventDefault
       @oninput="@((x) => { OnInput((string)x.Value); })" />

In the @code section, use such properties and methods:

private string Value;
private bool PreventDefault = false;
private Regex rgx = new Regex("[^a-zA-Z ']")
private void OnInput(string value) => Value = value;
private void OnKeyDown(KeyboardEventArgs e) => PreventDefault = rgx.Replace(e.Key, "") == ""; 

I hope it will be useful.

Dopp answered 6/10, 2023 at 17:28 Comment(0)
P
3

If you are into a EditForm context you can use the blazor component InputNumber for edit Int32, Int64, Int16, Single, Double, Decimal. According to Blazor Docs it's rendered like:

<input type="number"/>

Example of use:

<EditForm Model="myObject">
    <InputNumber @bind-Value="myObject.mydouble" />
    <ValidationMessage For="()=> myObject.mydouble"/>
</EditForm>

@code {
    private MyObject myObject = new MyObject();

    class MyObject {
        public double mydouble { get; set; }
    }
} 

Thanks to ValidationMessage component, if user tries to input non-numeric characters a message is displayed. The type of binding variable can be inferred by the compiler, or you can explicity indicate like:

<InputNumber TValue="double" @bind-Value="myObject.mydouble" />
Perverse answered 28/8, 2021 at 9:25 Comment(1)
Yeah, that would be the Blazor way to do it. I kind of question validating inputs that are automatically validated by the browser, though. If you have an <input type="number"> people are going to figure out pretty quick what they need to do.Zorine
N
1

Pure C#

<input type="text" class="input-group"
       @bind="text"
       @onkeydown=OnKeyDown
       @onkeydown:preventDefault=@preventDefault
       @bind:event="oninput" />

@code {
    string text = string.Empty;

    bool preventDefault = false;
 
    void OnKeyDown(KeyboardEventArgs e)
    {
        preventDefault = IsNumericLetter(e.Key, text) == false;
    }

    static bool IsNumericLetter(string letter, string text)
    {
        if(letter == "Backspace" || letter == "ArrowLeft" || letter == "ArrowRight" || letter == "Delete" || letter == "Enter") {
            return true;
        }
        // validate key pressed
        char keyChar = letter.ToCharArray()[0];

        if(char.IsDigit(keyChar)) {
            return true;
        }
        if(keyChar == '-' && text.Contains('-') == false && text.Length == 0 /* only first char */) {
            return true;
        }
        if(keyChar == '.' && text.Contains('.') == false) {
            return true;
        }
        return false;
    }
}
Namely answered 3/5 at 13:12 Comment(0)
Y
0

I think you can solve it with a Html tag, just use : <input type="number ...> You can check here the documentation. https://developer.mozilla.org/es/docs/Web/HTML/Element/input/number

Yogi answered 27/8, 2021 at 12:25 Comment(0)
C
0

Can't comment the other's answer but it works perfect!

Add to the Script section in Host.cshtml:

$(document).on("keypress",".numbers", function (e) {
                return (e.charCode != 8 && e.charCode == 0 || (e.charCode >= 48 && e.charCode <= 57));
            });
$(document).on("paste", ".numbers", function (e) {
            e.preventDefault();
            let paste = (e.originalEvent.clipboardData || window.clipboardData).getData('text');
            this.value = paste.replace(/\D/g, '');
            this.dispatchEvent(new Event('change'));
            });

Your input must contain class="numbers":

<input type="text" class="numbers" @bind-value="@anyValue"/>
Cookery answered 8/9, 2021 at 16:12 Comment(0)
M
-2

you can add jquery as helper.

<input type="text" @bind="Model" class="NumberOnly" />

and put this code on MainLayout.razor

<script>  
$(document).on("keypress", ".NumberOnly", function(e){
    return (e.charCode !=8 && e.charCode ==0 || (e.charCode >= 48 && e.charCode <= 57));
});
</script>
Maureen answered 19/8, 2021 at 7:46 Comment(1)
I would advise against adding the entirety of jQuery to a Blazor app just to accomplish this one thingRadiobiology

© 2022 - 2024 — McMap. All rights reserved.