【Rails6】新・JavaScriptによる「入力フォームの内容のリアルタイムチェック機能」の実装例


以前、【Rails6】JavaScriptによる「入力フォームの内容のリアルタイムチェック機能」の実装例という記事で、入力フォームのリアルタイムチェック機能の実装方法を紹介しましたが、この実装方法には以下の問題がありました。

  • エラーメッセージのタグをhiddenで隠しているので、フォームの中に不自然な空白がある
  • 複数のタイプのエラーメッセージを表示しようとすると空白がさらに大きくなってしまう

今回はこれを改善し、しかもパワーアップしました。
前回と同様にjQueryのようなライブラリは使用せず、そのままのJavaScriptで実装したことが今回もポイントです。

実行環境

Rails 6.0.3.6

動作確認

今回のリアルタイムチェック機能の仕様は以下の通りです。

  • 入力された値によって以下のエラーメッセージが表示される
    • 半角数字以外の場合→「価格は半角数字で入力してください」
    • 300〜9,999,999の範囲外の場合→「価格は300〜9,999,999の範囲で設定してください」
  • 正しい値を入力するとメッセージが非表示になる

Javascriptのコード

メインとなるJavaScriptのコードは以下の通りです。

app/javascript/validation.js
//validationイベントを定義
const validation = () => {
  //エラーメッセージを表示するための要素を取得して変数化
  const priceErrorElement = document.getElementById("price-error");
  //フォームの値が入る要素を取得して変数化
  const itemPrice = document.getElementById("item-price");

  //ここから半角数字での入力を促すイベント
  //半角数字でないものにマッチする正規表現を変数化
  const pricePattern = /^\d+$/;

  //入力フォームでキーが離されたときにイベントが発生
  itemPrice.addEventListener("keyup", e => {
    //idがprice-character-errorの要素(エラーメッセージ)を取得して変数化
    const errorMessageCharacter = document.getElementById("price-character-error");
    //入力された値が正規表現にマッチしている or 空白のとき
    if (pricePattern.test(itemPrice.value) || itemPrice.value == "") {
      //エラーメッセージが存在しているとき
      if (errorMessageCharacter != null) {
        //エラーメッセージを削除
        errorMessageCharacter.remove();
      }
    //入力された値が正規表現にマッチしていないとき
    } else   {
      //エラーメッセージが存在していないとき
      if (errorMessageCharacter === null) {
        //エラーメッセージを挿入
        priceErrorElement.insertAdjacentHTML('afterend', '<div id="price-character-error" class="price-error">価格は半角数字で入力してください</div>' );
      }
    }
  });
  //ここまで半角数字での入力を促すイベント

  //ここから300〜9,999,999の範囲での入力を促すイベント
  //最小値と最大値を変数化
  const minimumPrice = 300;
  const maximumPrice = 9999999;

  //入力フォームでキーが離されたときにイベントが発生
  itemPrice.addEventListener("keyup", e => {
    //idがprice-range-errorの要素(エラーメッセージ)を取得して変数化
    const rangeErrorMessage = document.getElementById("price-range-error");
    //入力された値が300より小さい or 9,999,999より大きいとき
    if (itemPrice.value < minimumPrice || itemPrice.value > maximumPrice ) {
      //エラーメッセージが存在していないとき
      if (rangeErrorMessage === null) {
        //エラーメッセージを挿入
        priceErrorElement.insertAdjacentHTML('afterend', '<div id="price-range-error" class="price-error">価格は300〜9,999,999の範囲で設定してください</div>' );
      }
    //入力された値が300以上 or 9,999,999以下のとき
    } else {
      //エラーメッセージの要素が存在しているとき
      if (rangeErrorMessage != null) {
        //エラーメッセージを削除
        rangeErrorMessage.remove();
      }
    }
  });
  //ここまで300〜9,999,999の範囲での入力を促すイベント
}

//ページが読み込まれた(load)ときに、validationイベントを実行
window.addEventListener("load", validation)

上記validation.jsapplication.jsで読み込むことを忘れないようにしましょう。

app/javascript/packs/application.js
require("../validation")

Viewのコード

エラーメッセージを入れたい箇所に以下の要素を記述します。

new.html.erb
<div id="price-error"></div>