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);
}
Related
Is there a function that splits the the given string into 2 evenly and place half of each to different textboxes?
I have tried var.split and var.slice
<script>
function display()
{
var myStr = document.getElementbyId("reqnum").value;
var strArray = myStr.split(" ");
// Display array values on page
for(var i = 0; i < strArray.length; i++){
document.write("<p>" + strArray[i] + "</p>");
}
}
the expected should split the no. evenly and would display an error if the numbers are odd.
You can check the length of your input string. If it is odd then display an error.
<input type="text" id="reqnum" >
<input type="button" value="Display" onclick="display()">
<script>
function display()
{
var myStr = document.getElementById("reqnum").value;
if( !myStr || myStr.length % 2 == 1){
document.write("<p>Invalid input</p>");
}else{
var a = parseInt(myStr.substring(0, myStr.length/2));
var b = parseInt(myStr.substring(myStr.length/2, myStr.length));
document.write("<p>" + a + "</p>");
document.write("<p>" + b + "</p>");
document.write("<p> Result after multiplication : " + (a*b) + "</p>");
}
}
</script>
you can convert the numbers to string and then you can do the following.
var num = "1234567890"
var num1
var num2
if (num.length % 2 == 0) {
num1 = num.slice(0, (num.length / 2))
num2 = num.slice((num.length / 2))
} else {
console.log("Number contains odd number of digits")
}
console.log("Num1 " + num1 + " and Num2 " + num2)
use the Slice method, documentation is here.
For your slicing in half:
let half1, half2;
if( myStr.length % 2 == 0 ){
half1 = myStr.slice(0, (myStr.length / 2));
half2 = myStr.slice( (myStr.length / 2), myStr.length );
} else {
// error code
}
function splitToEqual(num){
num = num.toString()
return [num.substring(0, num.length / 2), num.substring(num.length / 2, num.length)]
}
console.log(splitToEqual(1234567890))
Have you tried using slice and length String methods?
Ie.
const string = '1234567890';
const length = string.length;
const res1 = string.slice(0,length/2);
const res2 = string.slice(length/2);
console.log(res1,res2);
Based on your request, I created the following piece of code :-)
Hope it helps.
var inputBox, warning, fBox, sBox;
function inputBoxChanged(e) {
var text = e.currentTarget.value;
if (text.length % 2 != 0) {
warning.innerText = "Value needs to be even sized";
fBox.value = "";
sBox.value = "";
} else {
warning.innerText = "";
var splitPos = text.length / 2;
fBox.value = text.slice(0, splitPos);
sBox.value = text.slice(splitPos, text.length);
}
}
document.addEventListener("DOMContentLoaded", function (e) {
inputBox = document.getElementById("input");
warning = document.getElementById("warning");
fBox = document.getElementById("first");
sBox = document.getElementById("second");
inputBox.addEventListener("change", inputBoxChanged);
});
<html>
<body>
<input id="input" type="text"/>
<span id="warning"></span>
<hr/>
<input id="first" type="text" readonly/>
<input id="second" type="text"readonly/>
</body>
</html>
Use substring() function as
var substring=string.substring(strating_index,end_index);
index will start from 0
var str="1234567890"
var substr=str.substring(0,str.length/2);
var substr2=str.substring(strlength/2,strlength);
$("#ID1").val(substr);
$('#ID2').val(substr2);
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>
Using Angularjs 1.xx
var transformedInput = text.replace(/[^0-9.]/g, '')
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
if(transformedInput!="")
transformedInput="$"+transformedInput;
Input = 123456789, Output = $123,456,789
But I need the following output:
Input = 20.56, Output = $20.5600
Input = 20, Output = $20.0000
Input = 20.567, Output = $20.5670
Without using filters.
Use parseFloat to convert string to float then use toFixed(4)
var text = "20";
var transformedInput = text.replace(/[^0-9.]/g, '')
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
if(transformedInput!="")
transformedInput="$"+parseFloat(transformedInput).toFixed(4);
console.log(transformedInput);
Use Angular currency filter
<span data-ng-bind="'123456789'| currency : '$' : 4 "></span>
Hope this implementation will work for you.
var msg = document.getElementById('myInputBox'),
btn = document.getElementById('formatButton');
btn.addEventListener('click', getFormattedData);
function checkNumeric(str) {
return str.replace(/\,|\$/g, '');
}
Number.prototype.format = function() {
return this.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
};
function getFormattedData() {
var num = checkNumeric(msg.value),
val = (Number(num).toFixed(4)).toString().split('.'),
decimal = '';
if (num.indexOf('.') > -1) {
decimal = '.' + val[1];
}
msg.value = '$' + Number(val[0]).format() + decimal;
}
<input type="text" id='myInputBox' value="" />
<input type="button" id="formatButton" value='Get Output'>
You've got the built-in Number#toLocaleString which is exactly meant for this :
var nbs = [20.56, 20, 20.567];
var $s = nbs.map(n =>
n.toLocaleString('en-US', {
style: 'currency', // that's money
currency: 'USD', // that's $
// the difficult (?) part
// we need to get the length of digits before "."
minimumSignificantDigits: ((~~n) + '').length + 4
})
);
console.log($s);
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" />
I am trying to insert additional characters in a specific string.
function sample(x) {
if (x.value.length > 2 && x.value.length < 5) {
var first = x.value.substring(0, 2) + "'";
var second = x.value.substring(2, x.value.length) + "''";
x.value = first + "" + second ; }
}
<input id="txt" type="text" placeholder="onkeypress" onkeypress="sample(this)" value="" /><br />
<input id="txt1" type="text" placeholder="onchange" onchange="sample(this)" value="" />
By using onchange attribute in htmlinput, the code runs perfectly. But can this also run with onkeypress attribute? If value of inputs is 1006, the result should be 10'06''. Help. Thanks.
Try this:
You need to replace the quotes('/") before manipulating the string. Also use keyup event. Refer this to understand the purpose of each events. onkeyup is fired when the key is released
function sample(x) {
x.value = x.value.replace(/[\'\"]/g, '');
if (x.value.length > 2 && x.value.length < 5) {
var first = x.value.substring(0, 2) + "'";
var second = x.value.substring(2, x.value.length) + "''";
x.value = first + "" + second;
}
}
<input id="txt" type="text" placeholder="onkeypress" onkeyup="sample(this)" value="" />
<br/>
<input id="txt1" type="text" placeholder="onchange" onchange="sample(this)" value="" />
I see this was already correctly answered, but here's my take.
Adding a timeout to formatting function would give user a chance to enter 4 characters before formatting kicks in and potentially confuses user:
function sample(x) {
setTimeout(function() {
if (x.value.length > 2 && x.value.length < 5) {
var first = x.value.substring(0, 2) + "'";
var second = x.value.substring(2, x.value.length) + "\"";
x.value = first + second;
}
}, 1500); // this is the timeout value in milliseconds
}
Please see this CodePen for a working example:
http://codepen.io/Tiketti/pen/YyVRwb?editors=101
The difference between onchange and onkeypress is,
onchange detects the change in length and values when control is released from element
onkeypress detects the change in length on keypress but change in value on another key press. The length starts from 0 it means if I enter 4567, while typing 7, the length is 0,1,2,3 but value is 456 even the 7 is present in input. But when you press 8 it shows 4567.
You can see that happening here http://codepen.io/anon/pen/XmRydE
function sample(x) {
console.log(x.value);
console.log(x.value.length);
if (x.value.length > 2 && x.value.length < 5) {
var first = x.value.substring(0, 2) + "'";
var second = x.value.substring(2, x.value.length) + "''";
x.value = first + "" + second ; }
}
function sampleKeyPress(x) {
console.log(x.value);
console.log(x.value.length);
if (x.value.length >= 4 && x.value.length < 5) {
var first = x.value.substring(0, 2) + "'";
var second = x.value.substring(2, x.value.length) + "''";
x.value = first + "" + second ; }
}
<input id="txt" type="text" placeholder="onkeypress" onkeypress="sampleKeyPress(this)" value="" /><br />
<input id="txt1" type="text" placeholder="onchange" onchange="sample(this)" value="" />