Format input with regex - javascript

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.

Related

Replacing a dot using JavaScript instead removes everything

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.

Uncaught ReferenceError: changePhone is not defined

I have some text inputs on my site for phone numbers. I want to keep all numbers in one format not some like 123-456-7890 and others 1234567890. I've tried writing a code to change this but it is giving me an error of Uncaught ReferenceError: changePhone is not defined.
Here is my code:
<input type="text" id="phone" onblur="changePhone(this.id)">
function changePhone(id){
$(id).text(function(i, number) {
number = number.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3");
return number;
});
}
When running validation my code checks out as valid so I am not understanding why it doesn't work.
On a side note: Is there a PHP solution to achieve this or is jquery my best option?
EDIT: Here is a fiddle of my code: http://jsfiddle.net/4uk9hhtc/
There are so many things wrong with this.
$(id) does not work because you need a # before ID. You are doing $('whateverID') should be $('#whateverID')
The .text()does not work because you are running on an input element.
Your fiddle is missing jquery, and the code should in <head>
http://jsfiddle.net/4uk9hhtc/13
function changePhone(id){
var number = $("#"+id).val().replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3");
alert( number )
}
OR you could just use jquery and get rid of inline onclick like in the other answers
Here is something that actually works
$(function() {
$('#phone').on('blur', function(){
var val = ""+this.value;
this.value = val.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" id="phone" />
Pure JS with inline invocation
function changePhone(field) {
var val = ""+field.value;
field.value = val.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3");
}
<input type="text" id="phone" onblur="changePhone(this)"/>
Pure jQuery solution. Your fiddle isn't including jQuery by the way. I'm making assumptions that you know how to include jQuery correctly. You should be using val().
http://jsfiddle.net/2kLywwpu/1/
<input type="text" class="phone" id="theText">
using
var textbox = $('#theText').on('blur', function(){
textbox.val(function(i, number) {
number = number.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3");
return number;
});
});
Here's a fiddle that's not using your regular expression so you can see that the basic functionality works.
http://jsfiddle.net/2kLywwpu/2/

Jquery: Combine multiple user inputs into one text area?

I'm trying to put together multiple user inputs and then combine them into one textarea after button click.
For example:
User1:Hey, I just met you
User2:And this is crazy
User3:But Here's my number so call me maybe
Combined Result:
Hey, I just met you, And this is crazy, But Here's my number so call me maybe
Here's my code the button click is currently not working but when I tried it before it did work so I was thinking I have some problem w/ my Jquery that triggers this unusual result:
HTML and Imports:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<input class="combine" id="input1" disabled="true"></input>
<input class="combine" id="input2" disabled="true"></input>
<input class="combine" id="input3" disabled="true"></input>
<input class="combine" id="input4" disabled="true"></input>
<input class="combine" id="input5" disabled="true"></input>
<input class="combine" id="input6" disabled="true"></input>
<input class="combine" id="Voltes5" disabled="true" size="45"></input>
<button id="setVal">Set</button>
Jquery
$(document).ready(function(){
$('#setVal').on('click',function(){
jQuery(function(){
var form = $('.combine');
form.each(function(){
$('.Voltes5').append($(this).text()+ ' ');
});
});
});
});
Update for sir Arun P Johny
User1: If theres a (no comma when combined)
User2: will
User3: there's a way
Combined Result:
If theres a will, there's a way
Try
$(document).ready(function () {
$('#setVal').on('click', function () {
var form = $('.combine').not('#Voltes5');
var vals = form.map(function () {
var value = $.trim(this.value)
return value ? value : undefined;
}).get();
$('#Voltes5').val(vals.join(', '))
});
});
Demo: Fiddle
Here's a one-liner for non-readability ;)
$('#setVal').click(function(){$('#Voltes5').val($('.combine').not('#Voltes5').map(function(){return $(this).val();}).get().join(''))});
Expanded:
$('#setVal').click(function(){
$('#Voltes5').val(
$('.combine')
.not('#Voltes5')
.map(
function(){
return $(this).val();
})
.get()
.join('')
);
});
Get fiddly with it: http://jsfiddle.net/ArtBIT/u57Zp/
Here is one way to do this:
$('#setVal').on('click', function () {
$(".combine[id^=input]").each(function () {
if(this.value) {
$("#Voltes5")[0].value += ' ' + this.value;
}
});
});
There are several different ways to do this..
I'd do it this way using an array:
$(document).ready(function () {
$('#setVal').on('click', function () {
//create an array for the values
var inpAry = [];
$('.combine').each(function () {
//add each value to the array
inpAry.push($(this).val+' ');
});
//set the final input val
$('#Voltes5').val(inpAry);
});
});
but you would need to remove the combine class from #setVal because that would be included in the .each.
This way it would also be possible to have the final box updated on keyup as I'm not just appending the values, the combined values are set each time.
$(document).ready(function(){
$('#setVal').on('click',function(){
var val='';
$('.combine').not('#Voltes5').each(function(){
val+=$(this).val();
});
$('#Voltes5').val(val);
});
});
.text() will give text of the element ,for input val u have to use .val()
So there's immediate big problem in the code, which is that you're referring to your Voltes5 element as a class, not an ID. The jQuery selector you want is:
#Voltes5
instead of:
.Voltes5
There are a few other things to think about too, though, for the sake of functionality and best practices. Firstly, the Voltes5 element also has class combine, meaning that the $('.combine').each() call will include this element. The outcome of this is that it will also append its current text to itself when the code is run (or, when the code is run with the above correction).
When grabbing the current entered text of an input element, a jQuery .val() call is what you want, not .text() - see this answer for some more discussion.
Another thing that could be noted is that you should really explicitly specify what sort of input these elements are; <input type="text"> is hugely preferable to <input>.
Finally, input is a void element (reading), meaning it shouldn't have any content between opening and closing tags. Ideally, you wouldn't even give a closing tag; either have just the opening tag, or self-close it:
<input>
<input />
HTH
replace $('.Voltes5').append($(this).text()+ ' ');
with
$('#Voltes5').append($(this).text()+ ' ');

jQuery library to autopopulate multiple fields

I have multiple textboxes with set character limits that together make up a code. There is value in the boxes being separated for a variety of reasons. I want to be able to paste a complete code in the first textbox and have it automatically populate all the textboxes. Is there a way to do this in javascript or a jquery library for this case?
Currently I'm using jQuery autotab on each textbox and I'd prefer to keep that functionality.
DEMO
Use the onpaste event to capture the data from the user's clipboard. Then take that data and produce an array appropriate for your inputs. Then set those values using .val()
JS
$(function(){
// get first input element
pastable = document.getElementById('pastable');
// listen for the user to paste
pastable.onpaste = function(e){
// retrieve paste data as an array split to each 3 characters (3 dots below in regex)
var inputArray = e.clipboardData.getData('text/plain').match(/.../g);
// loop over input fields
$('input').each(function(i){
// place data from paste
$(this).val(inputArray[i]);
});
};
});​
HTML
<input type='text' id="pastable" maxlength="3"/>
<input type='text' maxlength="3" />
<input type='text' maxlength="3" />​
You can certainly do this in JS. I don't know about a library to do it for you through. Shooting from the hip here but maybe something like this:
Example HTML
<input type='text' data-auto-pop='true' data-group='1' data-char-limit='3'/>
<input type='text' data-auto-pop='true' data-group='1' data-char-limit='3'/>
<input type='text' data-auto-pop='true' data-group='1' data-char-limit='4'/>
Example JS
$("input[data-auto-pop='true']").change(function () {
var $this = $(this), val = $this.val();
if ($this.data("char-limit") > val.length) {
return;
} else {
var setVal = function() {
$this.val(val.slice(0, $this.data("char-limit"));
val = val.slice($this.data("char-limit"));
};
setVal();
while ($this.closest("input[data-group='"+$this.data("group")+"']") && val.length > 0) {
$this = $this.closest("input[data-group='"+$this.data("group")+"']");
setVal();
}
}
}
Probably has some mistakes in it but you should get the idea.

Validate TextBox In JavaScript

i need a validate textbox which is accepted like this $250.00 here is '$' will accepted only one time and then never accepted '$' as well as '.'(dot).
You could use a masked input for example
your mask would be
$('#input').mask('$9?.99');
You can do:
var x = document.getElementById('your-text-box').value;
if(x.match(/^\$[0-9]+\.[0-9]+$/) == null) {
// invalid
}
else {
// valid
}
The regex /^\$[0-9]+\.[0-9]+$/ will match any string meeting the following constraints
Should start with a $
Should have 1 or more numbers after the $
Should have a . after the first set of numbers
Should end with 1 or more numbers after the .
Is jquery an option?
Here is a jquery solution. First of all I wouldn't validate expecting user to put '$'. I would put that outside the form and just allow people to enter the amount. That's weird, but I guess I don't really have the context on what you are doing. See Jquery validation:
$("#myform").validate({
rules: {
field: {
required: true,
digits: true
}
}
});
This is using digits to allow only numbers. Otherwise if you really need $ in there you need to create a custom validation rule.
<!-- wherever your jquery file is -->
<script src="../../jquery.min.js"></script>
<input type="text" id="cost"><input type="button" id="check" value="Check!">
<script>
// jquery solution
$(document).ready( function (){
$('#check').click( function (){
var cost = $('#cost').val();
var patt=/^(\$)?\d+(\.\d+)?$/;
var result=patt.test(cost);
alert(result);
});
});
</script>
Of course you can use pure java script as well to reduce the dependency
<input type="text" id="cost">
<input type="button" id="check" value="Check!" onClick="check();">
<script>
// Pure Javascript Solution
var check = function (){
var cost = document.getElementById('cost').value;
var patt=/^(\$)?\d+(\.\d+)?$/;
var result=patt.test(cost);
alert(result);
}
</script>

Categories