JavaScript - Accepting only certain values for decimals - javascript

I have a number field to which I need to apply certain conditions with pure JS or jQuery:
Max 30
Min -30
Only 2 digits after the point, example 2.25
So possible values are like this (2.00 / 2.25 / 2.50/ 2.75 / 3.00...)
I managed to do so unless for the last condition that should accept only values .00 or .25 or .50 or .75
Here is my code:
var t_myField = false;
var myField_min = -30;
var myField_max = 30;
$('#myField').focus(function ()
{
var $this = $(this)
t_myField = setInterval(
function ()
{
if (($this.val() < myField_min || $this.val() > myField_max) && $this.val().length != 0)
{
if ($this.val() < myField_min)
{
$this.val(myField_min)
}
if ($this.val() > myField_max)
{
$this.val(myField_max)
}
}
}, 50)
});
$('#myField').on("keyup", function (e)
{
// Replacer , by .
$(this).val($(this).val().replace(/,/g, '.'));
// Allow only float numeric values (positif & negatif)
var self = $(this);
self.val(self.val().replace(/[^0-9\.-]/g, ''));
if (e.which != 46 && e.which != 45 && e.which != 46 && !(e.which >= 48 && e.which <= 57))
{
e.preventDefault();
}
// Allow max 2 digits after decimals for certain fields
match = (/(\d{0,2})[^.]*((?:\.\d{0,2})?)/g).exec(this.value.replace(/[^\d.]/g, ''));
this.value = match[1] + match[2];
});
<input type="text" name="myField" id="myField" class="myField">
JSFIDDLE => https://jsfiddle.net/Cartha/vq65Lypj/5/
[EDIT]
Control should be on keyup. This is why I can't use html5 attributes like min/max/step...

You can make use of % operator like x % 0.25 == 0 ? true : false

let myField = document.getElementById('myField');
myField.addEventListener('keypress', onlyNumbers,{passive: false});
myField.addEventListener('change', checkInput);
function onlyNumbers(e) {
if (!isNumberKey(e)) {
e.preventDefault();
}
}
function isNumberKey(e) {
return (e.which <= 31 || (e.which >= 48 && e.which <= 57) || e.which === 45 || e.which === 46);
}
function checkInput(e) {
let x = parseFloat(e.target.value);
if (!isNaN(x)) {
if (x > 30) {
x = 30;
} else if (x < -30) {
x = -30;
} else if (x % 0.25 !== 0) {
x = Math.round(x / 0.25) * 0.25;
}
e.target.value = x.toFixed(2);
}
}
This will allow only numbers with 0.25 steps.
Digit-only algorithm has been improved to completely prevent other type of input to be displayed (your code shows the forbidden input and then erases it).
This is the basic idea, a lot of other improvements can be made. For example, to always show two decimals (EX. 2.00 instead of 2), make an animation, etc. Currently, the check is set to happen after focus ends.
NOTE: Little extra improvements made in last edit.
JS Fiddle (I don't know how to embed it to the answer)

I would recommend creating a web component here. I'll show you the basic setup for a customized built-in with a component that already works and does not involve fumbling with $(document).ready() or DOMContentLoaded:
class DecimalInput extends HTMLInputElement {
constructor() {
super();
this.addEventListener('input', (e) => {
const val = parseFloat(this.value),
min = parseFloat(this.min),
max = parseFloat(this.max),
step = parseFloat(this.step);
if (val%step !== 0) {
this.value = Math.round(val/step) * step
}
if (val > max) {
this.value = max
}
if (val < min) {
this.value = min
}
this.value = Number(this.value).toFixed(2, 10);
})
}
}
customElements.define('decimal-input', DecimalInput, { extends: 'input' })
<input type="number" is="decimal-input" min="-30" max="30" step="0.25" value="0" />
This component is already quite close to your requirements. Use it to do our own refinements based on this.

Related

allow only 0-100 percent values in textbox

I have a percentage textbox. I want to enter values 0 to 100. Not more than 100 or negative values.
FIDDLE
Please check this fiddle. Here, it is allowing only 2 digit values like 99 only and after 99 it is allowing number of decimals(99..........9999) like this. Need to allow only one decimal point and I can enter 100 also.
Note :
Can Enter 0 to 100 and not negative and not more than 100.00
After decimal I want to enter only 2 digits like, 99.99 only.
Do not allow negative values.
Allow only one decimal point like(9.99 or 99.99). Not (9.......9..9...80099 or 99.......9......9).
<script>
function check(e,value){
//Check Charater
var unicode=e.charCode? e.charCode : e.keyCode;
if (value.indexOf(".") != -1)if( unicode == 46 )return false;
if (unicode!=8)if((unicode<48||unicode>57)&&unicode!=46)return false;
}
function checkLength(){
var fieldVal = document.getElementById('txtF').value;
//Suppose u want 3 number of character
if(fieldVal < 100){
return true;
}
else
{
var str = document.getElementById('txtF').value;
str = str.substring(0, str.length - 1);
document.getElementById('txtF').value = str;
}
}
</script>
<input id="txtF" type="number" onKeyPress="return check(event,value)" onInput="checkLength()" />
<p id="s"></p>
Please help me how can I do this using jQuery or JavaScript.
Updated fiddle. This solves it for now, but the use of step=0.01 may not be what you want. Setting the step to 0.01 allows us to check the validity state of the input.
The validitiy state is not updated an a "before" event so on an "after" event we rollback the input.
<input id="txtF" type="number" onInput="return check(event,value)" min="0" max="100" step="0.01" />
check = function (e,value){
if (!e.target.validity.valid) {
e.target.value = value.substring(0,value.length - 1);
return false;
}
var idx = value.indexOf('.');
if (idx >= 0 && value.length - idx > 3) {
e.target.value = value.substring(0,value.length - 1);
return false;
}
return true;
}
<script>
var point=false;
var count=0;
function check(e,value){
//Check Charater
debugger;
if(count==3)return false;
var unicode=e.charCode? e.charCode : e.keyCode;
if( unicode == 46 && point==true)
return false;
if( unicode == 46 && point==false)
{
point=true;
}
if (unicode!=8)if((unicode<48||unicode>57)&&unicode!=46)return false;
if(point==true)count++;
}
function checkLength(){
var fieldVal = document.getElementById('txtF').value;
//Suppose u want 3 number of character
if(fieldVal <= 100){
return true;
}
else
{
var str = document.getElementById('txtF').value;
str = str.substring(0, str.length - 1);
document.getElementById('txtF').value = str;
}
}
</script>
<input id="txtF" type="number" onKeyPress="return check(event,value)" onInput="checkLength()" />
<p id="s"></p>
http://jsfiddle.net/ySt7S/130/

validate input with decimal precision and scale

I am trying to create a javascript function which is called on keypress event on a input which does the following:
Input should be a valid decimal with format (5,2) => (XXXXX.YY) which are variable to the function. Input is restricted if user adds any value which does not conform to the format above.
If existing input starts with . append 0 to the starting automatically
HTML
<input type="text" onkeypress="return checkDecimal(event, this, 5, 2);" id="price2" value="27.15">
Javascript
function checkDecimal(evt, item, lenBeforeDecimal, lenAfterDecimal) {
var charCode = evt.which;
var trimmed = $(item).val().replace(/\b^0+/g, "");
if(checkStartsWith(trimmed, '.') == true){
trimmed = '0' + trimmed;
}
//Allow following keys
//8 = Backspace, 9 = Tab
if(charCode == 8 || charCode == 9){
return true;
}
//Only a single '.' is to be allowed
if(charCode == 46){
var dotOccurrences = (trimmed.match(/\./g) || []).length;
if(dotOccurrences != undefined && dotOccurrences == 1){
return false;
}else{
return true;
}
}
if (charCode > 31 && ((charCode < 48) || (charCode > 57))) {
return false;
}
if ($(item).val() != trimmed){
$(item).val(trimmed);}
//Check the start and end length
if(trimmed.indexOf('.') == -1){
if(trimmed.length >= parseInt(lenBeforeDecimal)){
return false;
}
}else{
var inputArr = trimmed.split(".");
if(inputArr[0].length > parseInt(lenBeforeDecimal) || inputArr[1].length >= parseInt(lenAfterDecimal)){
return false;
}
}
return true;
}
function checkStartsWith(str, prefix){
return str.indexOf(prefix) === 0;
}
Issues
If user inputs 12345.9 and then moves the caret position after 5, user is able to add another digit before the decimal 123456.9 which should not be allowed.
If user inputs 1.9 and then remove 1 and add 5, 5 is added at the end and the entered value becomes 0.95 and not 5.9
JS Fiddle
Consider using a regular expression like:
/^(\d{0,5}\.\d{0,2}|\d{0,5}|\.\d{0,2})$/;
that allows everything up to and including your required format, but returns false if the number part is more than 5 digits or if the fraction is more than 2 digits, e.g.:
<input type="text" onkeyup="check(this.value)"><span id="er"></span>
<script>
function check(v) {
var re = /^(\d{0,5}\.\d{0,2}|\d{0,5}|\.\d{0,2})$/;
document.getElementById('er').innerHTML = re.test(v);
}
</script>
You'll need separate validation for the final value, e.g.
/^\d{5}\.\d{2}$/.test(value);
to make sure it's the required format.
I don't understand the requirement to add a leading zero to "." since the user must enter 5 leading digits anyway (unless I misunderstand the question).

Validate date on keypress not working

This is the regex :
pattern =/^([0-9]{2})-([0-9]{2})-([0-9]{4})$/;
Hi guys, I found a simple regex for date format , no checking for leap year, but on my fiddle I can still input other invalid characters.
Please see my FIDDLE.
http://jsbin.com/ruhaxo/9/edit
Your code made me a little uncomfortable, so I tried to write this more simply so that it would be easier to read, you can pull out the part that you need, which I really think is just the event.preventDefault() when there is a match. Just to expand, as well: http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes you are looking for char codes not the literal numbers.
$('input').on('keypress', function (e) {
var leng = $(this).val().length;
if (window.event) {
code = e.keyCode;
}else {
code = e.which;
};
var allowedCharacters = [49,50,51,52,53,54,55,56,57,48,45];
var isValidInput = false;
for (var i = allowedCharacters.length - 1; i >= 0; i--) {
if(allowedCharacters[i] == code){
isValidInput = true;
}
};
if(isValidInput === false || /* Can only input 1,2,3,4,5,6,7,8,9 or - */
(code == 45 && (leng < 2 || leng > 5 || leng == 3 || leng == 4)) ||
((leng == 2 || leng == 5) && code !== 45) || /* only can hit a - for 3rd pos. */
leng == 10 ) /* only want 10 characters "12-45-7890" */
{
event.preventDefault();
return;
}
});
You can also do this with an object, rather than an Array. Which is a little easier to read:
$('input').on('keypress', function (e) {
var leng = $(this).val().length;
if (window.event) {
code = e.keyCode;
}else {
code = e.which;
};
var allowedCharacters = {49:1,50:2,51:3,52:4,53:5,54:6,55:7,56:8,57:9,48:0,45:'-'}; /* KeyCodes for 1,2,3,4,5,6,7,8,9,- */
if(typeof allowedCharacters[code] === 'undefined'|| /* Can only input 1,2,3,4,5,6,7,8,9 or - */
(code == 45 && (leng < 2 || leng > 5 || leng == 3 || leng == 4)) ||
((leng == 2 || leng == 5) && code !== 45) || /* only can hit a - for 3rd pos. */
leng == 10 ) /* only want 10 characters "12-45-7890" */
{
event.preventDefault();
return;
}
});
EDITED:
Please be careful with this, I haven't fully tested this, but I edited the regex from the post mentioned, if you have this in addition to one of the other choices above, (this happens on keyup after the other checks have been made) this would validate the date in the format mm-dd-yyyy please check that it works properly, I tried 02-29-2008, the first leap year I could think of, and it worked, but I would recommend testing it more since it has been modified.
$('input').on('keyup',function(e){
/* From:
http://stackoverflow.com/questions/17503043/javascript-regular-expression-to-validate-date-in-mm-dd-yyyy-format
and
http://jsfiddle.net/LSsMc/
*/
var thisVal = $(this).val();
var leng = thisVal.length;
var reg = new RegExp(/^(((0[13578]|1[02])\-(0[1-9]|[12]\d|3[01])\-((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\-(0[1-9]|[12]\d|30)\-((19|[2-9]\d)\d{2}))|(02\-(0[1-9]|1\d|2[0-8])\-((19|[2-9]\d)\d{2}))|(02\-29\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g);
if(leng == 10){
if(reg.test(thisVal)){
console.log('Valid Date');
}else {
event.preventDefault();
return;
}
}
});

Scroll if any alphanumeric character or symbol is pressed

I am writing a JS code that scrolls a container is any alphanumeric character or symbol is pressed.
This is what I came up with:
var $q = $('input#q');
$q.on('keydown', function (e) {
var reMatch = /[!-~]/.exec(e.which);
if (typeof reMatch != 'null' && reMatch.length > 0) {
$('#container').animate({scrollTop: 410}, 500);
$(this).off('keydown');
}
}).focus();
But this executes for all keys like shift, tab, enter etc ...
What's wrong with the code?
e.which gives a numeric representation of the key pressed. The number keys are represented by 48-57 (or 96-105 on the keypad) while letters are represented by 65-90
Try this:
var $q = $('input#q');
$q.on('keydown', function (e) {
var val = e.which;
var num = (val > 47 && val < 58 || val > 95 && val < 106);
var letter = (val > 64 && val < 91);
if (num || letter) {
$('#container').animate({scrollTop: 410}, 500);
$(this).off('keydown');
}
}).focus();
You could do this for it to work with anything that creates an input in the text field:
var $q = $('input#q');
$q.on('input', function (e) {
$('#container').animate({
scrollTop: 410
}, 500);
$(this).off('input');
}).focus();
but this will not work for IE versions less than 9. Although if you look, you can find shims. Here is an example
You could do this, but it would not scroll immediately if the user is holding a key down for a long time (until the user releases the key).
var $q = $('input#q');
var qval = $q.val()
$q.on('keyup', function (e) {
if(qval != $q.val()) {
$('#container').animate({scrollTop: 410}, 500);
$(this).off('keyup');
}
}).focus();

JavaScript on IE and Chrome? (It works on Firefox)

function ord(string) {
var str = string + '',
code = str.charCodeAt(0);
if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
var hi = code;
if (str.length === 1) {
return code; // This is just a high surrogate with no following low surrogate, so we return its value;
// we could also throw an error as it is not a complete character, but someone may want to know }
var low = str.charCodeAt(1);
return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
}
if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate return code; // This is just a low surrogate with no preceding high surrogate, so we return its value;
// we could also throw an error as it is not a complete character, but someone may want to know
}
return code;
}
}
$(document).ready(function () {
var maxTxtNumber = 8;
var arrTxtNumber = new Array();
var txtvalues = new Array();
var arr = {};
$('.numericonly').keypress(function (e) {
var t = $(this).val();
var k = e.which;
delete arr[8];
if ((e.which >= 49 && e.which <= 55) || e.which == 8) {
if (e.which == 8) {
var s = new String(t);
s = s.charCodeAt(0);
delete arr[s];
}
if (arr[k]) {
e.preventDefault();
} else {
arr[k] = e.which;
}
} else {
e.preventDefault();
}
});
});
The code works on Firefox but not on IE and Chrome?
Other browsers use e.keyCode to tell you which key was pressed. Cross-browser:
var k = e.keyCode || e.which;
Also make sure you use k rather than repeating e.which every time.
All that code is not required. If you want to test that an input's value is only digits, then something like the following will do:
<input type="text" onblur="check(this);" ...>
function check(el) {
if (!isDigits(el.value)) {
alert('Hey!!\nThe element you just left should only contain digits');
}
}
function isDigits(s) {
return /^\d*$/.test(s);
}
It's much more friendly to give the user a hint about the format you require and wait until they either leave the control or submit the form before offering a warning about invalid values. You really don't care how the user gets to a valid value, just so long as it's valid when the form is submitted.
And you must validate on the server again.
I recommend running your code through a validator such as http://www.jslint.com/ to make sure that everything adheres to universal standards.

Categories