How to make html numeric input wrap back around - javascript

So my question is, if you have an HTML numeric input with max={100} and min={50} how can you make it so that if you hit the down arrow when it is set to 50, to wrap back around to 100. I tried doing this manually by manipulating the onChange handler method, but this messes with the ability to type in the input box, making it so that if I begin to type 100, the first key pressed (1) is below 50 and sets it to 50.

Something like this:
const input = document.querySelector('input');
input.addEventListener('keydown', e => {
const min = parseInt(input.min);
const max = parseInt(input.max);
if(e.keyCode === 38 || e.code === 'ArrowUp') {
e.preventDefault();
input.value++;
if(input.value > max) input.value = min;
}
if(e.keyCode === 40 || e.code === 'ArrowDown') {
e.preventDefault();
input.value--;
if(input.value < min) input.value = max;
}
})
/* hide spin button */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
display: none;
}
input[type=number] {
font-size: 3em;
}
<input type="number" min="50" max="100" value="50" autofocus/>

change handler triggers every time the input value changes. You need to use keyup handler as John mentioned in the comment.
$('#input').on('keyup', function(e) { // Trigger when a key is pressed and then released
if (e.which === 38) { // Check if the pressed key is Up Arrow
var val = $('#input').val();
if (!isNaN(val)) { // Check if the value is a valid number
val++;
if (val > 100) val = 50; // If it exceeds 100, go back to 50
if (val < 50) val = 100; // Vice versa
$('#input').val(val);
}
else $('#input').val(50); // If the value is not a number, set it to 50
}
if (e.which === 40) { // Check if the pressed key is Down Arrow
var val = $('#input').val();
if (!isNaN(val)) {
val--;
if (val > 100) val = 50;
if (val < 50) val = 100;
$('#input').val(val);
}
else $('#input').val(50);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type='text' id='input' value="50">

You can use closures to keep track of the value in the input and then check the updated values against the elements own min and max attributes. Something like below:
function ticker(initVal, el, max, min) {
var currentValue = initVal;
return function(n) {
if (currentValue == n) {
if (n == max) {
el.value = min;
} else if (n == min) {
el.value = max;
}
}
currentValue = n;
}
}
var target = document.querySelector('#myNumber');
var updateEl = ticker(target.value, target, target.max, target.min);
document.querySelector('#myNumber').addEventListener('click', (e) => updateEl(e.target.value));
<input type="number" id="myNumber" value="1" max="5" min="1">

Related

JavaScript input type number check if input is a Number

Hey guys trying that I can just enter numbers with my keyboard into an html number field from 1-100.
I took the function from here HTML number input min and max not working properly and it worked properly for numbers between 1-100.
But I can still enter letters and I don't know how to solve it. I tried adding
if (typeof (parseInt(el.value)) != 'number') {
el.value = el.min;
}
But it is not working. Here is my whole code:
const enforceMinMax = (el) => {
if (el.value != "") {
if (parseInt(el.value) < parseInt(el.min)) {
el.value = el.min;
}
if (parseInt(el.value) > parseInt(el.max)) {
el.value = el.max;
}
if (typeof (parseInt(el.value)) != 'number') {
el.value = el.min;
}
}
}
<input type="number" id="quantity" name="quantity" min="1" max="100" step="1" onkeyup=enforceMinMax(this) ><br /><br />
How can I stop entering letters with my keyboard in a html number field?
You could apply this same logic to every numeric input that has a min & max attribute like so:
// find all numeric inputs that have both min & max attributes
// and apply the event handler to each.
document.querySelectorAll('input[type="number"][min][max]').forEach(
input => input.addEventListener('keyup', function(e) {
// if the value is numeric proceed - test the numeric value of the input against the min/max attribute values.
if( !isNaN( Number( this.value ) ) ) {
if( Number( this.value ) > this.max )this.value=this.max;
if( Number( this.value ) < this.min )this.value=this.min;
return true;
}
e.preventDefault();
return false;
})
);
<input type="number" name="quantity" min="1" max="100" step="1" />
You can compare keyCode and return false if key is not a number, then on key up you can validate min and max value, accordingly modify value of input
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<script>
function handleKeyDown(e) {
if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
e.preventDefault();
return false;
}
}
function handleKeyUp(e) {
const v = e?.target?.value || 0;
if (parseInt(v) === NaN || parseInt(v) < 1) {
e.target.value = 1;
} else if (parseInt(v) > 100) {
e.target.value = 100;
}
}
</script>
</head>
<body>
<input
type="number"
min="1"
max="100"
onkeydown="handleKeyDown(event)"
onkeyup="handleKeyUp(event)"
/>
</body>
</html>

Listener keydown : backspace and field length

I'm wondering why my Backspace touch increment my countLetters variable.
I ask him to return the number of characters, without ever manually incrementing the variable. Why does the backspace key increment my variable once, before working properly?
const $textareas = document.querySelectorAll('.js-textarea');
$textareas.forEach(function($textarea) {
$textarea.addEventListener('keydown', function(event) {
let max = 100;
let countLetters = $textarea.value.length;
let $meta = this.nextSibling.nextSibling; // = meta
$meta.innerHTML = countLetters + ' / ' + max;
if (countLetters >= max) {
$textarea.value.toString().substring(0, max);
}
if (event.which != 46) {
return;
}
// Disabled <textarea>
if (countLetters >= max) {
event.preventDefault();
}
});
});
Demo is available on Here's Codepen!
Thanks
Keydown fires before letter was added or removed in case of backspace. Use keyup instead of keydown.
The value of the text area is changed after your keydown handler runs. You could use the input event instead.
Here is an example:
const max = 100;
$textarea.addEventListener('input', function() {
const countLetters = $textarea.value.length;
const $meta = this.nextSibling.nextSibling;
$meta.innerHTML = countLetters + ' / ' + max;
});
$textarea.addEventListener('keydown', function(event) {
if ($textarea.value.length >= max && event.key === 'Backspace') {
event.preventDefault();
}
});

how to prevent a key input from appearing in input field?

I am trying to validate user input in a text input field.
I have written a javascript function for the same purpose which fires on onkeyup event.
The goal is to only allow user input if it's a numeric value less than 100 and with at most 1 decimal place.
The function is working fine but if a enter an invalid character ,say 'a', it will flash in the input box before being removed.
What I want is that if the entered character violates the defined condition it should not appear in the input box (as it is flashing right now for a split second).
Here's my code:
function validatePercent(event) {
var txt = $("#tds_input").val();
// alert(event.source);
if (!parseInt(txt)) {
$("#tds_input").val('');
}
if (isNaN(txt / 1)) {
txt = txt.substr(0, txt.length - 1);
$("#tds_input").val(txt);
}
if (txt > 100) {
//alert(2);
txt = txt.toString();
txt = txt.substr(0, txt.length - 1);
$("#tds_input").val(txt);
}
txt = txt.toString();
if (txt.indexOf('.') > -1) {
if (txt.substr(txt.indexOf('.') + 1, txt.length).length > 1) {
txt = txt.substr(0, txt.length - 1);
$("#tds_input").val(txt);
}
}
}
Using type=number (and not text) can help
function validatePercent(event)
{
var txt=$("#tds_input").val();
if(!parseInt(txt))
{
$("#tds_input").val('');
}
if(isNaN(txt/1))
{
txt=txt.substr(0,txt.length-1);
$("#tds_input").val(txt);
}
if(txt>100)
{
txt=txt.toString();
txt=txt.substr(0,txt.length-1);
$("#tds_input").val(txt);
}
txt=txt.toString();
if(txt.indexOf('.')>-1)
{
if(txt.substr(txt.indexOf('.')+1,txt.length).length>1){
txt=txt.substr(0,txt.length-1);
$("#tds_input").val(txt);
}
}
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" id = "tds_input" onkeyup="validatePercent()">
UPDATED
You could store the value of the when the focus is in the input.
When the user enters a valid percentage (integer only), replace the value stored. When inputs is incorrect, just replace with the old value.
var decimalSeparator = 1.1.toLocaleString().replace(/\d/g, ''),
pattern1 = "^(\\d{1,3})?([",
pattern2 = "]?\\d{1})?$",
regex = new RegExp(pattern1+decimalSeparator+pattern2),
resetContent = function () {
$('#tds_input').val($('#tds_input').data('val'));
},
matchRegex = function (value) {
return value.match(regex);
};
$('#tds_input').bind('focusin', (e) => {
$('#tds_input').data('val', $('#tds_input').val());
});
// handle input (keys, paste)
$('#tds_input').bind('input', (e) => {
let txtValue = $('#tds_input').val();
// input is empty
if (txtValue === "") {
$('#tds_input').data('val', "");
return;
}
// value does not match regex
if (!matchRegex(txtValue)) {
// maybe it ends with the decimal character?
if (txtValue[txtValue.length - 1] === "." && txtValue !== "100.") {
// simulate the user enters a decimal next
if (matchRegex(txtValue + "1")) {
$('#tds_input').data('val', txtValue);
return;
}
}
resetContent();
return;
}
// check between 0 and 100
let value = parseFloat(txtValue);
if (value >= 0 && value <= 100) {
// store new valid number
$('#tds_input').data('val', value);
// put the value as an integer in the input
$('#tds_input').val(value);
return;
} else resetContent();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="tds_input"/>

html Input type number with Thousand Separator

i want to add thousand separator on keyup event in input type number
but this work just in 6 character, if more than 6 character, value on input has reseted
this my short code
<input type="number" id="tanpa-rupiah" step="any">
var dengan_rupiah = document.getElementById('dengan-rupiah');
dengan_rupiah.addEventListener('keyup', function(e)
{
dengan_rupiah.value = formatRupiah(this.value, 'Rp. ');
});
function formatRupiah(bilangan, prefix)
{
var number_string = bilangan.replace(/[^,\d]/g, '').toString(),
split = number_string.split(','),
sisa = split[0].length % 3,
rupiah = split[0].substr(0, sisa),
ribuan = split[0].substr(sisa).match(/\d{1,3}/gi);
if (ribuan) {
separator = sisa ? '.' : '';
rupiah += separator + ribuan.join('.');
}
rupiah = split[1] != undefined ? rupiah + ',' + split[1] : rupiah;
return prefix == undefined ? rupiah : (rupiah ? 'Rp. ' + rupiah : '');
}
this my fiddle https://jsfiddle.net/C2heg/4619/
This might suit you. On keydown prevent the default action if it is not a number key. On keyup, parse the value and update it. Use the data- attributes to store and get the original value.
var elem = document.getElementById("num");
elem.addEventListener("keydown",function(event){
var key = event.which;
if((key<48 || key>57) && key != 8) event.preventDefault();
});
elem.addEventListener("keyup",function(event){
var value = this.value.replace(/,/g,"");
this.dataset.currentValue=parseInt(value);
var caret = value.length-1;
while((caret-3)>-1)
{
caret -= 3;
value = value.split('');
value.splice(caret+1,0,",");
value = value.join('');
}
this.value = value;
});
function showValue()
{
console.log(document.getElementById("num").dataset.currentValue);
}
<input type="text" id="num" maxlength="30">
<button onclick="showValue()">Get Value</button>
Ok I have posted answer below. I have added limit of 20 numbers. You can change it as per your need.
You can use Number.toLocaleString() for this purpose.
Below is working example:
// When ready.
$(function() {
var extra = 0;
var $input = $("#amount");
$input.on("keyup", function(event) {
// When user select text in the document, also abort.
var selection = window.getSelection().toString();
if (selection !== '') {
return;
}
// When the arrow keys are pressed, abort.
if ($.inArray(event.keyCode, [38, 40, 37, 39]) !== -1) {
if (event.keyCode == 38) {
extra = 1000;
} else if (event.keyCode == 40) {
extra = -1000;
} else {
return;
}
}
var $this = $(this);
// Get the value.
var input = $this.val();
var input = input.replace(/[\D\s\._\-]+/g, "");
input = input ? parseInt(input, 10) : 0;
input += extra;
extra = 0;
$this.val(function() {
return (input === 0) ? "" : input.toLocaleString("en-US");
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="amount" name="amount" type="text" maxlength="20" />
change your the input type equal to "text" then its work
<input type="text" id="tanpa-rupiah" step="any">
checkout jsfiddle

Maximum allowed value for <input type="text"/>

I have this input field:
<input type="text"/>
How can I allow entering only a number that is not greater than some predefined value, like for example 10, so every attempt to enter a number greater than 10 won't be allowed?
Javascript
function createValidator(element) {
return function() {
var min = parseInt(element.getAttribute("min")) || 0;
var max = parseInt(element.getAttribute("max")) || 0;
var value = parseInt(element.value) || min;
element.value = value; // make sure we got an int
if (value < min) element.value = min;
if (value > max) element.value = max;
}
}
var elm = document.body.querySelector("input[type=number]");
elm.onkeyup = createValidator(elm);
HTML
<input type="number" min="0" max="10"></input>
I haven't tested it, but I think it should work.
Convert the value to a number immediately, then compare it to a maximum value:
window.onload = function () {
var textbox = document.getElementById("text1");
var maxVal = 10;
addEvent(textbox, "keyup", function () {
var thisVal = +this.value;
this.className = this.className.replace(" input-error ", "");
if (isNaN(thisVal) || thisVal > maxVal) {
this.className += " input-error ";
// Invalid input
}
});
};
function addEvent(element, event, callback) {
if (element.addEventListener) {
element.addEventListener(event, callback, false);
} else if (element.attachEvent) {
element.attachEvent("on" + event, callback);
} else {
element["on" + event] = callback;
}
}
DEMO: http://jsfiddle.net/jBFHn/
As you type, if the value isn't a number or the value is greater than the maximum, the "input-error" class is added to the element. You can take out the whole class changing, and put in your own stuff.
This is how I used this property in my project.
<script>
function integerInRange(value, min, max, name) {
if(value < min || value > max)
{
document.getElementById(name).value = "100";
alert("Write here your message");
}
}
</script>
And my input like this
<input type="text" id="yyy" name="xxx" onkeyup="integerInRange(this.value, 0, 100, "yyy")" />
If you using bootstrap you can use alert window!
function integerInRange(value, min, max, name) {
if(value < min || value > max)
{
document.getElementById(name).value = "100";
$.pnotify({ title: 'UYARI', text: 'Girilen değer ' + min + ' ile ' + max + ' arasında olmalıdır.', type: 'error' });
$(".ui-pnotify-history-container").remove();
}
}

Categories

Resources