HTML User Input Type Restriction - javascript

Restriction:
Can't type negative numbers, Decimal Numbers, Numbers < 2 and Numbers > 99
So far I have:
<input required type="number" min="2" max="99" oninput="this.value = Math.abs(this.value)" maxLength="2" matInput value="{{element[col]}}" [(ngModel)]="element[col]">
It restricts the user from typing negative numbers only.
I can validate with function but I need to restrict the typing.
Kindly, share a few thoughts as I'm programming front-end for the very first time.

I think the solution you're looking for is this:
<input required type="number" min="2" max="99" oninput="validity.valid||(value='');" maxLength="2" matInput value="{{element[col]}}" [(ngModel)]="element[col]">
But I guess it will lose the previous input. For that, you'll need to maintain a state variable in your component and restore the earlier value.

You can checkout below code;
HTML part:
<input required id="id2" type="number" min="2" max="99" oninput="someFunction(this)">
Javascript part:
let b = "";
function someFunction(a) {
if (inpObj.checkValidity()) {
a.value = a.value;
b = a.value
} else if (!a.value) {
a.value = ""
} else {
a.value = b;
}
}
You can modify this according to your need.

Related

JavaScript /TypeScript Match RegEx on Input Field (Prevent Input Starting with 0)

I am trying to write a RegEx for an input field in Angular / TypeScript that prevents the user from typing anything other than a 1-3 digit number not starting with 0. Restricting the input to only digits is easy, but I am not able to figure out how to restrict an input starting with 0. Everything I try seems to break the RegEx check.
<input matInput
[(ngModel)]="backupIntervalLength"
(ngModelChange)="onIntervalLengthChange($event)"
maxLength="3"
onkeypress="return String.fromCharCode(event.charCode).match(/[^0-9]/g) === null"
>
I'm not familiar with Angular but here is a JS solution, since you didn't tag your question with Angular I assume you can translate it into Angular code.
const input = document.getElementById("input");
input.addEventListener("input", e => {
const { value } = e.currentTarget;
if (!/^[1-9]\d{0,2}$/.test(value)) {
e.currentTarget.value = value.slice(0, -1);
}
});
<input id="input" type="number" />
Turns out it wasn't all that complicated. I just had to think in invert :)
<input matInput
[(ngModel)]="backupIntervalLength"
(ngModelChange)="onIntervalLengthChange($event)"
maxLength="3"
onkeypress="return String.fromCharCode(event.charCode).match(/[^1-9]?[^0-9]?[^0-9]/g) === null"
>

Jquery does not count correctly?

I want to book a ticket with a free offer, these are the rules:
One person can buy 1 or more tickets, but limited to 4
He can make a minumum offer of 1 euro, but no limit, for tickets. So if he buys 4 tickets the offer will be at least 4 euros.
The check (validate()) happens after page loading and on every change or keyup event. All seems ok when I increase tickets to buy from 1 to 2, the offer increase from 1 to 2, as expected.
My issue:
When I leave "ticket" (first input) on 2 and I increase the offer, it does not exceed 9, at 10 it set the input value back to same value that is in the ticket input.
Also, if I hold arrow up to increase number until 50, for example, it's ok.
What's wrong?
My code is:
validate();
$('.input_data').on('change keyup', validate);
function validate() {
control_tick = $("input[name='ticket']").val();
if ((control_tick < 1) || (control_tick > 4)) {
control_tick = 1;
$("input[name='ticket']").val(control_tick);
} else {
$("input[name='ticket']").val(control_tick);
}
control_off = $("input[name='offer']").val();
if (control_tick > control_off) {
control_off = control_tick;
$("input[name='offer']").val(control_off);
console.log('prezzo minore di ticket');
}
if (control_off => control_tick) {
$("input[name='offer']").val(control_off);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label>Ticket number (max 4):</label><br>
<input class="w3-input w3-center input_data" type="number" name="ticket" value="1" min="1" max="4" step="1">
<label>Offer €:</label>
<input class="w3-input w3-center input_data" type="number" name="offer" value="1" min="1" max="1000" step="1">
Cause
When you get the value of a field using .val(), that value is always of type string. Therefore when you compare the values using if (control_tick > control_off) {, you're comparing two strings, not two numbers. And in the rules of string comparison, "2" is considered to be "greater" than "10", because it compares each character one at a time, rather than the whole string, and clearly it regards "2" as greater than "1".
(Regarding holding the up arrow to 50, this will be ok because "50" (or rather, "5" is greater then "2" in string comparisons, just as it is in numeric comparisons. But if you hold it all the way to 100 it'll reset again - I'm sure you can work out why, by now.)
Solution
You need to parse your values as numbers before you attempt to compare them. Since these will always be whole numbers, we can use parseInt. This will ensure it does a numeric comparison instead.
See the demo below for a working example.
(Note also that removed the last if statement - apart from the slight syntax error (=> should be >=, although it doesn't cause a syntax error because it's valid, (but useless) as an arrow expression) it seemed redundant, because you're just populating the field with the same value you got from it a moment earlier. The else after the first if is also redundant for the same reason.)
validate();
$('.input_data').on('change keyup', validate);
function validate() {
control_tick = parseInt($("input[name='ticket']").val());
if ((control_tick < 1) || (control_tick > 4)) {
control_tick = 1;
$("input[name='ticket']").val(control_tick);
}
control_off = parseInt($("input[name='offer']").val());
if (control_tick > control_off) {
control_off = control_tick;
$("input[name='offer']").val(control_off);
console.log('prezzo minore di ticket');
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label>Ticket number (max 4):</label><br>
<input class="w3-input w3-center input_data" type="number" name="ticket" value="1" min="1" max="4" step="1">
<label>Offer €:</label>
<input class="w3-input w3-center input_data" type="number" name="offer" value="1" min="1" max="1000" step="1">

Cannot validate dot for input type number

I am trying to add validation for input type number to accept only integer.
I added pattern="\d*" to the element. It works fine for input 10.12, 10.13. But fails for input 10.
I printed the value for the html input. It is 10 instead of 10..
<script>
function getValue(){
alert(document.getElementById("numberInput").value);
}
</script>
<input type="number" id="numberInput"> </input>
<button onclick="getValue();">
Ideally it should consider 10. as invalid input.
Pasting is indeed tricky. I came up with the following:
function setValid(target) {
const val = target.value;
// Remove value, as setting the same value has no effect.
target.value = '';
// Reset value on the next tick
requestAnimationFrame(() => target.value = val);
}
<form action="#" method="post">
Numbers: <input name="num"
type="number"
min="1"
step="1"
onblur="setValid(this)"
onpaste="requestAnimationFrame( () => setValid(this) )"
onkeypress="return event.charCode >= 48 && event.charCode <= 57"
title="Numbers only">
<input type="submit">
</form>
What this does is the following:
When the input loses focus, it resets the value
When pasting, it waits until the value is set, and then resets it.
There are probably even better solutions out there.
This answer is based on kneeki's answer here.

Converting form number field value structure

in a webpage, I asked users to input a field named "budget". I tried using the script below to create thousands separator for the entered number:
window.onload = function() {
document.getElementById("project-budget").onblur = function() {
this.value = parseFloat(this.value.replace(/,/g, ""))
.toFixed(0)
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
document.getElementById("display").value = this.value.replace(/,/g, "")
}
}
<input id="project-budget" step="5" required type="text" pattern="[0-9]*" class="test input-item text-field is_number numberVal" name="et_budget" min="1">
it changes the value perfectly but the problem is that making the field value as text cause cms to not understand value in this field. so I need to change the value back to simple numbers in a hidden field and use that hidden field to insert value to database.
how can I change the value back?
for example user enters 1000000 and the script changes it to 1,000,000. I want to print 1000000 in a hidden field.
This might help.
function parseBudget(element) {
const value = parseFloat(element.value.replace(/,/g, ''));
console.log(value);
element.value = value.toFixed(0)
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
document.querySelector("#forCms").value = value;
}
<input id="project-budget" step="5" required type="text" pattern="[0-9]*" onblur="parseBudget(this)" class="test input-item text-field is_number numberVal" name="et_budget" min="1">
<input type="number" id="forCms">

Input type number maxlength 5

I want to limit the input type number to maximum 5 numbers, I am using below code, which is working well, only issue is that for backspace I have to use event.keycode which I dont want to use. Is there any alternative apart from usking keycode of backspace.
var input = document.getElementById('input');
input.addEventListener('keypress',showData,false)
function showData(event)
{
if(event.target.value.length<=5)
{
return true;
}
else
{
event.preventDefault();
}
}
If you want it so if the user tries to type more than 5 numbers it only keeps the 5 numbers:
input.oninput = function() {
if (this.value.length > 5) {
this.value = this.value.slice(0,5);
}
}
Why don't you just use:
<input type="number" max="99999">
This will still not stop a user from manually entering a value larger than 99999, but the input element will be invalid.
<input type="number" max="99999" />
How can I limit possible inputs in a HTML5 "number" element?
<form>
<input required type="text" name="inputname" pattern="[0-9]{5,}">
<input type="submit" value="submit">
</form>

Categories