プログラミング

JavaScript で電話番号入力フォームを自動整形する方法

電話番号の自動整形

よくある下記のような入力欄で電話番号が全角で入力された場合に自動で半角に変換してくれるフォームを、ピュアな JavaScript を使って実装します。

今回は送信処理まではやらないので、「送信する」ボタンはただ置いてるだけです。悪しからず。。

ソースコード

ほんとはスタイルは当てなくていっかって思ったのですが、input タグの focus 時にデフォルトでボワっとでる青枠が許せなくて結局当てちゃいました(笑。

あのボワっと青枠、結構有名なサイトとかでもデフォルトのままになってること多いの、個人的に謎なんだよな。

個人の好みなだけなんですけど…、そんなわけで一応CSSも載せておきます。

<form action="" method="POST" class="telform">
  <h2 class="form-title">電話番号を入力してね</h2>
  <input type="tel" name="tel" id="tel">
  <input type="submit" value="送信する">
</form>
//  1. 電話番号入力フォームの要素を取得
const telInput = document.getElementById('tel');  

// 2. イベント設定
telInput.addEventListener('blur', () => { 

// 3. 入力された値を取得
let telInputValue = telInput.value;

// 4. 全角ハイフンを半角ハイフンに変換
telInputValue = telInputValue.replace(/[‐-―ー]/g, '-');

// 5. 全角数字を半角数字に変換
const replacedValue = telInputValue.replace(/[0-9]/g,
    function(str){ 
        return String.fromCharCode(str.charCodeAt(0) - 0xFEE0)
    }); 
    
// 6. 変換後の値を表示する
telInput.value = replacedValue;
}, false);
.telform {
  width: 500px;
  margin: auto;
  margin-top: 60px;
}

.form-title {
  color: #545454;
  margin-bottom: 8px;
}

#tel {
  width: 250px;
  height: 15px;
  border-radius: 4px;
  border: 1px solid #ccc;
  outline: none;
  padding: 8px;

  &:focus {
    border: 1px solid royalblue;
  }
}

input[type="submit"] {
  background-color: #545454;
  border: 1px solid #545454;
  border-radius: 4px;
  color: #fff;
  padding: 4px 8px;
  margin-left: 4px;
  cursor: pointer;
}

実装方法

今回はユーザーがフォームに全角で「080−3333−4444」と入力したケースを想定し、処理の流れを追っていきたいと思います。

1. 対象要素を取得

getElementById() メソッドを使って要素を取得します。

//  1. 電話番号入力フォームの要素を取得
const telInput = document.getElementById('tel');  

今回のフォームは id="tel" が付与されているので、その部分を取得します。

2. イベントの設定

1.で取得した telInput 要素に対して、ユーザーがフォームに電話番号を入力し、インプット要素がフォーカスを失った時に全角→半角に自動変換するようにしたいので、 blur イベントを設定します。

telInput.addEventListener('blur', () => { }, false);

ちなみに今回は使っていないですが、 blur イベントの反対で、要素がフォーカスを受け取ったときに発生するのが focus イベントです。

また上記では blur イベントを使用していますが、change イベントでも同じことができます。

blur イベントと change イベントの違い

blur イベントは、要素がフォーカスを失った際に必ず実行されるのに対し、change イベントは要素の値が変更された時のみ実行されます。

どっちがいいんだろうね…好みかな(違う?誰かわかる人教えて)

3. 入力された値を取得

telInput 要素の value プロパティにアクセスして、入力された値(「080−3333−4444」)を取得します。

// 3. 入力された値を取得
let telInputValue = telInput.value;

ここ、 let で変数宣言してる理由なんですが、

変数 telInputValue は後述の4.で再代入を行うので、ここを const で変数宣言すると「 Assignment to constant variable. 」って怒られます。。

JavaScriptの変数宣言

const →再宣言× 再代入×
let   →再宣言× 再代入◯
var  →再宣言◯ 再代入◯

const は定数なので再代入できないのに、代入しようとしちゃってるよ〜ってことですね。

じゃあ var でよくね?ってなりますが、var はスコープが広くなりがちで事故が起きやすいので、変数宣言は cosntlet で行うのが主流だそうです。

再代入を行わずに const で新たに変数宣言してもいいんですが、そこらへんは好みでしょうかね?あんまり変数増えるとわかりづらいかと思って let で宣言して変数を使い回すようにしました。

4. 全角ハイフンを半角ハイフンに置換

replace() メソッドを使って全角ハイフンを半角ハイフンに置換します。

// 4. 全角ハイフンを半角ハイフンに変換
telInputValue = telInputValue.replace(/[‐-―ー]/g, '-');

今回の場合は、置換対象の文字列パターンの最後に g オプションが付いているので「 replace(/[‐-―ー]/g, ‘-‘) 」は、文字列の中の全ての全角ハイフンを半角ハイフンに置き換える、という意味になります。

replace() メソッドの使い方

replace(‘置換対象の文字列パターン’,  ‘置換文字’)

てか、[‐-―ー]て??

全角ハイフン多くない??!

どうでもいいけど気になったので、調べてみた……

ハイフンっぽい文字たち

「 ‐ 」→ Unicode U+2010  半角ハイフンとは別の普通のハイフン

「 - 」→ Unicode U+FF0D  全角ハイフンマイナス

「 ― 」→ Unicode U+2015  クォーテーションダッシュ

「 ー 」→ Unicode U+30FC  ひらがなカタカナの長音記号

どれもハイフンっぽいけど、Unicode的には違う文字コードらしい…

他にもハイフンっぽい文字コードってあるらしいんですが、調べた限りではこれくらいを置換対象にしてればOKな感じでした。

5. 全角数字を半角数字に変換

上記と同様、 replace() メソッドを使います。

// 5. 全角数字を半角数字に変換
const replacedValue = telInputValue.replace(/[0-9]/g,
    function(str){ 
        return String.fromCharCode(str.charCodeAt(0) - 0xFEE0)
    }); 

置換対象は [0-9] なので、全角の0〜9までの数字を、半角数字に変換します。

function(str) ~ の処理はお決まりの書き方のようで、charCodeAt() メソッドで入力された文字の文字コードを取得し、それに – 0xFEE0 とすることで全角→半角に変換します。

6. 変換後の値を表示する

最後に変換後の値( replacedValue )を最初に宣言したの変数 telInputvalue プロパティに代入してあげれば…

// 6. 変換後の値を表示する
telInput.value = replacedValue;

フォームからフォーカスを外したと同時に、全角数字・ハイフンが全て半角に自動変換されました!

まとめ

いかがだったでしょうか?

他にもっと良い書き方はあると思うので、あくまでも一例としてご参考いただければ幸いです。

フォーム入力では正規表現も避けては通れないので、それはおいおい別の記事にしたいと思っています。

どうでもいいけど今回の記事のアイキャッチ、今の若い世代が見ても電話って分からないかもだよね?汗。いや、流石にわかるか…?

では今回はこの辺で。

ここまでお読みいただき、ありがとうございました!