I've walked into a strange problem. When trying to replace a dot on a number input, instead of replacing just that dot, it clears out the entire input.
$("[data-input-payment-id]").on("keyup", function(e) {
var test_value = $(this).val().replace(/\./g, "");
$(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">
JSFIDDLE
How do I change it so it only removes the dots?
I think (guessing) it's because you use type="number". Then digits followed by a dot, e.g. 123., isn't a valid number, and val returns blank.
You could try this instead:
$("[data-input-payment-id]").on("keyup", function(e) {
var test_value = this.value.replace(/[^\d,]/g, "");
$(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input data-input-payment-id="12">
This uses normal text type and filters out anything but digits in the replace.
Edit:
Changed the regex to match anything but numbers and commas.
Your Keypress example gave me this idea. If you can intercept the keypress event, it is possible to check any validation before adding the actual value. This example also does not require any conditional and is able to filter any non-digit value.
$("[data-input-payment-id]").on("keypress", function(e) {
if ((this.value + e.key).match(/\D/)) {
return false;
}
});
$("[data-input-payment-id]").on("paste", function(e) {
var pasteData = (e.originalEvent.clipboardData || window.clipboardData).getData('text');
pasteData = pasteData.replace(/\D/g, '');
this.value = this.value + pasteData;
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">
Allows pasting data with filtering
No specific conditionals
Can be modified for custom validation
http://jsfiddle.net/xpvt214o/511118/
I would:
Instead of the keyup event, listen to the input event. This way you can also allow pasting.
Keep a record of the previous correct value, so that you can roll back to it. This is necessary because type=number inputs will have an empty string as value as soon as the input becomes invalid (as a number). I would store that previous correct value in a data property of the input element
With the use of the property validity.stepMismatch you can know whether the current value is violating the step property of the input which by default is 1. With a step of 1, this means entering a number with a decimal separator will be considered a mismatch.
As a trailing decimal separator will not (yet) yield a fractional number, it will pass the above validation. So echo the value back into the input when all is OK: this will eliminate any trailing decimal separator that might have been keyed in.
$("[data-input-payment-id]").on("input", function (e) {
if (!this.validity.stepMismatch) {
$(this).data("lastValid", $(this).val());
};
$(this).val($(this).data("lastValid") || "");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number"data-input-payment-id="12">
Having said this, I personally am not in favour of blocking user input in this way: they might for a moment think their keyboard is broke. It is in my opinion better to allow the user to type anything and just indicate with a message next to the input that the input is not valid (until it is).
This isn't really a solution as I'd personally like to see it, but here is what I did to solve the problem at hand. I changed the JavaScript code to listen for keycode 46 (the .) and I'm returning false on the paste event listener to disable pasting a value into the input.
$("[data-input-payment-id]").on("keypress", function(e) {
var key = e.charCode ? e.charCode : e.keyCode;
if (key == 46) {
return false;
}
});
$("[data-input-payment-id]").on("paste", function(e) {
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">
It works at least in Chrome and Edge.
See MDN docs on inputs of type number:
Value
A Number representing a number, or empty
If the input string cannot be converted to a proper number - such as if the string contains two dots - then accessing the .value property will return the empty string.
The .value (and val() function) will still return strings, but those strings must represent valid numbers (or be the empty string). Rather than setting the element's value unconditionally, simply check to see if the value isn't the empty string first:
$("[data-input-payment-id]").on("keyup", function(e) {
const val = $(this).val();
if (val === '') return;
var test_value = $(this).val().replace(/\./g, "");
$(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">
Or you might use a text input, and possibly a pattern:
$("[data-input-payment-id]").on("keyup", function(e) {
const val = $(this).val();
var test_value = $(this).val().replace(/\./g, "");
$(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<input data-input-payment-id="12">
<input type="submit">
</form>
<form>
<input pattern="^\d+$" data-input-payment-id="12">
<input type="submit">
</form>
$(this).val() is returning an empty string if an input with type="number" has more than one .
You can fix this, by only running the replacing the value if $(this).val() does not return an empty string.
Related
i've just build a javascript function with a regex control that allows 3 numbers and one dot.
function restrictNumber(e) {
var newValue = this.value.replace(new RegExp(/^(?!^(?:\d{1,3}|\d(?:\d?\.\d?|\.\d{2}))$).*/, 'gm'), "");
this.value = newValue;
}
$('.decimal').on('input', restrictNumber);
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<input class="decimal" type="text">
The specs of the regex are:
max. 3 numbers
only one or no dot
dot can be anywhere
Here is a regex demo for it: https://regex101.com/r/3Ru1O3/3/
i tried to "block" the input when a char is put in that isn't fitting. But when i try to test it deletes my hole string.
How can i change that behaviour that i just can't set new numbers put the string isnt vanishing.
You didn't say much about your actual requirements, as in, if the decimal is required at a certain place value, etc.. but based on what your existing regex does, it could definitely be shortened.
function restrictNumber(e) {
var newValue = this.value.replace(/[^\d\.]/, "").substr(0,4);
this.value = newValue;
}
$('.decimal').on('input', restrictNumber);
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<input class="decimal" type="text">
I want to auto list numbers every time the user types in 3 digits. The input numbers should appear in the div automatically.
$("#lister").on("keyup", function() {
var mxlen = $(this).data("mxlen");
var input = $(this).val();
if (input.length == mxlen) { //if input==3
$('#num_list').append('<li>' + input + '</li>');
$(this).html(''); //clear input after appended
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="num_list"></div>
<input type="number" id="lister" data-mxlen="3" />
The problem with my code is that it repeats the same numbers and does not clear the input after appending.
Your code is almost there, you just need to use val('') to reset the value.
Also note that you can make the logic more robust by using slice(0, mxlen) to restrict the value to 3 characters when typing quickly, and also change the check from == to >= for the same reason.
$("#lister").on("input", function() {
let $el = $(this);
var mxlen = $el.data("mxlen");
var input = $el.val();
if (input.length >= mxlen) {
$('#num_list').append('<li>' + input.slice(0, mxlen) + '</li>');
$el.val('');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="num_list"></div>
<input type="number" id="lister" data-mxlen="3" />
One last thing to note is that characters such as - or e are valid for entry in a type="number" input field, however they are not valid for the value returned from the field. As such the length check will get inconsistent output when these characters are used.
Depending on your use case you may be better off with a standard type="text" check and manually restricting the input to numerical values.
I have a input field which is a percent value, i am trying for it to display as % when not focused in and when focused in it will loose the %, also the input field needs to avoid chars on it. I'm using a type"text" input field with some jQuery.
$(document).ready(function() {
$('input.percent').percentInput();
});
(function($) {
$.fn.percentInput = function() {
$(this).change(function(){
var c = this.selectionStart,
r = /[^0-9]/gi,
v = $(this).val();
if(r.test(v)) {
$(this).val(v.replace(r, ''));
c--;
}
this.setSelectionRange(c, c);
});
$(this).focusout(function(){
$(this).val(this.value + "%");
});
$(this).focusin(function(){
$(this).val(this.value.replace('%',''));
});
};
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="percent" value="2"></input>
<input class="percent" value="4"></input>
on the snippet it does not behave the same as on my app, not sure why but the intended result is for it to erase any char that is not a digit or "only" 1 % sign.
Would change this approach only slightly:
use keypress (and eventually paste) to block invalid characters
use parseFloat (or int if you don't allow decimals) to remove leading 0's --> '00009.6' => '9.6%'
However I'd use <input type="number"> (btw: </input> closing tag is invalid HTML)
these days with a % sign just after the input. (number type has better display on mobile)
(function($) {
$.fn.percentInput = function() {
$(this)
// remove formatting on focus
.focus(function(){
this.value = this.value.replace('%','');
})
// add formatting on blur, do parseFloat so values like '00009.6' => '9.6%'
.blur(function(){
var r = /[^\d.]/g,
v = this.value;
this.value = parseFloat(v.replace(r, '')) + '%';
})
// prevent invalid chars
.keypress(function(e) {
if (/[^\d.%]/g.test(String.fromCharCode(e.keyCode)))
e.preventDefault();
});
};
})(jQuery);
$(document).ready(function() {
$('input.percent').percentInput();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="percent" value="2%">
<input class="percent" value="4%">
It is my understanding that the snippet you provided is the desired behavior, but your app isn't behaving in the desired way you've demonstrated. So, the question is: what's different between this snippet and your app? Does your app throw any errors into the console?
When I encounter problems like this, I'll usually run my page through an HTML validator. Sometimes, invalid html can corrupt more than you'd think.
When I put your html into a standard HTML5 template, the validator finds these errors in your snippet:
Basically, it is saying that you don't need </input>. Do this instead:
<input class="percent" value="2">
<input class="percent" value="4">
Perhaps this is completely unrelated, but I thought I'd mention it. I'd put your actual app through the html validator to see if you find more errors that could be ultimately corrupting your javascript's ability to achieve the desired behavior showcased by your snippet.
I have a panel that is used for programmatically creating textboxes. When a user clicks save, the values in these texboxes need to be concatenated and I need a character to separate each value. For this, I am using a comma (ASCII code 44). Because I am using a comma, I want to prevent any other commas from being entered in any of the textboxes in my textbox list. What would be the best way to go about doing this?
If jQuery is an option you can do
$(".no-comma-textbox").on("keydown", function(e){
if (e.which == 188){
e.preventDefault();
}
});
And all your textboxes should have class="no-comma-textbox".
(note: when I tested this 188 seems to be the correct value to use for comma at least in Chrome)
Try using oninput event attached to document , String.prototype.slice()
document.oninput = function(e) {
if (e.target.value.slice(-1) === ",") {
e.target.value = e.target.value.slice(0, -1)
}
}
var input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", "input2");
document.body.appendChild(input);
<input type="text" name="input0" />
<input type="text" name="input1" />
I have an html input type="number" field in an html page. like this:
<input type="number">
To validate the form I need to check that the length of this field is exactly 3. To do this I convert the number to String and execute the length() function.
The problem comes when the number starts with a zero. like 065
In that case the toString() method outputs a 65 with a length of 2
Do you have any idea on how to get the correct length of the number ?
I think that you would have to have your input type as text and then use JavaScript to get the length for validation. After that you could convert it to a number using the Number() function.
Change the input type to text and restrict the input with a pattern and maxlength:
<input type="text" pattern="\d*" maxlength="3">
You can solve this one of two ways:
When the user moves focus away from the field, remove the leading zeroes
In the validation, remove the leading zeroes then check the length
There is no need to convert to a number.
Removing leading zeroes when focus is lost:
function truncateNumericInput(event) {
event = event || window.event;
event.target = event.target || event.srcElement;
if (event.target.nodeName != "INPUT" || event.target.type != "number") {
return;
}
var input = event.target,
value = event.target.value;
input.value = value.indexOf(".") > -1
? value.replace(/^0{2,}/, "0")
: value.replace(/^0+/, "");
}
if (document.addEventListener) {
document.addEventListener("blur", truncateNumericInput, true);
} else {
document.attachEvent("focusout", truncateNumericInput);
}
JSFiddle: http://jsfiddle.net/67jyg1d9/
Removing leading zeroes during validation
var regex = /^0+/;
var value = input.value.replace(regex, "");
console.log(value.length <= 3)
<input type="number" name="quantity" min="0" max="999">
this takes care that only number can be entered and only till 999 that's 3 digits at max
You can solve your problem by using input type as number. You can build your logic by using overflow and underflow as shown below.
<input id="numtest" type="number" min="10" max="20" />
document.getElementById('numtest').validity.rangeOverflow
document.getElementById('numtest').validity.rangeUnderflow
or
document.getElementById('numtest').checkValidity();
rangeUnderflow: return true if value is less then min
rangeOverflow: return true if value is greater than max value.