How to fix credit card input spacing - javascript

I researched this on stack overflow, tried different answers but nothing worked for me. Can someone fix the problem please.
function spacingFunction() {
let varNumber = document.getElementById('cardnumber');
position = varNumber.selectionEnd;
varNumber.value = varNumber.value.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim()
varNumber.selectionEnd = position += ((varNumber.value.charAt(position - 1) === ' ' && varNumber.value.charAt(length - 1) === ' ' && length !== varNumber.value.length) ? 1 : 0);
}
<input id="cardnumber" placeholder="e.g. 1234 5678 9123 0000" maxlength="19" type="text" onkeydown="spacingFunction()">
I tried all fix examples from the site. Need solution

Your question was very unclear, but I believe that you asked to fix the spacing issue, here's a very good example on jsfiddle
input_credit_card = function(input)
{
var format_and_pos = function(char, backspace)
{
var start = 0;
var end = 0;
var pos = 0;
var separator = " ";
var value = input.value;
if (char !== false)
{
start = input.selectionStart;
end = input.selectionEnd;
if (backspace && start > 0) // handle backspace onkeydown
{
start--;
if (value[start] == separator)
{ start--; }
}
// To be able to replace the selection if there is one
value = value.substring(0, start) + char + value.substring(end);
pos = start + char.length; // caret position
}
var d = 0; // digit count
var dd = 0; // total
var gi = 0; // group index
var newV = "";
var groups = /^\D*3[47]/.test(value) ? // check for American Express
[4, 6, 5] : [4, 4, 4, 4];
for (var i = 0; i < value.length; i++)
{
if (/\D/.test(value[i]))
{
if (start > i)
{ pos--; }
}
else
{
if (d === groups[gi])
{
newV += separator;
d = 0;
gi++;
if (start >= i)
{ pos++; }
}
newV += value[i];
d++;
dd++;
}
if (d === groups[gi] && groups.length === gi + 1) // max length
{ break; }
}
input.value = newV;
if (char !== false)
{ input.setSelectionRange(pos, pos); }
};
input.addEventListener('keypress', function(e)
{
var code = e.charCode || e.keyCode || e.which;
// Check for tab and arrow keys (needed in Firefox)
if (code !== 9 && (code < 37 || code > 40) &&
// and CTRL+C / CTRL+V
!(e.ctrlKey && (code === 99 || code === 118)))
{
e.preventDefault();
var char = String.fromCharCode(code);
// if the character is non-digit
// OR
// if the value already contains 15/16 digits and there is no selection
// -> return false (the character is not inserted)
if (/\D/.test(char) || (this.selectionStart === this.selectionEnd &&
this.value.replace(/\D/g, '').length >=
(/^\D*3[47]/.test(this.value) ? 15 : 16))) // 15 digits if Amex
{
return false;
}
format_and_pos(char);
}
});
// backspace doesn't fire the keypress event
input.addEventListener('keydown', function(e)
{
if (e.keyCode === 8 || e.keyCode === 46) // backspace or delete
{
e.preventDefault();
format_and_pos('', this.selectionStart === this.selectionEnd);
}
});
input.addEventListener('paste', function()
{
// A timeout is needed to get the new value pasted
setTimeout(function(){ format_and_pos(''); }, 50);
});
input.addEventListener('blur', function()
{
// reformat onblur just in case (optional)
format_and_pos(this, false);
});
};
input_credit_card(document.getElementById('cardnumber'));
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input id="cardnumber" placeholder="e.g. 1234 5678 9123 0000" maxlength="19" type="text" onkeydown="spacingFunction()">
<script src="script.js"></script>
</body>
</html>

Related

How to add plus one position to setSelectionRange

I am trying to move cursor one more position to the right in input.
var start = this.selectionStart,
end = this.selectionEnd;
this.setSelectionRange(start, end);
This works for keeping position in the same place after input value changed, but iam trying to add one more position to it, because my format code add "-" character after 4 chars.
$("input[name=login-access-token]").keypress(function(event){
var start = this.selectionStart,
end = this.selectionEnd;
console.log(start);
var input = $(this).val();
input = input.replace(/[\W\s\._\-]+/g, '');
var split = 4;
var chunk = [];
for (var i = 0, len = input.length; i < len; i += split) {
split = 4;
chunk.push( input.substr( i, split ) );
}
var test = [];
chunk.forEach(element => {
test.push(element.match(/.{1,4}/g));
});
test.forEach(element => {
if(element.length!=4){
$(this).val(function() {
var out = chunk.join("-").toUpperCase();
if(out.length == 4 && event.keyCode != 8){
out += "-";
}
if(out.length == 9 && event.keyCode != 8 ){
out += "-";
}
return out;
});
}
});
this.setSelectionRange(start, end);
var selection = window.getSelection();
selection.addRange(1);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<input type="text" name="login-access-token" placeholder="Code" />
var selection = window.getSelection();
selection.addRange(1); //not working :/
I solved it! Just add +1 to start and end which is values what we get from selectionStart.
if(out.length == 4 && event.keyCode != 8){
out += "-";
start = start+1;
end = end +1;
}
if(out.length == 9 && event.keyCode != 8 ){
out += "-";
start = start+1;
end = end +1;
}

How to validate allow minus(-) and only numbers in input textbox using Jquery?

How to validate in an Amount input field?
Allow minus (Negative) sign only once in the text box. For, eg, -10.00. Don't allow other special characters because it's an amount field.
It should not allow alphabet letters. Allow only numbers.
Decimal(.) should be only once in the text box.
I've wrote this just now based on your conditions, test it below:
Update:
Modified to work both on jquery and in javascript inline
// This is a middleware that takes as parameter "decimals" which is by default 2
currencyNumber = function(decimals) {
if (typeof decimals !== 'number') {
decimals = 2;
}
return function(e) {
var input = $(this instanceof Window ? e : e.currentTarget);
var value = $.trim(input.val());
var hasNegativeNumber = value.substr(0, 1) === '-' ? '-' : '';
var nextValue = value
.replace(/\.+/g, '.')
.replace(/[^0-9\.]+/g, '');
if (nextValue === '.' || (nextValue.length > 1 && nextValue === "00")) {
nextValue = '';
}
var dotsFound = nextValue.split('.').filter(function(i) {
return i.length;
});
var afterDot = '';
var beforeDot = '';
if (dotsFound.length > 1) {
beforeDot = dotsFound[0];
dotsFound.splice(0, 1);
afterDot = dotsFound.join('');
nextValue = +(beforeDot) + '.' + afterDot.substr(0, decimals);
}
if (nextValue.substr(nextValue.length - 1, 1) === '.') {
input.one('change', function() {
if (nextValue.substr(nextValue.length - 1, 1) === '.') {
nextValue = nextValue.substr(0, nextValue.length - 1);
input.val(hasNegativeNumber + nextValue);
}
$(this).off('change');
})
} else {
input.off('change')
}
input.val(hasNegativeNumber + nextValue);
};
}
// Here is where you call the middleware
$("#amount").on("keyup", currencyNumber(3));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="banner-message">
Test your number (bind is from jquery):
<input id="amount" type='text' />
<br /> Test your number (bind is from javascript inline):
<input id="amount-inline" onkeyup="currencyNumber(3)(this);" type='text' />
</div>
Edited: I guess this is what you are looking for. Found this in jsfiddle.net. No plugin needed.
HTML:
<input type="text" maxlength="10" id="myInput">
Javascript
var input = document.getElementById("myInput");
input.onkeypress = function(e) { e = e || window.event;
var charCode = (typeof e.which == "number") ? e.which : e.keyCode;
// Allow non-printable keys
if (!charCode || charCode == 8 /* Backspace */ ) {
return;
}
var typedChar = String.fromCharCode(charCode);
// Allow numeric characters
if (/\d/.test(typedChar)) {
return;
}
// Allow the minus sign (-) if the user enters it first
if (typedChar == "-" && this.value == "") {
return;
}
// In all other cases, suppress the event
return false;
};

Insert "/" in MM/YYYY textbox on keypress event

I want to enter a "/" when user enters MM(2 digit) so it will be like MM/YYYY.
I have done similar for credit card number input which insert a space after 4 digit on keypress.
let ccNumber = e.target.value.split(" ").join("");
if (ccNumber.length > 0) {
ccNumber = ccNumber.match(new RegExp('.{1,4}', 'g')).join(" ");
}
e.target.value = ccNumber;
Fiddle
This works with
Regular keyboard input
Copy/Cut/Paste
Selected text
Adding the /
Because you're programmatically adding the / character, you have to update the cursor position whenever that affects the new input value. This can be more than one character if the user is pasting something. Most of the code complexity revolves around this issue.
There are a lot of comments in the code explaining the various situations that come up because of the /.
Full Code
var date = document.getElementById('date');
date.addEventListener('keypress', updateInput);
date.addEventListener('change', updateInput);
date.addEventListener('paste', updateInput);
date.addEventListener('keydown', removeText);
date.addEventListener('cut', removeText);
function updateInput(event) {
event.preventDefault();
var string = getString(event);
var selectionStart = this.selectionStart;
var selectionEnd = this.selectionEnd;
var selectionLength = selectionEnd - selectionStart;
var sanitizedString = string.replace(/[^0-9]+/g, '');
// Do nothing if nothing is added after sanitization
if (sanitizedString.length === 0) {
return;
}
// Only paste numbers that will fit
var valLength = date.value.replace(/[^0-9]+/g, '').length;
var availableSpace = 6 - valLength + selectionLength;
// If `/` is selected it should not count as available space
if (selectionStart <= 2 && selectionEnd >= 3) {
availableSpace -= 1;
}
// Remove numbers that don't fit
if (sanitizedString.length > availableSpace) {
sanitizedString = sanitizedString.substring(0, availableSpace);
}
var newCursorPosition = selectionEnd + sanitizedString.length - selectionLength;
// Add one to cursor position if a `/` gets inserted
if (selectionStart <= 2 && newCursorPosition >= 2) {
newCursorPosition += 1;
}
// Previous input value before current cursor position
var valueStart = date.value.substring(0, this.selectionStart);
// Previous input value after current cursor position
var valueEnd = date.value.substring(this.selectionEnd, date.value.length);
var proposedValue = valueStart + sanitizedString + valueEnd;
// Remove anything that's not a number
var sanitized = proposedValue.replace(/[^0-9]+/g, '');
format(sanitized);
this.setSelectionRange(newCursorPosition, newCursorPosition);
}
function removeText(event) {
if (event.key === 'Backspace' || event.type === 'cut') {
event.preventDefault();
var selectionStart = this.selectionStart;
var selectionEnd = this.selectionEnd;
var selectionLength = selectionEnd - selectionStart;
// If pressing backspace with no selected text
if (selectionLength === 0 && event.type !== 'cut') {
selectionStart -= 1;
// Remove number from before `/` if attempting to delete `/`
if (selectionStart === 2) {
selectionStart -= 1;
}
}
var valueStart = date.value.substring(0, selectionStart);
var valueEnd = date.value.substring(selectionEnd, date.value.length);
// Account for added `/`
if (selectionStart === 2) {
selectionStart += 1;
}
var proposedValue = valueStart + valueEnd;
var sanitized = proposedValue.replace(/[^0-9]+/g, '');
format(sanitized);
this.setSelectionRange(selectionStart, selectionStart);
}
}
function getString(event) {
if (event.type === 'paste') {
var clipboardData = event.clipboardData || window.clipboardData;
return clipboardData.getData('Text');
} else {
return String.fromCharCode(event.which);
}
}
function format(sanitized) {
var newValue;
var month = sanitized.substring(0, 2);
if (sanitized.length < 2) {
newValue = month;
} else {
var year = sanitized.substring(2, 6);
newValue = month + '/' + year;
}
date.value = newValue;
}
<input id="date" type="text" maxlength="7">
Try:
var date = document.getElementById('date');
date.addEventListener('keypress', function (event) {
var char = String.fromCharCode(event.which),
offset = date.selectionStart;
console.log(offset)
if (/\d/.test(char) && offset < 7) {
if (offset === 2) {
offset += 1;
}
date.value = date.value.substr(0, offset) + char + date.value.substr(offset + 1);
date.selectionStart = date.selectionEnd = offset + 1;
}
if (!event.keyCode) {
event.preventDefault();
}
});
<input id="date" type="text" value="mm/yyyy" maxlength="6" size="6">
function keypress(elem) { // get Input
if (typeof elem == 'string') {
if (document.getElementById(elem)) elem = document.getElementById(elem);
if (typeof elem == 'string') elem = document.getElementsByName(elem).item(0);
}
const el = elem; //handle error if not found input
el.maxLength = 19;
el.addEventListener('keypress', function (e) {
const t = e.keyCode || e.which
if (t == 8 || (t > 47 && t < 58)) { // limit numeric characters and backspace
if (t != 8) {
if (el.value.length == 2) el.value += '/';
if (el.value.length == 5) el.value += '/';
if (el.value.length == 10) el.value += ' ';
if (el.value.length == 13) el.value += ':';
if (el.value.length == 16) el.value += ':';
}
} else {
e.preventDefault();
}
});}

Allow to enter only 2 decimal points number

I have a condition to allow user to input only 2 decimal points number and restrict the alphabets and other characters. I used the following function:
function isNumberKeyOnlyWithDecimalFormat(event,value,id){
var val = value;
if (event.shiftKey === true) {
event.preventDefault();
}
if ((event.keyCode >= 48 && event.keyCode <= 57) ||
(event.keyCode >= 96 && event.keyCode <= 105) ||
event.keyCode == 8 ||
event.keyCode == 9 ||
event.keyCode == 37 ||
event.keyCode == 39 ||
event.keyCode == 46 ||
event.keyCode == 190) {
} else {
event.preventDefault();
}
if(val.indexOf('.') !== -1 && event.keyCode == 190){
event.preventDefault();
}
if ((pointPos = $('#'+id).val().indexOf('.')) >= 0){
$('#'+id).attr("maxLength", pointPos+3);
}
else
$('#'+id).removeAttr("maxLength");
}
It is working fine while first time adding. But it restricts the if i want to edit the digits if it has already 2 decimal place. Can anyone help with this?
Try this. It will check the value each time the focus is gone from the input field, but you can use any event you like. It will parse the value as a float, and then round it to 2 decimal points.
Here is the fiddle: http://jsfiddle.net/sAp9D/
HTML:
<input type="text" id="the_id" />
JavaScript:
var input_field = document.getElementById('the_id');
input_field.addEventListener('change', function() {
var v = parseFloat(this.value);
if (isNaN(v)) {
this.value = '';
} else {
this.value = v.toFixed(2);
}
});
Your question is very hard to understand but if you want to check that a string has only 2 decimals then you can just do this
if( value.match(/\./g).length === 2 ) {
// Number has 2 decimals eg. 1.2.3
} else {
// Number is incorrect eg. 1.2.3.4
}
or if you want 1.2 then
if( value.match(/\./g).length === 1 ) {
// Code....
}
I use the following
// This function will only allow digits
function numericFormat( fld , e , extraStrCheck )
{
var sep = 0;
var key = '';
var i = j = 0;
var len = len2 = 0;
var strCheck = '0123456789';
if ( extraStrCheck )
strCheck += extraStrCheck;
var aux = aux2 = '';
var whichCode = (window.Event) ? e.which : e.keyCode;
if (whichCode == 13) return true; // Enter
if (whichCode == 8) return true; // Backspace
if (whichCode == 0) return true; // Null
if (whichCode == 9) return true; // Tab
key = String.fromCharCode(whichCode); // Get key value from key code
if ( strCheck.indexOf(key) == -1 ) return false; // Not a valid key
var x = new String(fld.value);
if ( key == '.' )
{
var exp = /\./;
var a = x.search(exp);
if ( a != -1 ) return false;
}
}
// samer code on change or on blur event
function allow2decimal(obj){
var v = parseFloat($(obj).val());
if (isNaN(v)) {
$(obj).value = '';
} else {
newVal = v.toFixed(2);
if(newVal >= 100){
$(obj).val( 100 );
}else{
$(obj).val(newVal);
}
}
}
//usage
<input
onkeypress="return numericFormat( this , event , '.');"
onchange="allow2decimal(this)"
value="0.1"
id="factory_silk" name="factory_silk" />
<html>
<head>
<script type="text/javascript">
function NumAndTwoDecimals(e, field) {
var val = field.value;
var re = /^([0-9]+[\.]?[0-9]?[0-9]?|[0-9]+)$/g;
var re1 = /^([0-9]+[\.]?[0-9]?[0-9]?|[0-9]+)/g;
if (re.test(val)) {
}
else {
val = re1.exec(val);
if (val) {
field.value = val[0];
}
else {
field.value = "";
}
}
}
</script>
</head>
<body>
<input type="text" name="text" onkeyup="NumAndTwoDecimals(event , this);">
</body>
</html>
$('.number').keypress(function(evt){
var str = $(this).val();
var index = str.indexOf('.');
if(index==-1){index=0;}else{index= index+1;}
var extrapoint = str.indexOf('.',index);
if(extrapoint>0){$(this).val(str.slice(0,-1));}
var charCode = (evt.which) ? evt.which : event.keyCode;
if(charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57))
return false;
return true;
var validNumber = new RegExp(/^\d*\.?\d*$/);
var lastValid = $(this).val();
if (validNumber.test($(this).val()))
{
lastValid = $(this).val();
}
else
{
$(this).val(lastValid);
}
});

Javascript dashes in phone number

I tried to research the answer to this question but I'm lost. I am trying to make a one search bar that automatically puts a dash in the phone number. I've solved that.
The next part is the challenging part. How can I make it always do XXX-XXX-XXXX, even if the characters pasted were something like 555 555 1212 or 555---555-1212, where it will only reel back the number and output with 555-555-1212. It shouldn't count the spaces or extra dashes as a character.
I found: http://www.jotform.com/answers/15202-can-I-add-script-to-my-form-that-will-automatically-add-hyphens-in-between-the-3-digit-area-code-and-also-the-3-digit-prefix
I changed it just a bit by adding:
<SCRIPT LANGUAGE="JavaScript">
function addDashes(f)
{
f.value = f.value.slice(0,3)+"-"+f.value.slice(3,6)+"-"+f.value.slice(6,15);
}
</SCRIPT>
<input id="input_4" class="form-textbox" maxlength="15" name="atn" size="25" onBlur='addDashes(this)' />
Right now, this works only if the user puts 5555555555 and automatically turns it into 555-555-5555. I'm trying to figure out how to take something like 5-55555-5555 and turn it into 555-555-5555. Currently, it makes it 5-5-555-5-5555.
See my dilemma? lol. It can't be php or any server side scripting as this must be able to run on a desktop.
Resolution:
<SCRIPT LANGUAGE="JavaScript">
function addDashes(f)
{
f.value = f.value.replace(/\D/g, '');
f.value = f.value.slice(0,3)+"-"+f.value.slice(3,6)+"-"+f.value.slice(6,15);
}
</SCRIPT>
First, clean your input by deleting all chars that are not numbers (ref.: Regex to replace everything except numbers and a decimal point)
Then, you put your dashes.
function addDashes(f)
{
f_val = f.value.replace(/\D[^\.]/g, "");
f.value = f_val.slice(0,3)+"-"+f_val.slice(3,6)+"-"+f_val.slice(6);
}
I have a strong tendency to treat phone numbers as a straight string of 10 digits with no formatting (so I can apply formatting to them on-the-fly, as needed and so searching and comparison is simpler), although that may change if I ever have to deal with international phone numbers. If all you're dealing with is US phone numbers, this will work nicely (formats it as it's typed):
function addDashes(f) {
var r = /(\D+)/g,
npa = '',
nxx = '',
last4 = '';
f.value = f.value.replace(r, '');
npa = f.value.substr(0, 3);
nxx = f.value.substr(3, 3);
last4 = f.value.substr(6, 4);
f.value = npa + '-' + nxx + '-' + last4;
}​
Here's a fiddle: http://jsfiddle.net/EYuk5/
transform with string method replace
let phone = '0884332212'.replace(/^(\d{3})(\d{3})(\d{4})/, '$1-$2-$3')
console.log(phone)
// => 088-433-2212
I did this
function addDashesToNumber(number){
const numWithoutDashes = number.replace(/[^0-9]/g, '')
if(numWithoutDashes.length > 10) return number.slice(0, -1)
const dashPlaces = [3, 6]
return numWithoutDashes
.split('')
.reduce((acc, curr, i) => dashPlaces.includes(i) ? [...acc, '-', curr] : [...acc, curr], [])
.join('')
}
Try this:
function dashedNumber(value){
const afterIndices = [3,6,8];
const length = value.length;
let newValue = ''
for(let i=0; i<length; i++){
if(afterIndices.includes(i))
newValue+='-'
newValue+=value[i];
}
return newValue;
}
Here's a fiddle: https://jsfiddle.net/v9gq5jkw/.
<input id="phone">
function phone_formatting(ele, restore) {
var new_number,
selection_start = ele.selectionStart,
selection_end = ele.selectionEnd,
number = ele.value.replace(/\D/g, '');
if (number.length > 2) {
new_number = number.substring(0, 3) + '-';
if (number.length === 4 || number.length === 5) {
new_number += number.substr(3);
} else if (number.length > 5) {
new_number += number.substring(3, 6) + '-';
}
if (number.length > 6) {
new_number += number.substring(6);
}
} else {
new_number = number;
}
ele.value = (new_number.length > 12) ? new_number.substring(0, 12) : new_number;
if (new_number.slice(-1) === '-' && restore === false &&
(new_number.length === 8 && selection_end === 7) ||
(new_number.length === 4 && selection_end === 3)) {
selection_start = new_number.length;
selection_end = new_number.length;
} else if (restore === 'revert') {
selection_start--;
selection_end--;
}
ele.setSelectionRange(selection_start, selection_end);
}
function phone_number_check(field, e) {
var key_code = e.keyCode,
key_string = String.fromCharCode(key_code),
press_delete = false,
dash_key = 189,
delete_key = [8, 46],
direction_key = [33, 34, 35, 36, 37, 38, 39, 40],
selection_end = field.selectionEnd;
if (delete_key.indexOf(key_code) > -1) {
press_delete = true;
}
if (key_string.match(/^\d+$/) || press_delete) {
phone_formatting(field, press_delete);
} else if (direction_key.indexOf(key_code) > -1) {} else if (dash_key === key_code) {
if (selection_end === field.value.length) {
field.value = field.value.slice(0, -1)
} else {
field.value = field.value.substring(0, (selection_end - 1)) + field.value.substr(selection_end)
field.selectionEnd = selection_end - 1;
}
} else {
e.preventDefault();
phone_formatting(field, 'revert');
}
}
document.getElementById('phone').onkeyup = function(e) {
phone_number_check(this, e);
}
Beside adding dashes, you will need to deal with the position of the cursor, especially in case of deletion.
This AMD module does exactly that: https://github.com/whenyoubelieve2014/us-telephone-input

Categories