-1
function NumberKey(event) {
    let charCode = event.which || event.keyCode;
    console.log(event.keyCode)
    if ((charCode >= 48 && charCode <= 57) || //  Number (0-9)
        (charCode >= 96 && charCode <= 105) || // Numberpad (0-9)
        (charCode >=112 && charCode <= 123)|| // F keys (F1~12)
        charCode === 8 || // backspace
        charCode === 9 || // tab
        charCode === 13|| // enter
        charCode === 37 || // arrow left
        charCode === 39 || // arrow right
        charCode === 46){ // delete
    }else{
    event.preventDefault();
    return false;
    }
}

this is my code to prevent user typing anything else than numbers

and when I apply it as

onkeydown="return NumberKey(event)"

{% (with shift)
`qwertyuipasdfgh'zxcvb. (without shift)

+IME based languages are typable

onkeypress="return NumberKey(event)"

!@#$%^&*() (with shift)

+IME based languages are typable

When I apply both,

% (with shift)

+IME based languages are typable

I do not understand certain things about this result

  1. Why would onkeypress and onkeydown give different result?

  2. Why does onkeypress let % printed while it block all the rest special letters?

And for the other issue, I need help

Through console, I figured out that IME based languages are not counted as event. I've done some searching, finding out that IME takes the letter away as part of composition, which eventually never let me take the letter before it is shown on the screen.

I knew input type="password" would force IME to be disabled, forcing user to type English only. Which was fascinating just except that the letters are hidden, so I can't use them for phone numbers or IDs

tried ime-mode:disabled, found out it was deprecated for security issue long time ago.

Many people I found on web just let the user type whatever and delete afterwards if typed items do not satisfy certain conditions, which is definitely not what I want...

document.addEventListener('DOMContentLoaded', function() {
    const inputElement = document.getElementById('yourInputElementId');
    inputElement.addEventListener('compositionstart', function(event) {
        event.preventDefault();
    });
    inputElement.addEventListener('compositionupdate', function(event) {
        event.preventDefault();
    });
    inputElement.addEventListener('compositionend', function(event) {
        event.preventDefault();
    });
});

This is what ChatGPT suggested, which didn't work at all.

Oh and I forgot to say that I tried regex too, which didn't work the way I wanted... Here's some regex I tried

function NumberKey(evt) {
    let charCode = evt.which || evt.keyCode;
    let charStr = String.fromCharCode(charCode);
    let numcheck = /^[a-zA-Zㄱ-ㅎ가-힣]$/;
    if (numcheck.test(charStr)) {
        evt.preventDefault();
        return false;  
    } else {
        return true;
    }
}

function NumberKey(evt) {
    let charCode = evt.which || evt.keyCode;
    let charStr = String.fromCharCode(charCode);
    let numcheck = /^[0-9]$/;
    if (numcheck.test(charStr)) {
        return true; 
    } else {
        evt.preventDefault();
        return false; 
    }
}

Sorry for writing too long Please help me! I've been holding on to this for days!

6
  • 3
    Why not just use type="number"? Commented Jun 18, 2024 at 7:18
  • 1
    well, just tried it and still get % and IME language printed. it is much less work for sure, but I am hoping to be able to apply it to IDs too Commented Jun 18, 2024 at 7:22
  • Do you want it to run in an old browser? The keypress event is now deprecated. Commented Jun 18, 2024 at 7:52
  • 1
    Sounds like an X/Y problem. What is the actual aim of the code, to stop people from typing text in a number field or are there other concerns? Commented Jun 18, 2024 at 8:23
  • Instead of preventing a user typing which is bad UX, just offer up a warning that the input contains invalid character/disable the submit button (if there is one). Commented Jun 18, 2024 at 9:10

2 Answers 2

0

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<script>
var shifted = false;

function numberCheck(event) {
    if(event.keyCode == 16) {
        shifted = true;
    }

    if(shifted) return false;

    // Any, Backspace, Tab, ArrowLeft, ArrowRight, Delete -> add here other allowed keyCodes
    let keyCodes = [0, 8, 9, 13, 37, 39, 46];

    if(keyCodes.includes(event.keyCode) || (event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >= 96 && event.keyCode <= 105)) {
        return true;
    } else {
        return false;
    }
}

function shiftCheck(event) {
    if(event.keyCode == 16) {
        shifted = false;
    }
}
</script>


<span>Only numbers here: </span> <input type="text" onkeydown="return numberCheck(event)" onkeyup="return shiftCheck(event)"></input>
</body>
</html>

Differences between key actions - look at this explanation: onKeyPress Vs. onKeyUp and onKeyDown.

To prevent shifted number keys (@,#, etc.) you need to keep Shift button state.

Looks like your function NumberKey lacks return true when event.keyCode is allowed.

Sign up to request clarification or add additional context in comments.

4 Comments

didn't work, according to console shift+5 is counted as 53, 37 altogether. 53 is numb 5, 37 is left arrow which I both allowed... shift is not considered as 16 when pressed with another key i guess?
Yeah, I tried with other characters, when pressed together with other key, shift value varies. Thanks for trying though. And yes about returning true, I think it is deleted somehow while I try to copy it here. Wonder why it still worked perfectly same
I added code snippet. Looks like the input field allows only numbers. I believe this is what you wanted here?
Oh my mistake sorry, I left the var shifted=false; inside the function. It perfectly blocks the %! Thank you! Now my only goal is getting rid of IME typing.
-2

I think using regex would help here - although it has lots of its own special syntax to learn/navigate. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test It can detect characters, ranges, allowing them and not allowing them.

Apologies if not applicable or if I'm overlooking something

1 Comment

Thanks for suggestion, just that I forgot to write I also tried regex. Wonder why, but it ended up enabling more letters to type... + does not work for IME languages too

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.