Snow Monkey Formsでファイル形式をチェックする方法

Snow Monkey Formsの技術記事

Snow Monkey Formsはシンプルで柔軟なフォームプラグインですが、現時点では「ファイル形式チェック」機能が標準で搭載されていません

この記事では、JavaScriptを使って特定の拡張子のみアップロードを許可する方法を紹介します。


目次

なぜカスタマイズが必要か?

Snow Monkey Formsでは、「必須チェック」などはプラグイン側で行われますが、
現時点では、「拡張子が不正」な場合の判定ロジックは存在しないです

そのため、PDFやExcel以外のファイルを防ぎたい場合は、フロント側で独自にバリデーションを追加する必要がありました。


今回の実装ポイント

  • 独自のエラーメッセージをSnow Monkey Formsのエラーとは別に出せる
  • 複数のファイルボタンに対応
  • 許可する拡張子(例:pdf, xls, xlsx)を指定可能

エラーがある場合は、このようなポップアップウィンドウが出てきます。

コード全文(JavaScript)

JavaScriptファイルに貼り付けてください。

以下の部分は、ご自身のフォームに合わせて変更してください。

  • コードの先頭:
    「許可する拡張子」と「対象のファイル入力のname属性」
  • コードの中盤:
    アラートメッセージ
    「アップロードできるファイル形式は PDF または Excel(xls, xlsx)のみです。」

※ちなみに、このコードは「必須チェックエラー」が出ている時も、エラーチェックしてくれるようになっています。

  // ファイル形式のエラーメッセージをカスタマイズ(JS側)-----------
  // 許可する拡張子とファイル入力のname属性を配列で管理
  const allowedExt = ["pdf", "xlsx", "xls"]; // 許可する拡張子
  const fileNames = ["file-1", "file-2", "file-3"]; // 対象のファイル入力のname属性

  // <バリデーション関数>
  // フォーム要素(特に <input>, <select>, <textarea>)の値が変更されたとき(changeイベント)に呼び出されます。
  // この場合、ユーザーがファイル選択ダイアログでファイルを選び「開く」を押したときに、発火します。
  // 既にイベントが登録されている場合は、一度removeEventListenerで解除してから再登録しているので、二重登録防止も行なっています。
  const addFileValidation = () => {
    fileNames.forEach((name) => {
      const fileInput = document.querySelector(
        `input[type="file"][name="${name}"]`
      );
      if (!fileInput) return;

      // 二重登録防止: 既存のchangeイベントリスナーを解除してから再登録
      fileInput.removeEventListener("change", handleFileChange);
      fileInput.addEventListener("change", handleFileChange);
    });
  };

  // <ファイル選択時の処理>
  // ファイルの拡張子を取得し、許可された拡張子に含まれていなければ警告を表示し、
  // ファイル入力の値を空にリセットすることで、無効なファイルのアップロードを防ぎます。
  function handleFileChange(e) {
    const file = e.target.files[0];
    if (!file) return;

    const ext = file.name.split(".").pop().toLowerCase();
    if (!allowedExt.includes(ext)) {
      alert(
        "アップロードできるファイル形式は PDF または Excel(xls, xlsx)のみです。" // ファイルの拡張子が違う時のエラーメッセージ
      );
      e.target.value = ""; // 無効なファイルをリセット
    }
  }

  // ページ読み込み時に初期化
  document.addEventListener("DOMContentLoaded", () => {
    addFileValidation();

    // Snow Monkey Forms が data-screen を書き換えた時を監視
    // フォームの画面遷移などでdata-screen属性が変更されると、
    // DOMが動的に変わる可能性があるため、MutationObserver(DOM変化を監視するネイティブAPI)を使って属性の変化を監視し、
    // 変化があった場合に再度バリデーション関数を呼び出してイベントリスナーを再設定します。
    // これにより、フォームの状態変化に応じて常に正しいバリデーションが適用されるようになります。
    const form = document.querySelector(".snow-monkey-form");
    if (!form) return;

    const observer = new MutationObserver((mutations) => {
      for (const mutation of mutations) {
        if (
          mutation.type === "attributes" &&
          mutation.attributeName === "data-screen"
        ) {
          // invalid (フォーム既存のエラーが発動した)状態になったら再度バリデーションを付与
          addFileValidation();
        }
      }
    });

    observer.observe(form, {
      attributes: true,
      attributeFilter: ["data-screen"],
    });
  });

処理の流れ

処理内容説明
1. ファイル入力要素を取得name属性で指定した各inputをquerySelectorで取得
2. changeイベントを登録ファイル選択時にバリデーション関数を呼び出す
3. 拡張子チェックファイル名を.で分割し、許可拡張子に含まれているか確認
4. 不正拡張子ならアラート表示alertを出して、inputの値をリセット
5. MutationObserverで再監視Snow Monkey Formsが内部的にdata-screenを書き換えた場合にも再設定

Snow Monkey Formsの独自エラーと分離している理由

Snow Monkey Formsにはフックによるカスタマイズができますが、
「ファイルの拡張子のチェック」は現時点では存在していないです。

そして、Snow Monkey Formsのエラーメッセージはプラグインの内部で管理されており、
直接追加するのは保守性が下がるリスクがあります。

そのため、独自のアラートとして別処理に分離しています。
これにより、プラグインのアップデートにも比較的強い構成になります。

Snow Monkey Formsの技術記事

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
目次