Adding a space after 4 chars in an input [duplicate] - javascript

I'm really new in JavaScript and I would like to add to my input text, space insertion for IBAN account registering.
<input type="text" name="iban" onkeyup="if(this.value.length > 34){this.value=this.value.substr(0, 34);}" />
There is my input field; could someone tell me how I can do this?

The existing answers are relatively long, and they look like over-kill. Plus they don't work completely (for instance, one issue is that you can't edit previous characters).
For those interested, according to Wikipedia:
Permitted IBAN characters are the digits 0 to 9 and the 26 upper-case Latin alphabetic characters A to Z.
Here is a relatively short version that is similar to the existing answers:
document.getElementById('iban').addEventListener('input', function (e) {
e.target.value = e.target.value.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim();
});
<label for="iban">iban</label>
<input id="iban" type="text" name="iban" />
As stated above, the caveat is that you can't go back and edit previous characters. If you want to fix this, you would need to retrieve the caret's current position by initially accessing the selectionEnd property and then setting the caret's position after the regex formatting has been applied.
document.getElementById('iban').addEventListener('input', function (e) {
var target = e.target, position = target.selectionEnd, length = target.value.length;
target.value = target.value.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim();
target.selectionEnd = position += ((target.value.charAt(position - 1) === ' ' && target.value.charAt(length - 1) === ' ' && length !== target.value.length) ? 1 : 0);
});
<label for="iban">iban</label>
<input id="iban" type="text" name="iban" />
You will notice that there is a slight issue when the character after the caret is a space (because the space wasn't accounted for when initially retrieving the caret's position to begin with). To fix this, the position is manually incremented if the succeeding character is a space (assuming a space was actually added - which is determined by comparing the length before and after replacing the characters).

Using plain-JavaScript, I'd suggest:
function space(el, after) {
// defaults to a space after 4 characters:
after = after || 4;
/* removes all characters in the value that aren't a number,
or in the range from A to Z (uppercase): */
var v = el.value.replace(/[^\dA-Z]/g, ''),
/* creating the regular expression, to allow for the 'after' variable
to be used/changed: */
reg = new RegExp(".{" + after + "}","g")
el.value = v.replace(reg, function (a, b, c) {
return a + ' ';
});
}
var el = document.getElementById('iban');
el.addEventListener('keyup', function () {
space(this, 4);
});
JS Fiddle demo.
Somewhat belatedly, my rewrite of the above to handle strings, rather than DOM nodes:
function space(str, after) {
if (!str) {
return false;
}
after = after || 4;
var v = str.replace(/[^\dA-Z]/g, ''),
reg = new RegExp(".{" + after + "}", "g");
return v.replace(reg, function (a) {
return a + ' ';
});
}
var el = document.getElementById('iban');
el.addEventListener('keyup', function () {
this.value = space(this.value, 4);
});
JS Fiddle demo.
References:
addEventListener().
JavaScript regular expressions.

I wrote a simple function extending David's function to handle the last space. Also you can specify the separator.
function spacify(str, after, c) {
if (!str) {
return false;
}
after = after || 4;
c = c || " ";
var v = str.replace(/[^\dA-Z]/g, ''),
reg = new RegExp(".{" + after + "}", "g");
return v.replace(reg, function (a) {
return a + c;
}).replace(/[^0-9]+$/, "");
}
console.log(spacify("123123123131",4," "))
console.log(spacify("12312312313",4,"-"))

The code from Josh Crozie is really nice, but not complete.
Two issues with it;
If the caret is not at the end but e.g. at the before last position and the user starts typing, sometimes the caret doesn't stay at the before last position
Another issue is with Android 7+ devices. Those devices update the caret position slightly later, that means it needs a setTimeout() before reading the caret location
The code below is based on the code of Josh Crozie, now with the two issues mentioned above fixed and a little more verbose for readability purpose:
var isAndroid = navigator.userAgent.indexOf("ndroid") > -1;
var element = document.getElementById('iban');
element.addEventListener('input', function () {
if (isAndroid) {
// For android 7+ the update of the cursor location is a little bit behind, hence the little delay.
setTimeout(reformatInputField);
return;
}
reformatInputField();
});
function reformatInputField() {
function format(value) {
return value.replace(/[^\dA-Z]/gi, '')
.toUpperCase()
.replace(/(.{4})/g, '$1 ')
.trim();
}
function countSpaces(text) {
var spaces = text.match(/(\s+)/g);
return spaces ? spaces.length : 0;
}
var position = element.selectionEnd;
var previousValue = element.value;
element.value = format(element.value);
if (position !== element.value.length) {
var beforeCaret = previousValue.substr(0, position);
var countPrevious = countSpaces(beforeCaret);
var countCurrent = countSpaces(format(beforeCaret));
element.selectionEnd = position + (countCurrent - countPrevious);
}
}
<label for="iban">iban</label>
<input id="iban" type="text" name="iban" size="35" />

You have to capture each group of 4 digits and then put a space between each group.
$('input').blur(function () {
//Replace each group 4 digits with a group plus a space
var reformat = this.value.replace(/(\d{4})/g, function(match){
return match + " ";
});
this.value = reformat;
})
And this one updates the element while typing
//Keys pressed 0 times
var downed = 0;
$('#test').keydown(function (g) {
if(g.code.match("^Digit")){
downed++;
console.log(g)
}
if(downed == 1){
var reformat = this.value.replace(/(\d{4}\s*)/g, function(match){
//Strip spaces
if(match.match(/\s/)){return match;}
return match + " ";
});
console.log(reformat);
this.value = reformat;
//Start recount
downed = 0;
}
});
Check out the fiddle

for thousands on angular 4 in a pipe
integer = integer.replace(/[^\dA-Z]/g, '').replace(/(.{3})/g, '$1.').trim();

I need the same but for BVR/BVR+ swiss payment form.
So what I need is add a space every 5 chars but from the end of the string.
Example : "52 86571 22001 00000 10520 15992" or sometimes shorter like "843 14293 10520 15992".
So, here is the solution by reversing the string before and after adding spaces if rev=1.
function space(str, stp, rev) {
if (!str) {
return false;
}
if (rev == 1) {
str = str.split('').reverse().join('');
}
if(stp > 0) {
var v = str.replace(/[^\dA-Z]/g, ''),
reg = new RegExp(".{" + stp + "}", "g");
str = v.replace(reg, function (a) {
return a + ' ';
});
}
if (rev == 1) {
str = str.split('').reverse().join('');
}
return str;
}
Use :
var refTxt = space(refNum, 5, 1);
EDIT : PHP version added
function space($str=false, $stp=0, $rev= false) {
if(!$str)
return false;
if($rev)
return trim(strrev(chunk_split(strrev($str), $stp, ' ')));
else
return trim(chunk_split($str, $stp, ' '));
}

document.getElementById('iban').addEventListener('input', function (e) {
e.target.value = e.target.value.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim();
});
<label for="iban">iban</label>
<input id="iban" type="text" name="iban" />

This is the shortest version using JQuery on input with type number or tel:
$('input[type=number], input[type=tel]').on('input', function (e) {
e.target.value = e.target.value.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim();
});
You can also change the 4 to any other character limit you want.

onChangeText={number => {
const data =
number.length % 5 !== 4
? number
.replace(/[^\dA-Z]/g, '')
.replace(/(.{4})/g, '$1-')
.trim()
: number;
this.setState({
...this.state,
card: {...this.state.card, number: data},
});
}}
If you are trying to use for text input to adjust with credit card then this method will help you solve the backspace problem too

To Add space after 4 Digits
Useful to validate IBAN Number
document.getElementById('IBAN').addEventListener('input', function (e) {
e.target.value = e.target.value.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim();
});
<label for="IBAN">IBAN</label>
<input id="IBAN" maxlength="14" type="text" name="IBAN" />

Related

Pure Javascript - get beginning position of current line in a multiline textarea

I'm looking for a pure javascript answer as that reflects my projects scope. jQuery answers will not be marked correct, but are welcomed for future question seekers. Side note: I am also not interested in third party libraries.
I'm trying to get the first position (0) of the current line (current is based of selectionStart the chance the user selects more than 1 line) in a multiline textarea, but translate that to caret index.
What have I tried? Nothing pretty:
for ( i = 0; i < this.selectionStart; i++ ) {
if (this.value.substr(i,1).match(/\r?\n|\r/)) {
lineStartIndx = i + 1
}
}
This is proving to be costly when iterating textareas with huge amounts of lines. My personal usage of this will not be executed every keydown, however, I just used it as an example. Are there any better methods, built in or otherwise to emulate this outcome?
My full example:
var input = document.getElementById("ta");
var output = document.getElementById("output");
let pattern = /\r?\n|\r/;
var lineNum, lineStartIndx;
input.addEventListener("keydown", function(e) {
taHandler(this);
})
input.addEventListener("click", function(e) {
taHandler(this);
})
function taHandler(elem) {
lineNum = getLineNumForSelection(elem);
let caretPos = elem.selectionStart;
lineStartIndx = 0;
for ( i = 0; i < caretPos; i++ ) {
if (elem.value.substr(i,1).match(pattern)) {
lineStartIndx = i + 1
}
}
output.innerHTML = "Selection Start: " + caretPos + " Selection End: " + elem.selectionEnd +
" <br> Line Number: " + lineNum.start +
"<br>Line Start Position: " + lineStartIndx;
}
function getLineNumForSelection(sel) {
return {
'start' : sel.value.substr(0, sel.selectionStart).split(pattern).length,
'end' : sel.value.substr(0,sel.selectionEnd).split(pattern).length
};
}
<textarea id="ta" rows="5" cols="50">
Line one
Line two
Line three
Line four
</textarea>
<hr>
<div id="output"></div>
The method in my copy of the snippet splits the content into lines and uses the .length property instead of a loop so it looks "prettier" but according to time complexity of javascript's .length may not be any faster since there is nothing in the spec that prevents slow browser implementation.
Two side notes about the code, I'd use lineStartIndex, not lineStartIndx without the e. Since lineNum is an array, I'd use lineNumArray or selLineNums or something that is more obvious since variables ending in num are generally integers.
var input = document.getElementById("ta");
var output = document.getElementById("output");
let pattern = /\r?\n|\r/;
var lineNum, lineStartIndx;
input.addEventListener("keydown", function(e) {
taHandler(this);
})
input.addEventListener("click", function(e) {
taHandler(this);
})
function taHandler(elem) {
lineNum = getLineNumForSelection(elem);
let caretPos = elem.selectionStart;
lineStartIndx = 0;
// begin modified code
let lines = elem.value.split(pattern),
lineIndex = 0;
while ( (lineIndex + 1 ) < lineNum.start ) {
lineStartIndx += parseInt( lines[lineIndex].length ) + 1;
lineIndex++;
}
// end modified code
// begin replaced code
for ( i = 0; i < caretPos; i++ ) {
if (elem.value.substr(i,1).match(pattern)) {
lineStartIndx = i + 1
}
}
// end replaced code
output.innerHTML = "Selection Start: " + caretPos + " Selection End: " + elem.selectionEnd +
" <br> Line Number: " + lineNum.start +
"<br>Line Start Position: " + lineStartIndx;
}
function getLineNumForSelection(sel) {
return {
'start' : sel.value.substr(0, sel.selectionStart).split(pattern).length,
'end' : sel.value.substr(0,sel.selectionEnd).split(pattern).length
};
}
<textarea id="ta" rows="5" cols="50">
Line one
Line two
Line three
Line four
</textarea>
<hr>
<div id="output"></div>

output all characters and recognize end of js-function

i have put together the undermentioned script. it wont output the last character of the last source. i am not very well concerned with js and that is why i ask you. can anyone give me a clue?
function jtype(source, step){
var str = source, i = 0, isTag, text, all = "", ii = 0, totallength = 0;
for(ii = 1; ii < step; ii++){
all = all + $("#source-" + ii).val();
}
(function type() {
text = str.slice(0, ++i);
if (text === str) return;
$(".steps").html(all + text);
var char = text.slice(-1);
if( char === '<' ) isTag = true;
if( char === '>' ) isTag = false;
if (isTag) return type();
setTimeout(type, 20);
}());
}
this is an example-data-source:
<input type="hidden" class="sources" id="source-1" value="Gesetzliche Zinsen gebühren kraft Gesetzes. ">
<input type="hidden" class="sources" id="source-2" value="Der gesetzliche Zinssatz beträgt nach <a href="#" onclick="dofadein('#norm330')">§ 1000 Abs 1 ABGB</a> 4 Prozentpunkte pro Jahr. ">
<input type="hidden" class="sources" id="source-3" value="Gesetzliche Zinsen sind insb die sog Verzugszinsen nach <a href="#" onclick="dofadein('#norm430')">§ 1333 ABGB</a>.">
in this example it wont output the dot at the end of #source-3.
when i make an alert(source) right in the function jtype() the dot is NOT missing.
the other thing i want to know is. how can i determine the end of the output. i mean: how can i determine if the cycling is finished and the last character has been output?
thank you very much for your help and please excuse my bad english.
The problem seems to be that when the text === str you return before updating the element so the last character never gets inserted
Change:
if (text === str) return;
$(".steps").html(all + text);
To:
// update element before ending
$(".steps").html(all + text);
if (text === str) return;
DEMO

HTML Input type number Thousand separator

I want to have a thousand separator (e.g. 1,000,000) in my Input field. However, it has to be of type number because I need to be able to adjust its value using "step". Code:
<input type="number" id='myNumber' value="40,000" step='100'>
I tried using Javascript to adjust the value but didn't work. Any help would be appreciated. Thanks!
Using autoNumeric plugin you can made a field as numeric input with different separators.
Include plugin:
<script src="~/Scripts/autoNumeric/autoNumeric.min.js" type="text/javascript"></script>
Html:
<input type="text" id="DEMO" data-a-sign="" data-a-dec="," data-a-sep="." class="form-control">
Script:
<script>
jQuery(function($) {
$('#DEMO').autoNumeric('init');
});
</script>
You can type only number, if you input 100000,99 you will see 100.000,99.
More: https://github.com/autoNumeric/autoNumeric
Check this webdesign.tutsplus.com tutorial
Final result is summarized here (look at direct Codepen playground)
$("#formInput".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) {
return;
}
var $this = $(this);
// Get the value.
var input = $this.val();
input = input.replace(/[\D\s\._\-]+/g, "");
input = input?parseInt(input, 10):0;
$this.val(function () {
return (input === 0)?"":input.toLocaleString("en-US");
});
});
Notes:
toLocaleString() javascript function Actually show thousands separator (example and doc)
run below code in your console to get the idea
(30000000).toLocaleString('en-US',{useGrouping:true})
You can fake this functionality by using a pseudo-element to display the comma version.
div[comma-value]{
position:relative;
}
div[comma-value]:before{
content: attr(comma-value);
position:absolute;
left:0;
}
div[comma-value] input{
color:#fff;
}
A wrapping div is required because inputs can't have pseudo elements.
<div>
<input type="number" id='myNumber' value="40000" step='100'>
</div>
And a little bit of JavaScript to insert commas every third character
myNumber.value = commify(myNumber.value)
myNumber.addEventListener("change", function(){
commify(event.target.value)
})
function commify(value){
var chars = value.split("").reverse()
var withCommas = []
for(var i = 1; i <= chars.length; i++ ){
withCommas.push(chars[i-1])
if(i%3==0 && i != chars.length ){
withCommas.push(",")
}
}
var val = withCommas.reverse().join("")
myNumber.parentNode.setAttribute("comma-value",val)
}
Check out the fiddle
Create a mask input displaying the formatted number. This solution avoids changing the type or the value of the input.
$("input.mask").each((i,ele)=>{
let clone=$(ele).clone(false)
clone.attr("type","text")
let ele1=$(ele)
clone.val(Number(ele1.val()).toLocaleString("en"))
$(ele).after(clone)
$(ele).hide()
clone.mouseenter(()=>{
ele1.show()
clone.hide()
})
setInterval(()=>{
let newv=Number(ele1.val()).toLocaleString("en")
if(clone.val()!=newv){
clone.val(newv)
}
},10)
$(ele).mouseleave(()=>{
$(clone).show()
$(ele1).hide()
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="mask" type="number" value="12345.678"/>
csq recommends using the jQuery autoNumeric plugin. I found it to be very easy and intuitive to use.
My only gripe is that it forces <input type="text"> rather than <input type="number">. This means you lose the funcionality of step, but you gain users of your site being able to use commas in fields.
I guess you could use expected values of less than 1,000 as <input type="number"> and values more than 1,000 as <input type="text">
I've managed to pull it off after modifying https://stackoverflow.com/a/70726755/4829915 because:
The code didn't actually add commas due to not using Number().
It deleted the entire field when the initial value was blank.
No demo was provided.
Not saying the original approach was wrong or not, but I chose to use onfocus and onblur directly on the input itself.
Therefore, here's a revised answer:
Start with <input type="text">. You can still add min, max and step properties.
Add onfocus and onblur handlers to the <input> node:
function use_number(node) {
var empty_val = false;
const value = node.value;
if (node.value == '')
empty_val = true;
node.type = 'number';
if (!empty_val)
node.value = Number(value.replace(/,/g, '')); // or equivalent per locale
}
function use_text(node) {
var empty_val = false;
const value = Number(node.value);
if (node.value == '')
empty_val = true;
node.type = 'text';
if (!empty_val)
node.value = value.toLocaleString('en'); // or other formatting
}
<input type="text" min=0 onfocus="use_number(this)" onblur="use_text(this)">
function addCommas(nStr) { ....
In addition of yovanny's answer I create a Vue component which use this function.
Vue.component("in-n", {
template:
`<input #keyup="keyup" #keypress="isNumber($event)" v-model="text" type="text" />`,
props: ["value"],
data() {
return {
text: ""
}
},
methods: {
addCommas(nStr) {
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? ',' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
},
isNumber: function (evt) {
evt = (evt) ? evt : window.event;
var charCode = (evt.which) ? evt.which : evt.keyCode;
if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) {
evt.preventDefault();;
} else {
return true;
}
},
keyup() {
this.text = this.addCommas(this.text.replace(/,/g, ''));
this.$emit("input", parseInt(this.text.replace(/,/g, '')))
}
}
})
I found a much simpler answer:
Start with <input type="text">. You can still add min, max and step properties.
Add onfocus and onblur handlers to the <input> node:
node.addEventListener('onfocus', () => {
const value = node.value;
node.type = 'number';
node.value = Number(value.replace(/,/g, '')); // or equivalent per locale
});
node.addEventListener('onblur', () => {
const value = node.value;
node.type = 'text';
node.value = value.toLocaleString(); // or other formatting
});
When the user selects the input, it will convert to a regular numeric input with thousands separators removed, but with a normal spinner. When the user blurs the input, it reverts to formatted text.
I add an onkeyup handler that blurs the input when the "enter" key is pressed.
I have updated #CollenZhou answer https://stackoverflow.com/a/67295023/6777672 as on mouse leave, input looses focus which is annoying. I have also added all input type numbers to selector as well as class.
$('input.thousands-separator, input[type="number"]').each((i,ele)=>{
let clone=$(ele).clone(false)
clone.attr('type','text')
let ele1=$(ele)
clone.val(Number(ele1.val()).toLocaleString('en'))
$(ele).after(clone)
$(ele).hide()
clone.mouseenter(()=>{
ele1.show()
clone.hide()
})
setInterval(()=>{
let newv=Number(ele1.val()).toLocaleString('en')
if(clone.val()!=newv){
clone.val(newv)
}
},10)
$(ele).mouseleave((event)=>{
if ($(ele).is(':focus')) {
event.preventDefault();
} else {
$(clone).show()
$(ele1).hide()
}
})
$(ele).focusout(()=>{
$(clone).show()
$(ele1).hide()
})
})
try
function addCommas(nStr)
{
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? ',' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}

Using Regex to limit special characters in a textbox using jquery in ASP.net MVC form

I'm trying to limit to 3 the number of special characters in a text box using JQuery. The special characters can be in any order and can be adjacent to each other or scattered over the length of the text box. I spent the last 24 hours reading almost all relevant posts in stackoverflow and trying the suggestions.
I still haven't come with a suitable regex.
Here is what I have so far at the bottom of my ASP.net mvc form:
<script type="text/javascript">
$(document).ready(function () {
$('input[id$=textbox1]').bind('blur', function () {
var match = /^[.,:;!?€¥£¢$-~#%&*()_]{4,50}$/g.test(this.value);
if (match == true)
alert("Please enter a maximum of 3 special characters.");
});
});
</script>
Below is the list of special characters I'm targeting:
~`!##%^&*()-_:;?€¥£¢$-~{}[]<>/+|=
You where thinking to difficullty. Just count how often the elements are inside the input and throw a warning when the count is over three.
here is an
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
<script src="jquery-1.8.3.min.js"></script>
<script>
var limitchars = '[~`!##%\^&\*\(\)-_:;\?€¥£¢\${}\[]<>/+\|=]'
$(function () {
var teststring = "~`!##%\^&\*\(\)-_:;\?€¥£¢\${}\[]<>/+\|='-:;";
var regex = /[~`'!##%\^&\*\(\)-_:;\?€¥£¢\${}\[\]<>/+\|=]/g
//var test1 = teststring.match(regex);
//debugger;
//alert(teststring.length === test1.length);
$('input').keyup(function () {
var text = this.value;
var match = text.match(regex);
if (match.length > 3) {
alert('invalidI input');
}
});
});
</script>
</head>
<body>
<input type="text" />
</body>
</html>
Don't forget to escape the regular expression (http://www.regular-expressions.info/reference.html ). The g at the end of the regex counts the number of occurrence in string (http://stackoverflow.com/questions/4009756/how-to-count-string-occurrence-in-string )
You can find the number of bad characters by counting the number of matches.
Working example at http://jsbin.com/alidus/1/
$(document).ready(function () {
$('#test').bind('blur', function () {
var charactersToExlude = "~`!##%^&*()-_:;?€¥£¢$-~{}[]<>/+|=";
var badCharacterRegex = "[" + charactersToExlude.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&") + "]";
console.log(badCharacterRegex);
var patt=new RegExp(badCharacterRegex, "g");
var matches = this.value.match(patt);
var numberOfBadCharacters = matches ? matches.length : 0;
if (numberOfBadCharacters >= 3) {
$("#result").text("Please enter a maximum of 3 special characters. (" + numberOfBadCharacters + " bad characters).");
} else {
$("#result").text(numberOfBadCharacters + " bad characters.");
}
});
});
First we escape any bad characters that have meaning to regex. Then crete the pattern, match it, if any matches, count the number of matches.
$(document).ready(function () {
$('#test').bind('blur', function () {
var charactersToExlude = "~`!##%^&*()-_:;?€¥£¢$-~{}[]<>/+|=";
var badCharacterRegex = "[" + charactersToExlude.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&") + "]";
console.log(badCharacterRegex);
var patt=new RegExp(badCharacterRegex, "g");
var matches = this.value.match(patt);
var numberOfBadCharacters = matches ? matches.length : 0;
if (numberOfBadCharacters >= 3) {
$("#result").text("Please enter a maximum of 3 special characters. (" + numberOfBadCharacters + " bad characters).");
} else {
$("#result").text(numberOfBadCharacters + " bad characters.");
}
});
});

Insert hyphens in JavaScript

What is the easiest way to insert hyphens in JavaScript?
I have a phone number eg. 1234567890
While displaying in the front-end, I have to display it as 123-456-7890 using JavaScript.
What is the simplest way to achieve this?
Quickest way would be with some regex:
Where n is the number
n.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3");
Example: http://jsfiddle.net/jasongennaro/yXD7g/
var n = "1234567899";
console.log(n.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3"));
Given this kind of input, an other way would be:
var phone = "1234567890";
phone = phone.replace(/(\d{3})(\d{3})(\d+)/, '$1-$2-$3');
Of course this does not work if your input changes.
You could use the substr-function to achieve this, assumed that the hyphens are always inserted on the same position:
var hypString = phonestr.substr(0,3) + '-' + phonestr.substr(3, 6) + '-' + phonestr.substr(6);
If you want to mask your input in that way then you can do something like below so that when input is being given by the user it automatically formats it to the required format.
function transform(){
let ele = document.getElementById("phno");
ele.value = ele.value.replace(/^(\d{3})$/g, '$1-')
.replace(/^(\d{3}\-\d{3})$/g, '$1-');
}
<input
type="text"
onkeyup="transform()"
id="phno"
placeholder="123-123-4444"
maxlength="12"
/>
You can create a javascript function to format the phone number. Something like this:
function formatPhoneStr(o)
{
var strPhone = o.value;
if( (strPhone != null) && (strPhone.length > 0) && (strPhone.indexOf('(') == -1))
{
if (strPhone.length == 10)
{
strPhone = '(' + strPhone.substr(0,3) + ') ' + strPhone.substr(3,3) + '-' + strPhone.substr(6,4);
}
else if (strPhone.length > 10)
{
strPhone = '(' + strPhone.substr(0,3) + ') ' + strPhone.substr(3,3) + '-' + strPhone.substr(6,4) + ' x' + strPhone.substr(10);
}
o.value = strPhone;
}
}
Another alternative that I believe is the cleanest one: the slice string method.
formattedPhone = phone.slice(0,3) + '-' + phone.slice(3, 6) + '-' phone.slice(6)
The first parameter is the start position in the string, the second is the end position. As you can see above, no parameters it goes till the end of the string. A nice feature is that, like Python, negative positions count from the end of the string. This can make your code somewhat more robust:
formattedPhone = phone.slice(0,3) + '-' + phone.slice(3, -4) + '-' + phone.slice(-4)
Even if you got a phone with 9 or 11 digits it will look nice.
try this...
<input required type="tel" maxlength="12" onKeypress="addDashesPhone(this)" name="Phone" id="Phone">
function addDashesPhone(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;
}
For react just use a ref like this example:
Here I just replace the value of the element and include hyphens onBlur
Logic part:
const ref = React.useRef(null)
const blurHandle = () => {
ref.current.value = ref.current.value.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3")
};
declarative render part:
<Input
ref={phoneInput}
onFocus={focusHandler}
onBlur={blurHandle}
type="tel"
placeholder="###-###-####"
name="from_phoneNumber"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
/>
If your Input is a sepparated styled component using an input JSX element inside remember pass the ref to the children element using a foward ref
const Input = React.forwardRef((props, ref) => (
<input type="tel" ref={ref} ........ />
))
If you're using the ASP.NET client library they have a great String.format method that provides locale formats and all kinds of fancy stuff. The method is called as you'd expect if you're familiar with .NET:
<script type="text/javascript">
var myPhone = String.format("{0}-{1}-{2}", firstThree, secondThree, lastFour);
</script>
If you're not using ASP.NET library, I'm sure you could get the rudimentary formatting done in your own implementation - obviously this would be sans localization and you should throw some error handling/checking in the mix:
function format(str, arr){
for(var i = 0; i < arr.length; i++) {
var r = new RegExp("\\{" + i + "\\}", "g");
str = str.replace(r,arr[i]);
}
return str;
}
alert(format("{0}-{1}-{2}", [123,456,7890]));
here's my solution just in case it helps someone:
validatePhone: function (e) {
var number = this.$el.find('#phoneNumberField').val().replace(/-/g, '');
if(number.length > 10) {
e.preventDefault();
}
if(number.length < 3) {
number = number; // just for legibility
} else if(number.length < 7) {
number = number.substring(0,3) +
'-' +
number.substring(3,6)
} else if(number.length > 6) {
number = number.substring(0,3) +
'-' +
number.substring(3,6) +
'-' +
number.substring(6,10);
}
this.$el.find('#phoneNumberField').val(number);
}

Categories

Resources