How can I prevent numeric inputs using VueJS - javascript

I need to create a validation that prevent the user from inputting numeric inputs on a textbox. I found some solution using a native javascript but it is not working on my side.
On my text box I have this trigger
v-on:keyup="preventNumericInput($event)">
And on my Vue I created a function on my class
preventNumericInput($event) {
console.log($event.keyCode); //will display the keyCode value
console.log($event.key); //will show the key value
var keyCode = ($event.keyCode ? $event.keyCode : $event.which);
if (keyCode > 47 && keyCode < 58) {
$event.preventDefault();
}
}
Can you help me with this?

As mentioned in my comment, keyup will be firing too late to prevent the value being entered into the input field. For example, think about holding a key down to enter the same value repeatedly; there is no key up.
Instead, usekeydown or keypress
<input #keypress="preventNumericInput">
Demo ~ http://jsfiddle.net/wadt08jm/1/

Input must be type number, otherwise isNaN won't work
<input type="number" :value="price" step="0.1" min="0" #input="onInput($event)" >
into input replace ',' by '.'
test if not number
if not number replace observable price by element.value
data () {
return { price: 0 }
},
methods: {
onInput (e: Event) {
const element = e.target as HTMLInputElement
const value = parseFloat(element.value === '' ? '0' : element.value.replace(',', '.'))
if (isNaN(value)) {
element.value = this.price.toString()
} else {
this.price = value
}
}
}

Related

Ensure a positive integer number in input

I have an HTML input element for positive integer numbers. I need to evaluate this input field and ensure that only proper values are inserted.
function exampleFunction(event, element) {
// If event is not backspace and Not a Number
if (event.which != 8) {
//If the event is Not a Number
if (isNaN(String.fromCharCode(event.which))) {
// Cancels the event
event.preventDefault();
}
//If the length reached the limit
else {
var value = document.getElementById(element.id).value;
var maxLength = document.getElementById(element.id).maxLength;
var valueLength = document.getElementById(element.id).value.length;
if (valueLength >= maxLength) {
// Cancels the event
event.preventDefault();
} else {
// Convert the value to a number and back to string. This means leading 0 will be gone.
document.getElementById(element.id).value = Number(value);
}
}
}
};
<input id="exampleInput" type="number" value="0" min="0" step="1" maxlength="5" onkeypress="exampleFunction(event, this)">
purposes:
default value is 0
only numbers shall be accepted
no decimal value .,
no other characters +-e
the input can come from:
typing
copy
backspace and delete can also modify the value
length of input shall also be limited for 5 character length
leading 0 shall be eliminated after a proper new value
Problems:
the default value is 0 and leading zeros are not immediately deleted, only after the second number is typed
with ctrl+v .,+-e characters can be inserted
Question:
Is any better solution for my purposes?
If it is jQuery related, it is also acceptable.
Maybe I am not using the proper event. I tried also to handle the
input event but it is not possible to evaluate the input text.
I am not sure if I make this too complicated, or the solution would be much more complex than I think.
I suggest you to use .addEventListener() instead of the inline event handler.
So to the same input element, you can add more than one event. To do what you wish to do, there are three events implied:
keydown to prevent the not allowed keys
contextmenu for mouse pasting
input to parseInt the value
The below snippet is restricting the input to nubers only. No dot, minus sign, e or whatever except numbers are allowed.
Pasting can be done via [CTRL]+[v] or the mouse contextmenu. In both cases, I assume the previous value of the input should be squarely cleared.
I took the pasted negative numbers case in account using Math.abs().
// Get the element
let myInput = document.querySelector("#exampleInput")
// This event handler only allows numbers, backspace and [ctrl]+[v]
myInput.addEventListener("keydown", function(event) {
console.log("Key:", event.key)
// If this is to be a keyboard paste [CTRL]+[v],
// squarely clears the input value before the paste is done
if (event.ctrlKey && event.key === "v") {
console.log("keyboard paste")
this.value = ""
return;
}
// If the key is not backspace, but is NAN, it is not a number.
// In short, only a number OR a backspace is allowed at this point.
if (event.key !== "Backspace" && isNaN(event.key)) {
event.preventDefault();
console.log(" --------- Event prevented")
}
});
// This handler is for "mouse pastes"
// It squarely clears the input value before the paste is done
myInput.addEventListener("contextmenu", function(event) {
this.value = ""
})
// This handler fixes the value length and parses as a positive integer
myInput.addEventListener("input", function(event) {
console.log("Original value", this.value)
// Get the maxlength attribute value
var maxLength = parseInt(this.maxLength)
// ParseInt the value (will remove any leading zero) and ensure it is positive
// Then keep just the [maxlength] first characters.
var value = Math.abs(parseInt(this.value)).toString().slice(0, maxLength)
console.log("Fixed value", value)
this.value = value;
});
<input id="exampleInput" type="number" value="0" min="0" step="1" maxlength="5">
Here we go with a JQuery solution
Features:
Remove default "0" on focus.
Set maximum length to (5)
Allowed numeric content only and Backspace, Del, Home, End, Arrow-Left, Arrow-Right,
ctrl+v, ctrl+c, ctrl+a buttons.
Check if the copied text contains any numeric value and collect it and remove non-numeric values.
Check if pasted text length + current value length are meeting maximum length
$(document).ready(function() {
//Remove default "0" ONLY! when focus at the input.
$("#exampleInput").on('focus', function() {
var oldval = $("#exampleInput").val();
if (oldval < 1) {
$("#exampleInput").val("");
}
});
/* SET CTRL+V , CTRL+C funciton */
var ctrlprs = false,
ctrlk = 17,
mccmd = 91,
vk = 86,
ak = 65,
ck = 67;
$(document).keydown(function(e) {
if (e.keyCode == ctrlk || e.keyCode == mccmd) ctrlprs = true;
}).keyup(function(e) {
if (e.keyCode == ctrlk || e.keyCode == mccmd) ctrlprs = false;
});
//Listen to the input in keydown
$("#exampleInput").on('keydown', function(e) {
var txt = $("#exampleInput").val();
//exceptions for [b-space,end,home,left,right,del]
var keys = [8, 35, 36, 37, 39, 46];
var rgx = $.inArray(e.which, keys) < 0;
var cnvrt = String.fromCharCode(e.which);
/* allow CTRL + "a or c or v" */
if (ctrlprs && ((e.keyCode == ck) || (e.keyCode == ak) || (e.keyCode == vk))) {
} else if ((txt.length == 5) || (cnvrt.match(/[^0-9]/)) || (e.shiftKey)) {
if ((rgx)) {
e.preventDefault();
/* prevent all text except numbers, and set max input value length to (5) */
}
}
});
/*Bind a paste function to check if clipboard data met with requirements or not.*/
$("#exampleInput").on('paste', function(e) {
var oldl = $("#exampleInput").val();
var oldval = e.originalEvent.clipboardData.getData('text');
if (oldval.match(/[0-9]{1,5}$\d/g)) {} else {
//remove all non-numeric text from clipboard text.
var newvar = oldval.replace(/\D/g, "");
setTimeout(function() {
//check if ( clipboard[Numeric only] + input value ) length equals or less than (5).
var totlen = oldl.length + newvar.length;
if (newvar.length > 0 && totlen <= 5) {
$("#exampleInput").val(oldl + newvar);
} else {
//if total length is more than (5) keep the input value before paste.
console.log("total length is : " totlen);
$("#exampleInput").val(oldl);
}
}, 1);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="exampleInput" type="number" value="0" min="0" step="1" maxlength="5">

How can I prevent other characters from being inputted on an input except numbers using Javascript

I am using Vue.JS (Bootstrap-Vue) to build a form, my input has the following code:
<b-form-input
v-mask="'####'"
number
type="number"
no-wheel
pattern="[0-9]"
step="1"
:class="{ 'hasError': $v.form.dobYear.$error }"
v-model.number="$v.form.dobYear.$model"
class="form-input"
name="year"
id="year"
maxlength="4"
min="1900"
max="2020"
#keydown="filterKey"
></b-form-input>
When a user presses down I want to prevent more than 4 characters to be entered, this works, but when testing, I can see period and dashes and other similar characters can also be added into the input and ignores the maximum of 4 characters. How can I update the following code to ensure nothing but numbers can be added to my input on mobile. I'm trying to detect if any of those unwanted keys are pressed then prevent the default action. (I've tested on Android Chrome)
filterKey(e) {
const value = e.target.value;
const key = e.key;
console.log(value, this.amount);
if (String(value).length === 4) {
//check if a number is pressed after 4 have been entered
if (!isNaN(Number(key))) {
e.preventDefault();
return;
} else if (key == 190 || key == 189 || key == 107 || key == 69) {
e.preventDefault();
return;
}
}
}
The following snippet will not allow anything to be entered into the input element if the length of the input's value is already 4, or if a non-numeric character is typed (but will allow 'Backspace' and 'Delete' keys):
EDIT : Implemented Hiws' suggestion to let the user type in numbers even if the length is 4, if some text is selected in the input element
function filterKey(e) {
let previousValue = e.target.value;
let key = e.keyCode || e.charCode;
if (key != 8 && key != 46) { // Ignore backspace and delete
if (
// preventDefault if length of input is 4 and no text is selected in the input
( String(e.target.value).length >= 4 && e.target.selectionStart === e.target.selectionEnd ) ||
// preventDefault if entered a space or non-number
!e.key.trim() || isNaN(e.key)
) {
// Prevent input if input length crosses 4,
// or if input is not a number
e.preventDefault();
// Include below line only if you have no other event listeners on the element, or its parents
e.stopImmediatePropagation();
return;
}
}
}
You block keys other than numbers only if number value already equals to 4. Try changing your blocking logic to:
if (String(value).length > 4 || !isNaN(Number(key)) || unwanted keyCodes) {
e.preventDefault();
return;
You can use a regex to test against the value of the input field and avoid messing with keyCodes.
if ( !/^[0-9]{0,4}$/.test(String(value)) ) {
e.preventDefault();
return;
}

Real time input text filtration which allows only numbers

Hello I'm trying to make real time input type="text" filter which allows only numbers and dot, using javascript.
I wrote
Javascript:
<script>
function thirdTaskFunction(evnt) {
evnt = evnt || window.event;
var charCode = evnt.which ? evnt.which : evnt.keyCode;
return /\d/.test(String.fromCharCode(charCode));
}
function thirdTaskFunction(evt) {
var charCode = (evt.which) ? evt.which : evt.keyCode;
if(charCode > 31 && (charCode < 48 || charCode > 57)) {
return false;
}
return true;
}
function thirdTaskFunction() {
var thirdInput = document.getElementById("thirdTaskInputText");
thirdInput = thirdInput.onchange = thirdTaskFuncion;
var valid = /^\-?\d+\.\d*$|^\-?[\d]*$/;
var number = /\-\d+\.\d*|\-[\d]*|[\d]+\.[\d]*|[\d]+/;
if(!valid.test(this.value)) {
var compare = this.value.match(number);
this.value = compare ? compare[0] : '';
}
}
</script>
HTML:
<div id="thirdTaskDIV">
<input id="thirdTaskInputText" type="text" placeholder="Type a number" autofocus onkeypressed="return thirdTaskFunction(event);">
</div>
I was trying many ways, every thirdTaskFunction() method wasn't work, I was tested solution on w3schools so maybe this is reason? But I think that I dont remember about something that make it works. And I know is very similar to "HTML text input allow only numeric input" but it didnt works.. So I hope somebody show me whats pappyn here.
One way to allow only numbers in an input field is using a keypress event listener. So you'll want to select the input field and give it an event listener, like this:
const inputField = document.querySelector("/*input field id here*/");
inputField.addEventListener("keypress", function(e){
if(e.keyCode > 48 && e.keyCode < 57){
e.preventDefault();
}
}
This function checks if the key that's pressed matches a number key, and if it doesn't, prevents the default action which in this case is printing the character to the input field.
If you have any questions, I'll do my best to answer them!
P.S. The keyCode numbers used are estimates based on memory, to get the key codes simply do a quick search on google for "ASCII key codes".
The event code (NOT keyCode since the keyCode property is deprecated) for the dot is Period and the event code for the numbers 0 to 9 comes in the form Digit0, Digit1 and so on.
Just use the keydown event listener to retrieve the event code and then use the includes() method to check if the current key has a code that includes "Digit" or "Period" and restrict input of that character if it doesn't include either of those two by using preventDefault() like this:
const input = document.getElementById('thirdTaskInputText');
function checkKey(e) {
if(e.code.includes("Digit") || e.code.includes("Period")) {
console.log("valid input");
} else {
e.preventDefault();
console.log("not a number!");
}
}
input.addEventListener('keydown', checkKey)
<input id="thirdTaskInputText" type="text" placeholder="Type a number">
Without the console logs, you can further simplify the above code to a single if statement using the bang operator ! like this:
const input = document.getElementById('thirdTaskInputText');
function checkKey(e) {
if(!(e.code.includes("Digit") || e.code.includes("Period"))) e.preventDefault();
}
input.addEventListener('keydown', checkKey)
<input id="thirdTaskInputText" type="text" placeholder="Type a number">

Keyup prevent default not working angular6

I want to stop entering any number after validating a custom regular expression , the issue is condition got true but event.preventDefault is not preventing the input , The reg ex is to input value in percentage between 1-100 with decimals
/^(100(\.0{1,2})?|[1-9]?\d(\.\d{1,2})?)$/
this is my input
<input type='text' (keyup)="preventPercentage($event)" [(ngModel)]="value">
ts
preventPercentage(event){
var p = event.target.value
var s= p.match(/^(100(\.0{1,2})?|[1-9]?\d(\.\d{1,2})?)$/) != null
if(!s && p){
event.preventDefault();
}
}
user can still enter any value even the condition is true
input anything between 100 above it still working and event is not preventing values
<input type='text' (keydown)="preventPercentage($event)" [(ngModel)]="value">
I used key down but it allows to enter 123 i.e three digit numbers
and I cannot then remove that number using backspace what exactly I am doing wrong can anyone suggest a sol any help will be appreciated
Try this. I think there is a change required in the regex as per your requirement.
preventPercentage(event){
var p = event.target.value + event.key;
var s = p.match(/^(100(\.0{1,2})?|[1-9]?\d(\.\d{1,2})?)$/) != null;
if (!s && event.keyCode !== 8) {
event.stopPropagation();
return false;
}
}
Use this with keydown:
<input type='text' (keydown)="preventPercentage($event)" [(ngModel)]="value">
preventPercentage(event: any) {
function stopProgram() {
event.stopPropagation();
return false;
}
if (event.keyCode === 8) {
return true;
}
var p = event.target.value;
if ((event.keyCode === 190 && p.indexOf('.') > -1) || p === '100') {
return stopProgram();
}
p = p + event.key;
var s = p.match(/^(100(\.0{1,2})?|[1-9]?\d(\.\d{1,2})?)$/) != null;
if (!s && event.keyCode !== 190) {
return stopProgram();
}
}
This is because it's necessary to use keydown event, not keyup.
It considers that the keyboard action is already done and you cannot cancel it.

changing character code with js and show the new character instead

I want to write a code that if a user press a key, It changes the keyCode or charCode of the User event and trigger the event with a new charcode,
I wrote this code in jsfiddle but this code doesn't work because of too much recursion.
function convert(e, elem) {
function getKey(event) {
if (event.which == null) {
return event.keyCode // IE
} else if (event.which != 0 && event.charCode != 0) {
return event.which // the rest
} else {
return null // special key
}
}
var key = getKey(e);
key++;
return key;
}
$(".myInput").keypress(function (e) {
var returnedKey = convert(e, this);
e.which = e.keyCode = returnedKey;
$(this).trigger(e);
});
<input type="text" class="myInput" />
any Idea that help my code work would be appreciated.
Thanks alot.
Regarding the recursion issue, you need to add a stopping condition, for example:
$(".myInput").keypress(function (e) {
var returnedKey = convert(e, this);
e.which = e.keyCode = returnedKey;
if(!e.isSecondTrigger){
e.isSecondTrigger = true;
$(this).trigger(e);
}});
This way, you only change the value once. However, as was stated by LShetty in the comments section, the event values are read only - you can't change the value of the button that was already pressed and in that way change the input text. In order to do this, you need to manually change the value of the input text after each user action (i.e. hold the value of the input text at each key press, modify it when the user presses a key, and then overwrite the input field value with the output).

Categories