WEB制作
JavaScript | 12章:まとめの演習1 NGワードを送信禁止にするフォームをつくろう
INDEX
目次

12章:まとめの演習1 NGワードを送信禁止にするフォームをつくろう

本章では、ここまでに学習したDOMの操作、変数・定数の使い方、配列、条件分岐、ループなどを組み合わせて、まとめの演習としてサンプルデータを作成していきます。

【12-1】NGワードを送信禁止にするフォームの仕様

今回作成するフォームチェックの機能は、あらかじめ登録しておいたNGワード(果物の名前)が、ユーザーが入力した文章に含まれていた場合に、データの送信を中止するというものです。

  • 作成する機能は以下のとおりです。

    • テキスト中に特定の文字列が含まれているかどうかを検索する機能をどのようにして作るか、というところがポイントです。


    本章で作成するサンプルページ
    ✔️ 作成するフォームの機能

    • ページロード時に複数行テキスト欄にカーソルを立てる。

    • 空欄では送信できない。

    • 登録されているNGワードが含まれているテキストは送信できない。

    • 送信キャンセルする際には、アラートでメッセージを表示する。


    演習データをダウンロードし、「ngwords-check_start.html」とjsフォルダ内の「ngwords-check.js」をエディターで開き、ブラウザプレビューしてください。


    使用素材

    JS12演習データ.zip (4.57 KB)
    演習素材について
    • ダウンロードした「JS12演習データ」フォルダの中には、「ngwords-check_start.html」「ngwords-check_fin.html」と「js」フォルダが入っています。
    • 「ngwords-check_start.html」と「js」フォルダの中の「ngwords-check.js」は作業用のファイルです。
    • 「ngwords-check_fin.html」は完成データです。
    • 自分で書いたコードがうまく動作しないときは、完成データとの違いを探してみると良いでしょう。

    「ngwords-check_start.html」と「js」フォルダの中身の「ngwords-check.js」をエディターで開いてコードを書いていきましょう。


    <body>
      <main class="maincontents">
        <h1 class="heading-main">NGワードを送信禁止にするフォーム</h1>
        <h2 class="heading-message">私に一言お手紙をください!果物の名前だけはやめてね</h2>
        <h3 class="heading-ng">登録されているNGワード</h3>
        <p class="ngwords-list">りんご、みかん、梨、オレンジ、レモン、マンゴー、スイカ、柿、ぶどう、イチゴ</p>
        <section class="form-wrap">
          <form class="form-ngwords">
            <div class="form-parts-wrap">
              <textarea name="comment" type="text" class="form-multiline"></textarea>
            </div>
            <div class="form-submitbtn-wrap">
              <input type="submit" value="入力内容を確認する" class="form-submitbtn">
            </div>
          </form>
        </section>
      </main>
    </body>
    ngwords-check_start.html サンプルコード12-1
     (11127)


    【12-2】ページロード時の処理を作成しよう

    🟧 ページロード時に複数行テキスト欄にカーソルを立てる

    まずはページロード時の処理を作成します。こちらの作成方法は「5章 フォームオブジェクトを操作しよう」で一度学んでいますので、とくに問題なく作成できると思います。


    scriptタグで外部JSファイルを関連付けする

    💡サンプルコード12-2の解説

    • 今回はJavaScriptを外部ファイルとして作成しますので、まずはダウンロードした「ngwords-check.js」を「ngwords-check_start.html」と関連付けします。
    • </body> の直前に <script></script> を記述します。
    ・・・中略・・・
    </main>
    <script src="js/ngwords-check.js"></script>
    </body>
    </html>
    ngwords-check_start.html サンプルコード12-2

    要素オブジェクトを作成する

    💡サンプルコード12-3、12-4の解説

    • カーソルを立てる複数行のテキスト欄はtextareaタグで作成されています。

    • このタグにはすでに「form-multiline」というclass名がつけてありますので、それをquerySelectorメソッドで取得して、constで宣言したtextArea定数に要素オブジェクトとして格納します。

    <textarea name="comment" type="text" class="form-multiline"></textarea>
    ngwords-check_start.html サンプルコード12-3
    //オブジェクト一覧
    const textArea = document.querySelector(".form-multiline");
    ngwords-check.js サンプルコード12-4

    focusメソッドでカーソルを立てる

    💡サンプルコード12-5の解説

    • テキスト欄にカーソルを立てることを「フォーカスする」といいます。

      • Elementオブジェクト(フォームパーツ)のfocusメソッドを使って実現します。

    //オブジェクト一覧
    const textArea = document.querySelector(".form-multiline");
    //ページロード時にカーソルを立てる
    textArea.focus();
    ngwords-check.js サンプルコード12-5

    【12-3】フォーム送信時の処理を作成しよう

    🟧 フォーム送信時に文字列の検索をする

    次にフォーム送信時の処理を作成します。

  • for文を使い、配列に格納した複数のNGワードを順番に検索していきます。

  • ユーザーが入力したテキストの中にNGワードが含まれていた場合には、アラートでメッセージの表示とイベント処理の中止を実行します。


  • 配列にNGワードを格納する

    💡サンプルコード12-6の解説

    • constで配列名ngWordを宣言し、[ ]内にNGワードの文字列を「,」で区切りながら格納していきます。

    • このNGワード(配列データ)の数は、ページ更新時に増やしたり減らしたりすることを前提とし、プログラムを作成します。

    //配列にNGワードを格納する
            const ngWord = ["りんご", "みかん", "梨", "オレンジ", "レモン", "マンゴー", "スイカ", "柿", "ぶどう", "イチゴ"];
    ngwords-check.js サンプルコード12-6

    formタグの要素オブジェクトを作成する

    💡サンプルコード12-7、12-8の解説

    • submitイベント(送信イベント)はform要素に設定するイベントであるため、まずはformタグのclass名を取得して要素オブジェクトを作成します。

    • querySelectorメソッドでformタグのclass名を取得し、定数formTagに格納してform要素オブジェクトを作成します。

    <form class="form-ngwords">
    ・・・中略・・・
    </form>
    ngwords-check_start.html サンプルコード12-7
    const formTag = document.querySelector(".form-ngwords");
    ngwords-check.js サンプルコード12-8

    submitイベントを設定する

    💡サンプルコード12-9の解説

    • form要素オブジェクトformTagaddEventListenerメソッドを使いsubmitイベントを設定します。

    • イベント処理内でフォームの送信キャンセルを実行するため、あらかじめ関数の引数にイベントオブジェクト名「e」を記述しておきます。(「9章 CONTACTフォームの入力チェックをやってみよう」参照)

    //submitイベントを設定する
    formTag.addEventListener("submit", function (e) {
            //ここにsubmitイベント発生時の処理を記述する
    }
    ngwords-check.js サンプルコード12-9

    submitイベント発生時の処理内容は以下のとおりです。

    ✔️ submitイベント発生時の処理内容

    • 空欄チェック(空欄だったとき)
    •  
      • アラートを出す

      • 送信中止

    • NGワードの検索

      • ループにより複数のNGワードを順番に検索する

      • 見つかったらアラートを出す

      • 送信中止

      • ループ中断


    空欄チェック
  • submitイベント発生時の処理内容を記述していきます。

    • まずは空欄チェックから作成します。

    • 8〜10章で学んだとおりです。

    💡サンプルコード12-10の解説

    • 定数inputTextを宣言し、そこにテキスト欄(textArea要素オブジェクト)に入力された内容をvalueプロパティで取得し、格納します。

    • 取得したデータが空の文字列「""」かどうかを、if文で判別します。

      • 条件式はinputText == ""です。

    • 空欄だった場合は、alert("メッセージを入力してください!");でメッセージを出力します。

    • 空データが送信されないよう、e.preventDefault();で送信イベントをキャンセルします。

    //submitイベントを設定する
    formTag.addEventListener("submit", function (e) {
      //ここにsubmitイベント発生時の処理を記述する
      //空欄チェック
      //入力されたテキストを取得して定数に格納する
      const inputText = textArea.value;
      //空欄チェック
      if (inputText == "") {
        alert("メッセージを入力してください!");
        e.preventDefault(); //送信中止
      }
    });
    ngwords-check.js サンプルコード12-10

    NGワードの検索
  • 次に、NGワードの検索です。

  • 配列に格納されたNGワードの文字列が、定数inputTextに格納されたテキストの中に含まれているかどうかを検索するコードを記述します。

  • 文字列の検索にはindexOfメソッドを使います。

  • indexOfメソッドは、JavaScriptの組み込みオブジェクト(ビルトインオブジェクト)であるStringオブジェクトのメソッドです。
    ※組み込みオブジェクトについては「11章 配列を学ぼう」を参照してください。


  • 💡Stringオブジェクトとは

    • Stringオブジェクトとは、文字列を扱うためのオブジェクトです。

    • とくに決まったオブジェクト名は持ちません。

    • 文字列が代入された変数(定数)がStringオブジェクトです。


    Stringオブジェクトの主なメソッド、プロパティには下のようなものがあります。

     (11177)


    まずは、下記のindexOfメソッドの使い方を確認しましょう。


    ✔️ submitイベント発生時の処理内容
    • StringオブジェクトのindexOfメソッドの使い方を解説します。
    • 💡サンプルコード12-11の解説

      • constで宣言した定数strに "おいしいりんご" という文字列を代入します。
      • この定数 str が Stringオブジェクトです。
      • 文字列 "おいしいりんご" の中に "りんご" という文字列が含まれているかどうかを indexOfメソッド で検索します。
        • str.indexOf("りんご")と記述します。
        • 検索結果は alertメソッド で出力します。
      • indexOfメソッド は、検索文字列が含まれていた場合に、 何文字目から含まれているかを番号で返します。 最初の文字が0、2文字目が1、3文字目が2です。
      • "おいしいりんご" の中に "りんご" は5文字目から含まれています。
        • 検索結果は 4 となります。
    <body>
      <script>
        const str = "おいしいりんご";
        alert(str.indexOf("りんご"));
      </script>
    </body>
    サンプルコード12-11

      💡サンプルコード12-12の解説

      • 検索文字列の”みかん”は、"おいしいりんご”の中には含まれていません。

      • このような場合の検索結果は-1となります。

    <body>
      <script>
        const str = "おいしいりんご";
        alert(str.indexOf("みかん"));
      </script>
    </body>
    サンプルコード12-12

    条件式の書き方
  • indexOfメソッドの使い方を学んだところで、NGワードが含まれているかどうかを判別するコードを書いてみましょう。

  • indexOfメソッドを使うと、検索文字列がStringオブジェクトに含まれていた場合は、何番目の文字から含まれているかという番号を返すのですから、返ってくる番号は、ユーザーが入力した文章によって異なります。

  • しかし、含まれていなかった場合は、どんな文章をユーザーが入力したとしても、必ず-1が返ってきます。

    • この-1を使い、判別するためのif文の条件式を書きます。


    例えば、下のサンプルコード12-13の条件式はどうでしょう。

    if (inputText.indexOf(ngWord[0]) != -1) {
      alert("NGワードが含まれています!");
    }
    サンプルコード12-13

    💡サンプルコード12-13の解説

    • Stringオブジェクトである定数inputTextにはユーザーが入力した文章が格納されています。

    • indexOfメソッドで配列データngWord[0]を検索しています。

      • サンプルコード12-6で定義した配列のとおり、ngWord[0]には文字列りんごが格納されています。

      • もし定数inputTextに文字列りんごが含まれていなかった場合、inputText.indexOf(ngWord[0])は-1を返します。

      • 調べたいのは、りんごが含まれていた場合ですので、条件式を「返ってきた値が-1ではないとき」とする必要があります。

      • 従って、条件式は、比較演算子「!=」(左辺と右辺の値が等しくない場合にtrueを返す)を使い、「inputText.indexOf(ngWord[0]) != -1」となります。


  • サンプルコード12-6で定義した配列データ(文字列)にアクセスするための配列名は次のとおりです。

  •  (11195)


    for文のループで全ての検索文字列(配列データ)が含まれているかどうかを順番に調べる
  • 上記サンプルコード12-13では、検索文字列をngWord[0]に限定してしまいましたので、文字列りんごが含まれているかどうかしか調べることができません。

  • 全ての検索文字列を検索するためには、for文のループを使い、配列のインデックス番号ループカウンタを連動させるコードを書けば、効率よく処理を実行することができます。

  • 具体的には、ngWord[i]のように、インデックス番号を変数iに差し替え、for文でiに1ずつ加算しながらループ処理を行うのです。

    💡サンプルコード12-14の解説

      まずはfor文の解説です。


      初期化式
      • let i = 0;で変数iに0を代入します。

        • この変数iがループカウンタです。

        • 増減式でこの変数iに1ずつ加算していきます。


      条件式
      • 条件式でループの回数を設定します。

      • i<ngWord.length;のlengthは配列のプロパティで、配列の長さ(データの数)を返します。

        • 今回は全部で10個の文字列データが配列に格納されていますので、10を返します。

        • i<10;と書くよりも、修正しやすいコードになります。


      増減式
      • 定番のi++で変数iに1ずつ加算します。


      次に、NGワードの検索のための条件分岐処理の解説です。


      if文の条件式
      • if (inputText.indexOf(ngWord[i]) != -1)と書けば、for文のループにより、ループカウンタ変数iに0〜9までの番号がループする度に順番に代入されます。

      • その結果、全ての検索文字列(配列データ)が順番に検索されます。


      ループを中断
      • NGワードが見つかった場合、return文で関数の実行を終了します。
        ※「10章 JavaScriptの反復処理を学ぼう」参照


      送信中止
      • イベントオブジェクトのpreventDefaultメソッドで、NGワードが見つかった際には、データの送信をキャンセルします。


      //取得したテキスト内に配列のNGワードが含まれているかどうかを、順番にfor文のループで検索する
      for (let i = 0; i < ngWord.length; i++) {
        if (inputText.indexOf(ngWord[i]) != -1) {
          alert("NGワードが含まれています!");
          e.preventDefault(); //送信中止
          return; //NGワードが見つかったらループを中断する
        }
      }
      サンプルコード12-14

      💡 完成コード全体 ngwords-check.js

      //オブジェクト一覧
      const textArea = document.querySelector(".form-multiline");
      const formTag = document.querySelector(".form-ngwords");
      
      //配列にNGワードを格納する
      const ngWord = ["りんご", "みかん", "梨", "オレンジ", "レモン", "マンゴー", "スイカ", "柿", "ぶどう", "イチゴ"];
      
      //ページロード時にカーソルを立てる
      textArea.focus();
      
      //submitイベントを設定する
      formTag.addEventListener("submit", function (e) {
        //ここにsubmitイベント発生時の処理を記述する
        //入力されたテキストを取得して定数に格納する
        const inputText = textArea.value;
        //空欄チェック
        if (inputText == "") {
          alert("メッセージを入力してください!");
          e.preventDefault();//送信中止
        }
      
        //取得したテキスト内に配列のNGワードが含まれているかどうかを、順番にfor文のループで検索する
        for (let i = 0; i < ngWord.length; i++) {
          if (inputText.indexOf(ngWord[i]) != -1) {
            alert("NGワードが含まれています!");
            e.preventDefault(); //送信中止
            return; //NGワードが見つかったらループを中断する
          }
        }
      })
      完成コード全体 ngwords-check.js サンプルコード12-15


      これで「12章:まとめの演習1 NGワードを送信禁止にするフォームをつくろう」の解説を終わります。

      次の章に進みましょう。

      WEBCOACH | キャリアチェンジまでの全てを学ぶマンツーマンWEBスクール
      © 2020 by WEBCOACH