deekeh
deekeh

Reputation: 762

How to format phone number in Japanese format with Vue2 and v-mask

I have a text box in Vue 2 application and I am using the v-mask library to format phone numbers as the user types them.

The problem

I want them to be formatted as per Japanese phone number format which is like this: (+81) ### #### ####

After the country code (+81), the first part of the phone is the area code. This code can be from 1 to 3 digits long. So, when the user types in the number, the program should assume that the area code is 1-digit long as per the available information. When the user exhausts the allowed number of digits in a single-digit area code phone number, the program should take additional digit and rearrange the spaces in such a way that it will become a phone number of 2 digits long area code. Similarly, on addition of another digit by the user, it should rearrange again as per 3-digit area code phone number.

What I have tried yet

  1. I have tried giving it the optional value ? character like (+81) #?#?# #### #### but it adds unwanted spaces after the first digit and does not consider it as we want it. Sample here: https://codesandbox.io/p/sandbox/v-mask-demo-forked-7r6rd4 (this sandbox can be run to test and forked to edit and debug).
  2. I have tried giving the v-mask as a method which changes the mask string as per the length of the user input, but there is a known-issue in the v-mask library which keeps emitting values when a function (or computed property) is given to it. The issue is logged here: https://github.com/probil/v-mask/issues/511

References

I have referred the official documentation of v-mask at https://www.npmjs.com/package/v-mask to build my masking logic.

Upvotes: 0

Views: 45

Answers (1)

Umair Sarfraz
Umair Sarfraz

Reputation: 6069

This can be achieved by a custom watcher and a method:

  computed: {
    formattedPhoneNumber: {
      get() {
        return this.formatPhoneNumber(this.models.phoneNumber);
      },
      set(value) {
        this.models.phoneNumber = value;
      },
    },
  },
  methods: {
    formatPhoneNumber(number) {
      if (!number) {
        return number;
      }

      if (number.startsWith("(+81)")) {
        number = number.slice(5);
      }

      let digits = number.replace(/\D/g, "");

      // Limit to a maximum of 11 digits
      digits = digits.slice(0, 11);

      if (digits.length <= 9) {
        // Format as # #### ####
        return `(+81) ${digits.slice(0, 1)} ${digits.slice(1, 5)} ${digits.slice(5)}`.trimEnd();
      } else if (digits.length === 10) {
        // Format as ## #### ####
        return `(+81) ${digits.slice(0, 2)} ${digits.slice(2, 6)} ${digits.slice(6)}`.trimEnd();
      } else if (digits.length === 11) {
        // Format as ### #### ####
        return `(+81) ${digits.slice(0, 3)} ${digits.slice(3, 7)} ${digits.slice(7)}`.trimEnd();
      } else {
        return digits;
      }
    },
  },
 <div class="six columns">
     <input
       class="u-full-width"
       id="phone-number-ex"
       type="text"
       placeholder="(+81) 000 0000 0000"
       v-model="formattedPhoneNumber"
     />
</div>

Upvotes: 0

Related Questions