'Vue.js aplying phone number format
I'm new to Vue.js and was trying to find a way how to format a phone number in an input field to the desired format. I was able to find an answer here on stackoverflow written in plain javascript but I dont know how to use the regex in Vue.
Solution in javascript
document.getElementById('phone').addEventListener('input', function (e) {
var x = e.target.value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
e.target.value = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3] : '');
});
So my question is how to apply it on this input div? So it allows the user to type only numbers and as he is typing the number is showing in the desired format.
<div contentEditable="true" class="inputDiv"></div>
Example what I would like to achive using vue.js.
document.getElementById('phone').addEventListener('input', function (e) {
var x = e.target.value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
e.target.value = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3] : '');
});
<input type="text" id="phone" placeholder="(555) 555-5555"/>
I was trying to look for an answer which is probably pretty stright forward but since I'm new to Vue I was unable to find anything which would help me to make it work.
Solution 1:[1]
You probably need to have a look at how vue works and have some walk through to get a better understanding.
Their documentation is awesome, you can start from there - https://vuejs.org/v2/guide/
For the question, here is a way you can utilise the framework
new Vue({
el: "#app",
data: {
value: ''
},
methods: {
acceptNumber() {
var x = this.value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
this.value = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3] : '');
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Phone number</h2>
<input v-model="value" type="text" @input="acceptNumber">
</div>
Solution 2:[2]
Introducing Vue-The-Mask.
npm install vue-the-mask
In your component
<template>
<input v-mask="['(###) ###-####']"/>
</template>
<script>
import {mask} from 'vue-the-mask'
export default{
name: "myComponent",
directives:{mask}
}
</script>
Solution 3:[3]
Usually in Vue you handle forms with v-model. In a typical form, you would have maybe a phoneNumber
variable in your component and would bind it to the input with v-model
:
<template>
<input name="phone" v-model="phoneNumber" />
</template>
<script>
export default new Vue ({
data() {
return {
phoneNumber: '',
}
}
})
</script>
The problem is that v-model
does not allow you to change the value dynamically as the user types, so that doesn't work for you.
Instead of binding with v-model
, however, you can still provide the value with v-bind
and react to user input with v-on
. The following snippet would always transform whatever the user writes to mayus:
<template>
<input name="phone" :value="phoneNumber" @input="handleUserInput" />
</template>
<script>
export default new Vue ({
data() {
return {
phoneNumber: '',
}
},
methods: {
handleUserInput(input) {
this.value = input.toUpperCase();
}
}
})
</script>
Applying format to the phone number is just a bit more complicated that toUpperCase()
, but the idea is the same:
<template>
<input name="phone" :value="phoneNumber" @input="handleUserInput" />
</template>
<script>
export default new Vue ({
data() {
return {
phoneNumber: '',
}
},
methods: {
handleUserInput(input) {
var replacedInput = e.target.value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
this.value = !replacedInput[2] ? replacedInput[1] : '(' + replacedInput[1] + ') ' + replacedInput[2] + (replacedInput[3] ? '-' + replacedInput[3] : '');
}
}
})
</script>
Solution 4:[4]
I would recommend using some of the open source Vue components for telephone input like:
https://github.com/LouisMazel/vue-phone-number-input
or
https://www.npmjs.com/package/vue-tel-input
They are really easy to use and and it will save you a lot as you would waste making your own phone input component.
Solution 5:[5]
Slight modification to @Satyam Pathak code, to support dynamically passing in property names.
<script>
export default new Vue ({
data() {
return {
objectName: {},
}
}
})
</script>
methods:{
formatPhoneNumber(propertyName) {
var x = this.objectName[propertyName]
.replace(/\D/g, "")
.match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
this.objectName[propertyName] = !x[2]
? x[1] : "(" + x[1] + ") " + x[2] + (x[3] ? "-" + x[3] : "");
}
}
Solution 6:[6]
My 5 cents. Imagine you have a phone model, that you wish to apply the formatting to.
data() {
return {
phone_number: null,
};
}
Your template would look something like this:
<template>
<div>
<input
type="tel"
placeholder="(123) 456-7890"
class="form-control"
id="input-phone"
v-model="phone_number"
maxlength="16"
@input="enforcePhoneFormat()"
/>
</div>
</template>
So, on input, you call the enforcePhoneFormat() method, which uses regex and transforms the input, to a following format - (123) 345-6789
.
methods: {
enforcePhoneFormat() {
let x = this.phone_number
.replace(/\D/g, "")
.match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
this.phone_number = !x[2]
? x[1]
: "(" + x[1] + ") " + x[2] + (x[3] ? "-" + x[3] : "");
}
}
To change the preferred format, you would have to change the regex, of course.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Richard KeMiKaL GeNeRaL Denton |
Solution 2 | digitalextremist |
Solution 3 | |
Solution 4 | N. Djokic |
Solution 5 | Dwain Browne |
Solution 6 | Ognjen |