Reputation: 389
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.
Upvotes: 8
Views: 40811
Reputation: 49
For those looking not to use another v-model, you can use $input with $event:
<input
ref="input"
type="text"
v-model="form.name"
@input="formatPhoneNumber($event)" />
then in script setup:
const form = useForm({
name: '',});
const input = ref();
const formatPhoneNumber = (event) => {
const number = event.target.value.replace(/\D/g, '');
const main = number.match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
event.target.value = !main[2]
? main[1]
: `(${main[1]}) ${main[2]}${main[3] ? '-' + main[3] : ''}`
input.value = event.target.value;
};
One v-model for a form
Upvotes: 0
Reputation: 91
let phone_format = function (number) {
var x = number.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
if (number.length < 11) {
number = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3]:'');
}
return number;
};
You can use above fnc.
I use like that.
<div class="position-relative">
<input v-model="aa" style="opacity:0" />
<div v-html="phone_format(aa)" style="position:absolute;top:0;left:0;width:100%;pointer-events: none;"></div>
</div>
Upvotes: 0
Reputation: 6788
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>
Upvotes: 1
Reputation: 6932
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://v2.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>
Upvotes: 19
Reputation: 343
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>
Upvotes: 2
Reputation: 619
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.
Upvotes: 1
Reputation: 1090
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] : "");
}
}
Upvotes: 0
Reputation: 1046
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.
Upvotes: 0