Jquery does not count correctly? - javascript

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">

Related

HTML User Input Type Restriction

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.

How to only allow whole numbers in input [duplicate]

I'm using the jQuery Tools Validator which implements HTML5 validations through jQuery.
It's been working great so far except for one thing. In the HTML5 specification, the input type "number" can have both integers and floating-point numbers.
This seems incredibly short-sighted since it will only be a useful validator when your database fields are signed floating-point numbers (for unsigned ints you'll have to fall back to pattern validation and thus lose extra features like the up and down arrows for browsers that support it).
Is there another input type or perhaps an attribute that would restrict the input to just unsigned integers?
I couldn't find any.
Setting the step to 1 is not the answer since it doesn't restrict the input. You can still type a negative floating-point number into the textbox.
Also, I am aware of pattern validation (I mentioned it in my original post), but that was not part of the question.
I wanted to know if HTML5 allowed restricting an input of type "number" to positive integer values. To this question the answer, it seems, would be "no, it does not".
I didn't want to use pattern validation because this causes some drawbacks when using jQuery Tools validation, but it now seems that the specification doesn't allow for a cleaner way to do this.
The best you can achieve with HTML only (documentation):
<input type="number" min="0" step="1"/>
Set the step attribute to 1:
<input type="number" step="1" />
This seems a bit buggy in Chrome right now so it might not be the best solution at the moment.
A better solution is to use the pattern attribute, that uses a regular expression to match the input:
<input type="text" pattern="\d*" />
\d is the regular expression for a number, * means that it accepts more than one of them.
<input type="text" name="PhoneNumber" pattern="[0-9]{10}" title="Phone number">
Using this code, the input to the text field limits to enter only digits. Pattern is the new attribute available in HTML 5.
Pattern attribute doc
The easy way using JavaScript:
<input type="text" oninput="this.value = this.value.replace(/[^0-9.]/g, ''); this.value = this.value.replace(/(\..*)\./g, '$1');" >
Pattern is nice but if you want to restrict the input to numbers only with type="text", you can use oninput and a regex as below:
<input type="text" oninput="this.value=this.value.replace(/[^0-9]/g,'');" id="myId"/>
I warks for me :)
<input type="number" oninput="this.value = Math.round(this.value);"/>
This is not only for HTML5. This works fine in all browsers. Try this:
document.getElementById("input").addEventListener("keyup", function() {
this.value = this.value.replace(/[^0-9]/g, "");
});
<input id="input" type="text">
Pattern are always preferable for restriction, try oninput and min occur 1 for inputting only numbers from 1 onwards
<input type="text" min="1" oninput="this.value=this.value.replace(/[^0-9]/g,'');"
value=${var} >
Shortest
This is size improvement of R. Yaghoobi answer
<input type="number" oninput="this.value|=0"/>
We use here standard shorthand for "OR" operator e.g 9 | 2 = 11 in binary: 0b1001 | 0b1010 = 0b1011 . This operator first cast numbers to integers in implicit way and then do OR. But because OR with zero don't change anything so number is cast to integer. OR with non-number string gives 0.
Just putting it in your input field : onkeypress='return event.charCode >= 48 && event.charCode <= 57'
I was working oh Chrome and had some problems, even though I use html attributes. I ended up with this js code
$("#element").on("input", function(){
var value = $(this).val();
$(this).val("");
$(this).val(parseInt(value));
return true;
});
Set step attribute to any float number, e.g. 0.01 and you are good to go.
have you tried setting the step attribute to 1 like this
<input type="number" step="1" />
Maybe it does not fit every use case, but
<input type="range" min="0" max="10" />
can do a fine job: fiddle.
Check the documentation.
This is an old question, but the accessible (and now supported in most browsers) version would be:
<input type="text" inputmode="numeric" pattern="[0-9]*">
See https://technology.blog.gov.uk/2020/02/24/why-the-gov-uk-design-system-team-changed-the-input-type-for-numbers/
Yes, HTML5 does. Try this code (w3school):
<!DOCTYPE html>
<html>
<body>
<form action="">
Quantity (between 1 and 5): <input type="number" name="quantity" min="1" max="5" />
<input type="submit" />
</form>
</body>
</html>
See the min and max paremeter? I tried it using Chrome 19 (worked) and Firefox 12 (did not work).
Set step="any" . Works fine.
Reference :http://blog.isotoma.com/2012/03/html5-input-typenumber-and-decimalsfloats-in-chrome/
Currently, it is not possible to prevent a user from writing decimal values in your input with HTML only.
You have to use javascript.
var valKeyDown;
var valKeyUp;
function integerOnly(e) {
e = e || window.event;
var code = e.which || e.keyCode;
if (!e.ctrlKey) {
var arrIntCodes1 = new Array(96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 8, 9, 116); // 96 TO 105 - 0 TO 9 (Numpad)
if (!e.shiftKey) { //48 to 57 - 0 to 9
arrIntCodes1.push(48); //These keys will be allowed only if shift key is NOT pressed
arrIntCodes1.push(49); //Because, with shift key (48 to 57) events will print chars like #,#,$,%,^, etc.
arrIntCodes1.push(50);
arrIntCodes1.push(51);
arrIntCodes1.push(52);
arrIntCodes1.push(53);
arrIntCodes1.push(54);
arrIntCodes1.push(55);
arrIntCodes1.push(56);
arrIntCodes1.push(57);
}
var arrIntCodes2 = new Array(35, 36, 37, 38, 39, 40, 46);
if ($.inArray(e.keyCode, arrIntCodes2) != -1) {
arrIntCodes1.push(e.keyCode);
}
if ($.inArray(code, arrIntCodes1) == -1) {
return false;
}
}
return true;
}
$('.integerOnly').keydown(function (event) {
valKeyDown = this.value;
return integerOnly(event);
});
$('.integerOnly').keyup(function (event) { //This is to protect if user copy-pastes some character value ,..
valKeyUp = this.value; //In that case, pasted text is replaced with old value,
if (!new RegExp('^[0-9]*$').test(valKeyUp)) { //which is stored in 'valKeyDown' at keydown event.
$(this).val(valKeyDown); //It is not possible to check this inside 'integerOnly' function as,
} //one cannot get the text printed by keydown event
}); //(that's why, this is checked on keyup)
$('.integerOnly').bind('input propertychange', function(e) { //if user copy-pastes some character value using mouse
valKeyUp = this.value;
if (!new RegExp('^[0-9]*$').test(valKeyUp)) {
$(this).val(valKeyDown);
}
});
From the specs
step="any" or positive floating-point number
Specifies the value granularity of the element’s value.
So you could simply set it to 1:
Posting it, if anyone requires it in future
const negativeValuePrevent = (e) => {
const charCode = e.which ? e.which : e.keyCode;
if(charCode > 31 && (charCode < 48 || charCode > 57)
&& charCode !== 46){
if(charCode < 96 || charCode > 105){
e.preventDefault();
return false;
}
}
return true;
};
Most of the answers are outdated.
The following does not work anymore:
<!-- It doesn't invalidate decimals when using validators -->
<input type="number" min="0" step="1" />
The below solution is much more elegant and straight-forward and works on all latest browsers as of early 2022.
<!-- It DOES invalidate decimals when using validators -->
<input type="number" pattern="\d*" />
The integer input would mean that it can only take positive numbers, 0 and negative numbers too. This is how I have been able to achieve this using Javascript keypress.
<input type="number" (keypress)="keypress($event, $event.target.value)" >
keypress(evt, value){
if (evt.charCode >= 48 && evt.charCode <= 57 || (value=="" && evt.charCode == 45))
{
return true;
}
return false;
}
The given code won't allow user to enter alphabets nor decimal on runtime, just positive and negative integer values.
Short and user friendly
This solution supports tab, backspace, enter, minus in intuitive way
<input type=text onkeypress="return /^-?[0-9]*$/.test(this.value+event.key)">
however it not allow to change already typed number to minus and not handle copy-paste case.
As alternative you can use solution based on R. Yaghoobi answer which allow to put minus and handle copy-paste case, but it delete whole number when user type forbidden character
<input type=text oninput="this.value= ['','-'].includes(this.value) ? this.value : this.value|0">
NOTE: above inline solutions use only in small projects. In other case opaque them in functions and move to your js files.
In the Future™ (see Can I Use), on user agents that present a keyboard to you, you can restrict a text input to just numeric with input[inputmode].

javascript enter number of seconds - not less than zero

i am facing an issue in javascript. i want to do user enter number of seconds in input field.
but the condition is that users can't enter number of seconds less than zero.
how can a make the code logic?
function sec(){
//your code logic is here
console.log("number of seconds is not less than");
}
<form>
<label for="seconds">Number of seconds:</label>
<input type="number" id="seconds" name="seconds">
<button onclick="sec()">Click</button>
</form>
what should i do? anyone help me?
Add your expectation about the input value as attributes on your input:
Specifically required min="0" would meet your needs.
function sec(){
//your code logic is here
console.log("number of seconds is not less than");
}
<form>
<label for="seconds">Number of seconds:</label>
<input type="number" id="seconds" name="seconds" required min="0">
<button onclick="sec()">Click</button>
</form>
With JavaScript you can convert your user's input to a Number then check its value with an equality condition.
E.g. you could fill out your sec() function like this:
function sec() {
const seconds_str = document.getElementById("seconds").value;
const seconds_num = parseInt(seconds_str, 10); // note: you could use parseFloat for decimal fractions
let result = "";
if (seconds_num < 0) {
result = "Is less than zero :'(";
} else {
result = "Is NOT less than zero :)";
}
console.log("User input = " + seconds_str);
console.log("Converted to integer = " + seconds_num);
console.log(result);
}
<form>
<label for="seconds">Number of seconds:</label>
<input type="number" id="seconds" name="seconds">
<button onclick="sec()" type="button">Click</button>
</form>
It would be up to you what you do when you detect a number less than zero. E.g. prevent form submitting, show an error message etc...

Input number does not limit decimal when "0" is typed

I have a scenario where the HTML input field must take only 16 digit where 6 of its digits will be allocated for decimal places, but one strange thing happend in the code below is, when I add "0" at the end of decimal values, the digits are not being restricted and it keeps increasing. Is there anything that I'm missing out here?
<input type="number" name="val" min=0 max=9999999999.999999 step=".000001" save="" oninput="validity.valid ? this.save = value : value = this.save;"
Resolved the issue with the following code
<input type="number" name="val" min=0 max=9999999999.999999 step=".000001" save="" oninput="validity.valid && ((value.toString()).split('.')[1] === undefined || ((value.toString()).split('.')[1].length < 6)) ? this.save = value : value = this.save"/>

js if(!value > 0) on number input validation returning incorrectly

In this example:
<form name="someform" action="somepage.php" method="post">
<input name="length" id="length" type="number" min="1" oninput="validate()"/>
<input type="submit" id="submit" value="submit" />
</form>
I want to disable the submit button for any length value that is not greater than 0. I have min="1" on the input, which works fine when the users rely on the up/down buttons to enter a value, but it does not stop them from entering a 0 with the keyboard. So I have added the following validation js function.
function validate() {
var valid = true;
length = document.getElementById("length").value;
if(!length > 0) {
valid = false;
}
document.getElementById("submit").disabled = valid == false;
}
This function returns valid = true if you enter a 0 in the box and I don't understand why. If you have a number in the box and delete it so that the box is empty, it will return false, but 0 is always true here.
edit: You can enter a negative number, like -5 and that also returns true.
I have a jsbin example here: http://jsbin.com/qatekupuzu/edit?html,js,console,output
Any help in getting this working correctly would be appreciated.
No need fo any if just store the test inside the boolean valid directly. Like this:
function validate() {
var length = document.getElementById("length").value; // get the value
var valid = length > 0; // if length is > 0 then valid will be true, otherwise it will be false
document.getElementById("submit").disabled = !valid; // disable if only valid is false
}
You shouldn't write !length > 0. Instead use length != 0 or length <= 0
Seems nobody has caught this, so I'll throw this answer in to shed some light on what is really going on here.
The reason your statement is behaving like this is because it isn't the statement you think it is. Let's inspect it and see.
if(!length > 0) is what you typed. This statement inside the if is actually two statements. !length gets evaluated first, then its value is compared with > 0.
!length evaluates to a boolean, which is only true iff the number is 0. Any other number evaluates to false. Then because the left operator of > is a boolean > 0 is evaluated as boolean > boolean, which only evaluates to true iff the statement is true > false.
So the issue is not the statement returning incorrectly, you just aren't using the statement you want. What you intended to write is if( !(length >0) ){ valid = false; } or more concisely if(length <=0) { valid = false; }
EDIT: Another factor is at play here which fooled me based on the variable name length. Calling typeof(length) reveals that this variable is a string despite the number enforcement on the element. The above applies the same for type string with the modification that !"" is the only string that evaluates to true.
I am unclear whether or not you are attempting to validate the length of this string being longer than 0 (i.e. not empty), or if you want to validate that the number the user entered is greater than 0. If the former is the case, then evaluating length.length is what you want. For the latter, you would need to parse this as an int first using parseInt().
validate() fires on every keypress, so its better to initialize the lengthInput and submitButton objects once and use them in the function for better performance.
var lengthInput = document.getElementById("length"),
submitButton = document.getElementById("submit");
function validate() {
submitButton.disabled = !(lengthInput.value > 0);
}
// initial validation
validate();
<form name="someform" action="somepage.php" method="post">
<input name="length" id="length" type="number" min="1" oninput="validate()"/>
<input type="submit" id="submit" value="submit" />
</form>
why not:
document.getElementById("length").oninput=function (){
this.value=Math.max(this.value,1);
}
Or:
document.getElementById("length").oninput=function (){
this.value=this.value>0?this.value:"";
}
More easy for the user to understand, instead of disabling...
Modern day browsers require no JavaScript to disable the input.
input:invalid {
/* background-color: #ffdddd; */
}
form:invalid [type="submit"] {
opacity: .5;
pointer-events: none;
}
<form name="someform" action="somepage.php" method="post">
<input name="length" id="length" type="number" min="1" required/>
<input type="submit" id="submit" value="submit"/>
</form>
The bug with your code is the fact it is actually ((!length) > 0). Changing it to be !(length>0) or (length<=0) would make more sense. And you are really comparing a string to a number so it should be Number(length) so you are not relying on type coercion.

Categories