jQuery - How to restrict input values for text box - javascript

I want to restrict input in TextBox to be either 'Y' or 'N' (any case).
How can this be done in jQuery.

I'm pretty sure that if keydown returns false, then the input is not allowed. You can do this by grabbing the key code from the event object. This doesn't prevent doing things like copy/pasting a value into the text box, though. So a better option would be a select or radio button if you want to restrict the user's input.
$("#some-selector").bind("keydown", function (e) {
return e.keyCode == 89 || e.keyCode == 78
});

As you said this does not take care of the case of copy/paste a better alternative would be to attach a change event handler and then check if its an allowed char else flag an error
$("some-selector").change( function () {
var textBoxVal=$(this).val();
if(textBoxVal!=='y' || textBoxVal!=='n')
alert("Error");
});
Note:alerts jsut an example- add a different style to the textbox or however u r handling error on ur page.

Related

How to tell if an element accepts keyboard input?

I'm working on keyboard shortcuts for a web application and need to check if a keypress should trigger the shortcut or if it is just the user typing and should therefore not trigger the shortcut.
For example, a common pattern is to use the / or s keys to open the global search bar. Obviously this should not open the search bar if the user is typing into another input.
The ideal logic would go something like this: On keypress, check the currently focused element. If the element accepts keyboard input (can be typed into), then do nothing. If the element does not accept keyboard input, run the shortcut.
Note that checking for focusability is not enough because links and buttons are focusable, but do not accept keyboard input (in the way I mean here).
Here's what I have so far:
function acceptsKeyboardInput(element) {
return (
element.tagName === "INPUT" ||
element.tagName === "TEXTAREA" ||
element.isContentEditable
);
}
Does this approach catch every case or is there a better way to tell if an HTML element accepts keyboard input?
Will all shortcuts be more than one key? If so you can listen for input and prevent a shortcut from running with a boolean value.
var is_input = false
window.addEventListener('keydown', function (e) {
console.log(is_input)
is_input = false
})
window.addEventListener('input', function (e) {
is_input = e.constructor.name == 'InputEvent'
})
Expected output for /s while able to type would be true or false (depending on the previous is_input value) at / keypress then true at s keypress and all keys following.
Expected output for /s while not able to type would be true or false (depending on the previous is_input value) at / keypress then false at s keypress and all keys following
From what I've seen, the suggestion given in the question seems to be the best approach—with some adjustments.
The first improvement is to blacklist a set of input types that don't accept keyboard input (e.g. checkbox or radio). I find it easier and better to use a blacklist rather than a whitelist for two reasons. The first is future-proofing against newly supported input types and in case you miss one. Second and more importantly, an invalid input type defaults back to type text, which means there are an infinite number of input types that accept keyboard input.
The second change is to also include <select> elements since they can be typed into as a sort of search/quick-select functionality.
Here's the full function:
const nonTypingInputTypes = new Set([
"checkbox",
"radio",
"button",
"reset",
"submit",
"file",
]);
export function acceptsKeyboardInput(element) {
return (
(element.tagName === "INPUT" && !nonTypingInputTypes.has(element.type)) ||
element.tagName === "TEXTAREA" ||
element.tagName === "SELECT" ||
element.isContentEditable
);
}
There are a few other inputs that don't accept keyboard input but that are less widely supported by browsers (e.g. color), so I've tried to keep it to the more commonly used and widely implemented input types.

Allow use special commands on input validating

I have a little problem with validating an input field.
Here is my validation code:
_validateInput: function(e) {
var value = e.currentTarget.value;
var key = e.which || e.keyCode;
var re = /[^0-9\.]/gi;
if (re.test(value + String.fromCharCode(key))) {
return value;
} else {
return value + String.fromCharCode(key);
}
},
The logic is the next. If user input non-digital characters, the function return current value of the input, without the last symbol.
If user type digit or dot, function return current input value + entered number.
What is my problem:
1) It not allows user to enter dot.
2) String.fromCharCode for dot character returns "¾" symbol.
3) Special symbols like backspace, tab, etc... doesn`t work.
4) Commands like Ctrl+V, Ctrl+A also does not work
Could someone help me to solve this problems? What is wrong with my RegEx?
Thanks!
P.S. Function fired on the keydown event
Unless you need to support older browsers listen for oninput instead of onkeydown and a lot of the processing will have been done for you.
http://www.w3schools.com/jsref/event_oninput.asp
This event is similar to the onchange event. The difference is that the oninput event occurs immediately after the value of an element has changed, while onchange occurs when the element loses focus, after the content has been changed. The other difference is that the onchange event also works on <keygen> and <select> elements.
Whenever oninput is triggered then check the value in the text area is valid and if it isn't then correct it. This will also let you check for multiple dots being entered (if you need to do that). For example 231.21.23 is not a valid number.

Input value onkeydown returns incorrect value (one less)

I'm working on a script for our client's project that autotabs you onto the next input field when you've hit the maximum character count for a particular input. For some reason the input value is returning one less than it should be, and therefore tabs to the 'next' input when an extra character is entered above the 'threshold'.
Here's my script to watch the inputs value - ofc, if there is a better way please advise :) -
var watchLength = function (watch) {
watch.onkeypress = function () {
var nextInput = getNextSibling(this);
console.log(this.getAttribute('data-autotab-length'));
console.log(this.value.length);
if (this.value.length == this.getAttribute('data-autotab-length')) {
nextInput.focus();
console.log('Limit reached here');
}
};
};
And a jsFiddle to the working input. The first input is limited to '2' characters, but when you type in 3 it jumps to the next input. I think this is something to do with the keypress/keydown event not reading the initial value, but I'm at a loss of how to fix it. Any help really appreciated.
I'm logging the results in the Console:
http://jsfiddle.net/qdnCZ/
The Problem is, that onkeypress will fire before you want it to. You can simply replace onkeypress by onkeyup, that way you make sure that the <input> elements value is set correctly the time you check it.
See: http://jsfiddle.net/qdnCZ/1/
Yes it will return one less, simply use +1 on the length check. This is beacuse onkeypress event is executed before the field is updated, which means using e.preventDefault() the letter will not appear in the field. You could use onkeyup otherwise.
Use onkeyup instead onkeypress
onkeyup gets fired after field gets updated
if (this.value.length == this.getAttribute('data-autotab-length')) {
nextInput.focus();
console.log('Limit reached here');
return false; // this is prevent the third value being entered
}
Updated fiddle

javascript (jquery) numeric input: keyCode for '3' and '#' are the same

I need to set up an <input type="text" /> so that it will accept only numeric chars, backspace, delete, enter, tabs and arrows.
There's a lot of exemple around there, i started with something similar to this:
function isNumericKeyCode (keyCode){
return ( (keyCode >= 48 && keyCode <= 57) //standard keyboard
||(keyCode >= 96 && keyCode <= 105)) //Numpad
}
$('#myTextBox').keydown(function(e){
var handled = true;
var keyCode = e.keyCode;
switch(keyCode){
//Enter and arrows
case 13:
case 37:
case 38:
case 39:
case 40:
doSomethingSpecialsWithThesesKeys();
break;
default:
handled = false;
break;
}
if ( !handled
&& keyCode !== 8 //backspace
&& keyCode !== 9 //tab
&& keyCode !== 46 //del
&& !isNumericKeyCode(keyCode)){
handled = true;
}
return handled;
});
All that worked perfectly until I hit the "#" key. In my french canadian keyboard, the "#" has his own key (no shift implied) that returns keyCode 51, the same as the number "3".
I think that in US keyboard, the "#" is obtained by pressing shift+3, that may be why they have the same keycode.
Now I realize that I have to handle the shift and alt keys too, but that's another story.
It works differently with the jquery keypress event, which offer the charCode property, but I did not used it at first because of what the documentation says :
as the keypress event isn't covered by any official specification, the
actual behavior encountered when using it may differ across browsers,
browser versions, and platforms.
Also, I would need a workaround in that case to handle tabs, arrows and other special keys since they don't provide a charCode.
So the question is :
is there a way to allow only some specifics chars using the keydown event? And that, in a way that will work independently of the keyboard layout?
As a side quest : Which browsers may be problematics with the keypress event? I mean, currently I don't really care if my website does not support IE6. I am targetting recent browsers.
Edit
As someone pointed out in the comments, this method does not allow user to "ctrl+v" a number in the input. In my particular case this is really not a requirement to be able to paste a number. But this popped something in my head, the user still can right-clic > copy some text in the input, and in that case that could be anything. The more I think of it, the more it seems to me that I will need the keydown event to handle tabs and arrows, and another event to handle the input itself.
Edit2
A lot of beautiful answers here, but the award goes to mrtsherman for the use of input and propertychange events. I will use a combination of this answer for the numeric validation, plus the keyCode event as before for the special use of arrows, tabs and enter keys.
How about something like this. This should cover cut/paste and also rmb content. We monitor the textbox for any change in content. Then we use a regex to filter out characters based on a whitelist. This won't handle non-character key, but I think that is okay.
The \d flag says that only digits should be accepted.
http://jsfiddle.net/UXeva/1
$('#myTextBox').bind('input propertychange', function() {
var text = $(this).val();
if (isNaN(text)) {
$(this).val(text.replace(/[^\d]/gi, ''));
}
});
We bind to two events here. input for FireFox and propertychange for other browsers.
If older browsers are'nt an issue, the number input type should cover this.
<input type="number" />
If not you could use the isNaN javascript function
$("#number1").on('keyup', function() {
var myval = $(this).val();
if (isNaN(myval)) {
alert('numbers only!');
}
});
Personally I would do some regex filtering with a check to see if the value has changed, that will allow any character that does not change the value, like tabs, enter and arrows. With a regex you could also add or remove any character, or you could use \d for digits only or as below, [0-9]. Up to you really what your exact needs are?
var P;
$("#number2").on('keyup', function() {
var V = $(this).val();
if (V != P) {
$(this).val(V.replace(/[^0-9]/g,''));
}
P=V;
});
They could also be combined to something like this:
$("#number3").on('keyup', function() {
var V = $(this).val();
if (isNaN(V)) {
$(this).val(V.replace(/[^0-9]/g,''));
}
});
Here's a FIDDLE to test them out!
Why not do something like this? It uses a combination of the keyup() event and isNaN(). It'll work whether the user types with the keyboard or pastes a number.
The way it works is, as soon as the text changes, it will check if the value is a number. If not, it will trim the input until it is a number. So, if you enter 25s or 25ss, you will be left with 25.
This will work with ctrl+v paste as well. It won't work with right-click paste and for that reason, I have disabled right-clicking only on the textbox.
Live Demo
The Jquery
$(document).ready(function(){
$('#number').keyup(function(){
var input = this.value;
while (isNaN(input))
{
input = input.substring(0,input.length-1);
$('#number').val(input);
}
});
$('#number').bind("contextmenu",function(e){
return false;
});
});
jQuery also provides a shiftkey boolean on the event object:
$('#myTextBox').keydown(function(e){
if(e.keyCode === 51 && !e.shiftKey){
// '3' key pressed while shift was **not** held down (not '#')
}
});
EDIT I reread your question and changed the code above for !shiftkey

How to change characters typed in Firefox

I need to change in a text input the character '.' to ',' while typing.
In IE I change the keyCode event property in the keypress event, like this
document.getElementById('mytext').onkeypress =
function (evt) {
var e = evt || window.event;
if (e.keyCode && e.keyCode==46)
e.keyCode = 44;
else if (e.which && e.which==46) {
e.which = 44;
}
};
but it seemes that in Firefox it's impossible to change characters typed in key events.
Any suggestions?
Try this. It works on all browsers:
window.onload = function () {
var input = document.getElementById("mytext");
input.onkeypress = function () {
var evt = arguments[0] || event;
var char = String.fromCharCode(evt.which || evt.keyCode);
// Is it a period?
if (char == ".") {
// Replace it with a comma
input.value += ",";
// Cancel the original event
evt.cancelBubble = true;
return false;
}
}
};
Update: Pier Luigi pointed out a problem with the above. It doesn't take care of the caret position not being at the end of the text. It will append the command to the end even if you're inserting some text to the value.
The solution would be, instead of appending a comma, to simulate a keypress event for the comma key. Unfortunately the way dispatching of synthetic events work in different browsers seems to show a lot of variety and isn't an easy feat. I'll see if I can find a nice and generic method for it.
Assume that all properties in an Event object are immutable. The DOM spec doesn't address what happens when you change those values manually.
Here's the logic you need: listen for all key events. If it's a period, suppress the event, and manually add the comma at the cursor position. (Here's a code snippet for inserting arbitrary text at the cursor position.)
You'd suppress the event in Firefox by calling event.preventDefault(); this tells the browser not to go ahead with the default action associated with this event (in this case, typing the character). You'd suppress the event in IE by setting event.returnValue to false.
If it's not a period, return early from your handler.
Technically you just want to replace all dots with commas.
document.getElementById('mytext').onkeyup = function(){
this.value = this.value.replace('.', ',');
}
If I look at the official Document Object Model Events document, mouse events fields are defined as read-only. Keyboard events are not defined there, I suppose Mozilla followed this policy for them.
So basically, unless there is some smart trick, you cannot alter an event the way you want. You probably have to intercept the key and insert the char (raw or translated) where the caret is, the way JS HTML editors do.
Does this really need to be done on the fly? If you are collecting the information to be posted to a form or submitted to a database, would it not be better to modify the data once it was submitted? That way the user never sees the confusing change.
This is possible now by intercepting and cancelling the default keydown event and using HTMLInputElement.setRangeText to insert your desired character. This would look something like this:
document.addEventListener('keydown', $event => {
if($event.code === 'Period'){
$event.preventDefault();
let inputEl = document.querySelector("#my-input");
inputEl.setRangeText(
',',
inputEl.selectionStart,
inputEl.selectionEnd,
"end"
);
}
})
setRangeText will insert text at the cursor position in a given input. The "end" string as the last argument sets the cursor to the end of the inserted content.
More info here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setRangeText

Categories