Vueで電話番号の有効性チェックと自動フォーマットが出来る処理


作ったもの

電話番号の有効性をチェックし、有効な場合ハイフン「−」を自動で入力するものを作りました。

  • 固定電話
    固定電話に合わせたハイフンが入力されます。

  • 携帯電話
    携帯電話に合わせたハイフンが入力されます。

  • ありえない電話番号
    ありえない番号の場合、電話番号と同じ桁数の数値を入力しても、エラーとなります。

環境

Vue

どう作ったか

libphonenumber-jsを使いました。
https://github.com/catamphetamine/libphonenumber-js/#cdn
こちらの記事を参考にしました。
https://qiita.com/the_red/items/fcedd5033530b7ff7ee7

コード

読み込ませる

今回はCDNで読み込ませたため、index.htmlに読み込ませました。

<script src="https://cdnjs.cloudflare.com/ajax/libs/libphonenumber-js/1.7.25/libphonenumber-js.min.js"></script>

(参考)https://github.com/catamphetamine/libphonenumber-js/#cdn

テンプレート側

<!-- 入力箇所 -->
<input class="form-control" v-model="phoneNumber" placeholder="例)00000000000" maxlength="13" type="tel" />
<!-- エラーメッセージ -->
<p v-if="isShowPhoneNumberError()" style="color: red;">
  入力が正しくありません
</p>
解説

isShowPhoneNumberError()で常にエラー監視をしています。

script側

import { AsYouType, parsePhoneNumberFromString } from 'libphonenumber-js'
  export default {
    data () {
      return {
        phoneNumber: '',
      }
    },
    methods: {
      isShowPhoneNumberError: function () {
        //======
        // 関数定義
        //======
        // 電話番号の有効性チェック関数
        const phoneNumberNoneProblem = function (val) {
          if (val) {
            // +81は日本の電話番号を示す
            const parsedPhoneNumber = parsePhoneNumberFromString('+81' + val, 'JA');
            return parsedPhoneNumber? parsedPhoneNumber.isValid() : false;
          } else {
            return false;
          }
        }
        // 整形する関数
        const formatTel = function (val) {
          return new AsYouType('JP').input(val);
        }
        // ハイフン有無を確認する関数
        const isHaihun = RegExp('-');

        //======
        // 関数呼び出し
        //======
        // 番号の有効性チェック
        if (!phoneNumberNoneProblem(this.phoneNumber)) {
          return true;
        }

        // 有効な番号の場合整形
        const formatedPhoneNumber = formatTel(this.phoneNumber);

        // 整形後にハイフンが入ってない番号 = 存在し得ない番号
        if (!isHaihun.test(formatedPhoneNumber)) {
          return true;
        }

        // 整形後の番号を代入
        this.phoneNumber = formatedPhoneNumber;
      },
    },
 }
解説

順に解説します。

①電話番号を解析し有効性をチェック

呼出元

        // 有効な番号ではない場合
        if (!phoneNumberNoneProblem(this.phoneNumber)) {
          return true;
        }

処理

        // 電話番号の有効性チェック関数
        // +81は日本の電話番号を示す
        const phoneNumberNoneProblem = function (val) {
          if (val) {
            // +81は日本の電話番号を示す
            const parsedPhoneNumber = parsePhoneNumberFromString('+81' + val, 'JA');
            return parsedPhoneNumber? parsedPhoneNumber.isValid() : false;
          } else {
            return false;
          }
        }

parsePhoneNumberFromStringメソッドでPhoneNumberクラスのインスタンスを生成。

PhoneNumberクラスのインスタンスを返します。電話番号を解析できなかった場合はundefindedです。たとえば、文字列に電話番号が含まれていない場合や、電話番号が存在しない国の呼び出しコードで始まっている場合などです。 開発者が電話番号を解析できなかった正確な理由を知りたい場合、parsePhoneNumber()関数を使用して正確なエラーをスローできます。
(参考)https://github.com/catamphetamine/libphonenumber-js/#parsephonenumberfromstringstring-defaultcountry

PhoneNumberクラスのisValidメソッドで電話番号が有効か確認。

電話番号が「有効」かどうかを確認します。最初に電話番号の長さをチェックしてから、利用可能なすべての正規表現に対して電話番号の桁をチェックします。 デフォルトでは、ライブラリはサイズが75キロバイトの「最小」メタデータを使用しますが、厳密な検証正規表現を含まないため、検証規則は厳しくなりません(各国ごとに、長さチェックなどの非常に基本的な検証が含まれています)。
(参考)https://github.com/catamphetamine/libphonenumber-js/#isvalid

②有効な番号の場合整形(ハイフンの入力)

呼出元

        // 有効な番号の場合整形
        let tempNumber = formatTel(this.phoneNumber);

処理

        // 整形する関数
        const formatTel = function (val) {
          return new AsYouType('JP').input(val);
        }

AsYouTypeクラスを生成し、inputメソッドで整形します。

(参考)https://github.com/catamphetamine/libphonenumber-js/#class-asyoutypedefaultcountry

③整形後の電話番号チェック

呼出元

        // 整形後にハイフンが入ってない番号 = 存在し得ない番号
        if (!isHaihun.test(tempNumber)) {
          return true;
        }

処理

        // ハイフン有無を確認する関数
        const isHaihun = RegExp('-');

整形後にハイフンが入らない番号がいくつかあり、今回それらは無効な番号とみなす事にしました。
(参考)http://www.tohoho-web.com/js/regexp.htm

最後に

皆さんのご参考になれば幸いです。
(そもそもVueでゴリゴリvalidationを書く事は少ないとは思いますが)
また、より良い方法があればぜひコメント下さい!