I want to restrict an input text through a regular expression. In the first example I use the attribute onkeyup = "lettersOnly(this)" inside the HTML, as follows:
<form>
<label for="username">Choose a Username:</label>
<input type="text" name="username" id="username" onkeyup="lettersOnly(this)">
</form>
<script>
function lettersOnly(input){
var regex = /[^a-z]/gi;
input.value = input.value.replace(regex, "");
}
</script>
It works but I learnt that this is a bad practice. I found other solution avoiding that, and setting someVariable.onkeyup inside <script> tags. However, my goal is to find another way to get the same result using addEventListener ('keyup', lettersOnly, false). I researched a lot for this specific situation but no answers. Is it possible? I tried the following:
<form>
<label for="username">Choose a Username:</label>
<input type="text" name="username" id="username">
<!--No more “onkeyup” attribute.-->
</form>
<script>
function lettersOnly(input){
var regex = /[^a-z]/gi;
input.value.addEventListener('keyup', lettersOnly(input){
input.value = input.value.replace(regex, "");
}, false)
}
</script>
Doesn‘t work. My intention is to avoid the event handler in the html and use instead, the addEventListener. What is wrong in this last coding? Why doesn‘t work? I‘ll really appreciate your patience.
In the code that you said you have tried; the function lettersOnly() will never be called and addEventListener() will never be called.
You can simply change it as follow -
<script>
function lettersOnly(input){
var regex = /[^a-z]/gi;
input.value = input.value.replace(regex, "");
}
document.getElementById("username").addEventListener("keyup", lettersOnly(this), false);
</script>
Finally, I found myself a solution and I want to share it.
<form>
<label for="username">Choose a Username:</label>
<input type="text" name="username" id="username">
<!--No more “onkeyup” attribute.-->
</form>
<script>
let user = document.getElementById("username");
var regex = /[^a-z]/gi;
user.addEventListener("keyup", ()=>{
user.value = user.value.replace(regex, "");
})
// The “user” variable has been just to simplify a lot of repeated coding, as it is equivalent to “document.getElementById(“username”).
</script>
I don‘t know if this is the best and optimal way to solve my inquire but it works. No “ONkeyup” at all, but using, instead, addEventListener ("keyup", anonymous arrow function). I‘ll really appreciate if anybody has any other suggestion.
The main problem with your second piece of code was that you weren't actually attaching the eventListener to the input element since the outer lettersOnly function was also not called at any time. It appears you resolved this in your own answer, but I'm going to expand upon my comment and suggest using keydown instead.
In the following snippet, I changed the eventListener to attach to keydown instead of keyup. Then we test if the new key (via event.key) matches our regex with .match. If the key pressed is a non-letter character, the match will be non-null, so we want to utilize event.preventDefault() to interrupt the new key from being added to the input value.
Note: this has the added benefit of not needing to use replace or replaceAll to remove the invalid character.
var regex = /[^a-z]/gi;
function lettersOnly(event) {
if (event.key.match(regex) !== null) {
// Since it is an invalid character, we will prevent default
event.preventDefault();
// Log the key to the console for demonstration
console.log(event.key);
// Not needed since we preventDefault()
//event.target.value = event.target.value.replace(regex, "");
}
}
// `username` is equivalent to `document.getElementById("username")
username.addEventListener("keydown", lettersOnly, false);
<form>
<label for="username">Choose a Username:</label>
<input type="text" name="username" id="username">
</form>