Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue js input mask

Tags:

vue.js

I want to have an input mask on a specific input where it parses the user input into a human readable US phone number.

For example

User enter: 1231231234 User sees: (123)-123-1234

What I have done so far is, i made a watch method like the follow

switch (this.form.values.primary_phone.length) {
        case 3:
          return this.form.values.primary_phone = this.form.values.primary_phone.replace(/^([0-9]{3})$/, '($1)');
        case 6:
          return this.form.values.primary_phone = this.form.values.primary_phone.replace(/^([0-9]{3})([0-9]{3})$/, '($1)-$2');
        case 10:
          return this.form.values.primary_phone = this.form.values.primary_phone.replace(/^([0-9]{3})([0-9]{3})([0-9]{4})$/, '($1)-$2-$3');
      }

Now this updates the value only when I focus out of from input. Is there a way I can do it to update while the input is still at focus?

like image 458
Steve Avatar asked Feb 03 '16 10:02

Steve


2 Answers

I would recommend you to do a directive wrapping the jquery plugin input mask.

There is an example:

JavaScript

Vue.directive('input-mask', {
  params: ['mask'],

  bind: function() {
    $(this.el).inputmask({
      mask: this.params.mask
    });

  },
});

var vm = new Vue({
  el: 'body',
  data: {
    value: '',
  }
});

HTML

<!-- Import Styles/Scripts from the plugin and do not forget the jQuery library -->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/css/jasny-bootstrap.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/js/jasny-bootstrap.min.js"></script>

<p>Selected: {{value}}</p>
<input v-model="value" v-input-mask mask="(999) 999-9999">

If you need there is a JSBin to show you how it works.

like image 184
Gustavo Bissolli Avatar answered Nov 07 '22 11:11

Gustavo Bissolli


For that you must define a custom filter on your input. Something like this

Vue.filter('mask', function (value) {
  if (value.length <= 3){
    var re = new RegExp("^([0-9]{"+value.length+"})$");
    return value = value.replace(re, '($1)');
  } 
  if (value.length > 3 && value.length <= 6){
    var re = new RegExp("^([0-9]{3})([0-9]{"+ (value.length - 3)+"})$");
    return value = value.replace(re, '($1)-$2');
  }
  if (value.length > 6 && value.length <= 10){
    var re = new RegExp("^([0-9]{3})([0-9]{3})([0-9]{"+(value.length-6)+"})$");
    return value = value.replace(re, '($1)-$2-$3');
  }
    return value;
})

Then apply that to your template. I made a jsfiddle (based on the markdown example from Vue page)

Notice that you still have to handle values of length greater than 10, and I also changed your function to use if statements instead of switch-case

like image 21
Yerko Palma Avatar answered Nov 07 '22 09:11

Yerko Palma