Reputation: 53
I want to only allow letters of the alphabet and numbers to be entered in a form field. I have tried many variations using regex, etc. and I cannot disable the space key or any special character keys.
Here is the latest copy of my code:
document.querySelector('#upperCase').addEventListener('keyup', function(e) {
console.log(this.value);
if (e.which == '32') return false;
this.value = this.value.toUpperCase();
});
#upperCase {
text-transform: uppercase;
}
<form>
<input id="upperCase" maxlength="10" name="upperCase" type="text">
</form>
Is it possible to only allow letters and number to be keyed into an input text box?
Here is my jsfiddle: https://jsfiddle.net/bcjg7osr/29/
Upvotes: 5
Views: 3322
Reputation: 21181
You should use Event.preventDefault()
instead of return false
, as that's specific to jQuery.
You should also use keydown
instead of keyup
, as keyup
fires after the default action, so it's too late to prevent it. keypress
could also be an option.
Also, KeyboardEvent.which
returns a number
, not a string
, so it would be better to do e.which === 32
instead of e.which == '32'
:
document.querySelector('#upperCase').addEventListener('keydown', (e) => {
console.log(e.which);
if (e.which === 32) {
e.preventDefault();
}
});
#upperCase {
text-transform: uppercase;
}
<form>
<input id="upperCase" maxlength="10" name="upperCase" type="text">
</form>
However, just as a side note, note both KeyboardEvent.which
and KeyboardEvent.keyCode
are currently deprecated. They newer options are KeyboardEvent.key
and KeyboardEvent.code
, but browser support is not great yet.
2022 update:
This answer is a bit old. Now you should be perfectly fine using e.key
and e.code
instead of e.keyCode
and e.which
, unless you need to support really old browsers.
You can easily check their values at https://keyjs.dev/.
The updated answer looks like this:
document.querySelector('#upperCase').addEventListener('keydown', function(e) {
console.log(e.code);
if (e.code === 'Space') {
e.preventDefault();
}
});
#upperCase {
text-transform: uppercase;
}
<form>
<input id="upperCase" maxlength="10" name="upperCase" type="text">
</form>
Regarding your question about whether it is possible to use a RegExp, yes, you can use a RegExp.
However, note that you can't use it in the pattern
HTML attribute if you want to prevent any invalid characters from appearing in the input field, as that would only validate its value when the form it belongs to is submitted, as you can see here:
document.getElementById('form').onsubmit = (e) => {
e.preventDefault();
};
<form id="form">
<input pattern = "\w*" type="text">
<button>SUBMIT</button>
<form>
Also, using a RegExp inside the keydown
event listener to validate the input's value won't work as you will get the previous value, the one before the last key stroke:
document.querySelector('#upperCase').addEventListener('keydown', function(e) {
const isInalid = !/^\w*$/.test(this.value);
console.log(`value = "${ this.value }", which is ${ /^\w*$/.test(this.value) ? 'still valid.' : 'now invalid.' }`);
if (isInalid) {
e.preventDefault();
}
});
#upperCase {
text-transform: uppercase;
}
<form>
<input id="upperCase" maxlength="10" name="upperCase" type="text">
</form>
However, you can use a RegExp to validate each pressed key if you use KeyboardEvent.key
:
document.querySelector('#upperCase').addEventListener('keydown', function(e) {
const key = e.key;
const isCharacter = key.length === 1;
console.log(`e.key = ${ key } (${ isCharacter ? 'character' : 'special key' })`);
// We don't want to prevent special keys like backspace or delete:
if (isCharacter && !/\w/.test(e.key)) {
e.preventDefault();
}
});
#upperCase {
text-transform: uppercase;
}
<form>
<input id="upperCase" maxlength="10" name="upperCase" type="text">
</form>
Note you can still do something similar to this using e.which
, but in that case you won't use a RegExp.
What you can do if you need a more advanced behaviour, such as formatting the input's value in a really specific way, is to use the input
event instead.
For example, imagine we want an input field for numeric values with thousands separators. A super basic implementation would look something like this:
document.querySelector('#upperCase').addEventListener('input', function(e) {
const numericValueMatch = this.value.match(/\d+/g);
if (!numericValueMatch) {
this.value = '';
return;
}
const valueAsNumber = parseInt(numericValueMatch.join(''));
console.log(`valueAsNumber = ${ valueAsNumber }`);
// toLocaleString is not the best option, but that's ok for this example:
this.value = valueAsNumber.toLocaleString();
});
<input id="upperCase" maxlength="10" type="text" />
Note this is just a super basic demo. You would need additional logic to keep the cursor's position after each key press and to make this work fine in general. The ideal solution would probably listen to more than a single event.
Upvotes: 2
Reputation: 56783
Added your "only letters and numbers" requirement. I suppose you want to allow Backspace as well. You might find other keys you want to allow (TAB, Arrow Keys...).
let allowedKeys = [..."01234567890abcdefghijklmnopqrstuvwxyz", "backspace"];
document.getElementById('upperCase').addEventListener('keydown', (e) => {
console.log(e.key);
if (!allowedKeys.includes(e.key.toLowerCase())) {
e.preventDefault();
return false;
}
e.target.value = e.target.value.toUpperCase();
});
#upperCase {
text-transform: uppercase;
}
<form>
<input id="upperCase" maxlength="10" name="upperCase" type="text">
</form>
Upvotes: 1
Reputation: 3644
You can do it in your js file:
document.querySelector('#upperCase').addEventListener('keyup',function(e){
if(e.which=='32') this.value='Dont enter space please'
else this.value=this.value.toUpperCase();
});
Upvotes: 0
Reputation: 241
One way you can do it is using the pattern attribute on your input. The only problem with the patter attribute is that it won't disallow spaces until the form is submitted, in which case the submission won't work and the user will be asked to change the input. This will only allow letters and numbers.
<input pattern = "[A-Za-z0-9]" id="upperCase" maxlength="10" name="upperCase"
type="text">
Upvotes: 3