LoginSignup
4
1

More than 3 years have passed since last update.

【JavaScript】JavaScriptでバリデーションを実装する。

Last updated at Posted at 2020-11-08

以下の項目を満たすバリデーションをjavascriptで実装してみる。
テンプレートエンジンはejs。フレームワークはexpress

  • パスワードが7文字以上
  • パスワードが確認用と一致している
  • 全ての項目が入力されている
  • 問題なかったら、ホーム画面へ

現在の状況
サインアップのフロントページ作成済
bc216d7ecd548acd6ecb29001bf34918.png

ログイン画面とサインアプページへのルーティング設定済

routes/users.js
const express = require('express');
const router = express.Router();

/* GET users listing. */
router.get('/login', function(req, res, next) {
  res.render('users/login');
});

router.get('/signup', function(req, res, next) {
  res.render('users/signup');
});

module.exports = router;

1 とりあえずホーム画面のルーティング作成

src/routes/home.js
const express = require('express');
const router = express.Router();

router.get('/', function(req, res, next) {
  res.render('home');
});

module.exports = router;
});

2 ホーム画面の仮作成

src/views/home.ejs
home

3 アクセスしてみる

Error: Failed to lookup view "error" in views directory "/app/views"
    at Function.render (/app/node_modules/express/lib/application.js:580:17)
    at ServerResponse.render (/app/node_modules/express/lib/response.js:1008:7)
    at /app/app.js:38:7
    at Layer.handle_error (/app/node_modules/express/lib/router/layer.js:71:5)
    at trim_prefix (/app/node_modules/express/lib/router/index.js:315:13)
    at /app/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/app/node_modules/express/lib/router/index.js:335:12)
    at next (/app/node_modules/express/lib/router/index.js:275:10)
    at /app/app.js:27:3
    at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)

エラー、、、

ルーティングが間違っている?

app.jsに登録してなかった。この辺の挙動はあまり理解していないが、とりあえず動作するようにしてみる。

app.js
const homeRouter = require('./routes/home');

app.use('/home', homeRouter);

を追記

再度アクセスしてみる。
オッケー

4 ejsを使用できるようにする。
  (1)npm install ejsについてはdocker build時に実施済
  (2)setメソッドで"view engine"というconfigに対し、テンプレートエンジンを指定

app.js
// テンプレートエンジンの指定
app.set("view engine", "ejs");
を追記

5 login画面でレンダリングできるかテストしてみる。

login.ejs

  <% const item = 'apple' %>
  <%= item %>

こんな感じで表示できるか確認。

2e528c8605286cbf073f14682b34ba4a.png

できた。

ログインページでjavascriptの読み込み

login.ejs
<script type="text/javascript" src='/javascript/validator.js'></script>

javascriptファイルの作成
/src/public/javascript/validator.js

6 各フォームに空欄エラー文を仕込む

signup.ejs
<input type="text" class="form-control col-7" id="NameForm" aria-describedby="namelHelp" 
 placeholder="Enter name">
<span id="error-name-null" class="d-none">必ず入力してください</span>

各フォームも同様。初期値は d-none で非表示にしている。
パスワード確認フォームには仕込まない。パスワードが空欄の場合エラー及びパスワードと空欄が一致する必要があるので、
パスワード確認が空欄の時、通ることはない。(共に空欄の場合一致はしてるが、パスワードが空欄エラー。パスワードが入力されている時、確認パスワードが空欄なら不一致エラーとなる)

7 フォームにonsubmitを仕込む

signup.ejs

<form class='col-7 mt-3 border pl-0 pr-0' onsubmit="return checkForm()">

onsubmitメソッド:
form要素に記述し、送信ボタンを押したとき(submit)に起動するスクリプトを指定するイベント属性(イベントハンドラ)。
起動するスクリプトは、属性値に "return 関数名()" と書く。
"true" を返せばフォームのアクションを実行し、"false" なら実行をキャンセルする。

8 空欄時の処理(名前入力欄)

validator.js
const checkForm = (e) => {
  const nameValue = document.getElementById("NameForm").value;
  let cancel = "off";
  //再クリック時に一旦、エラーメッセージを消去。(でないと残り続ける)
  document.getElementById('error-name-null').classList.add("d-none");

    if (!(nameValue)) {
      document.getElementById('error-name-null').classList.remove("d-none");
      cancel = "on";
    }
    if (cancel === "on"){
      return false;
    } else {
      return true;
    }
}

名前フォームが空欄の場合は、エラーメッセージを表示させる。
cancelフラグにonを格納。
cancelがonの時はonsubmitにfalseを返す。

9 パスワード欄の処理

    // パスワード空欄
    if (!(passwordValue)) {
      document.getElementById('error-password-null').classList.remove("d-none");
      cancel = "on";
    } else {
      // パスワード7文字以下
      if ((passwordValue.length < 7)) {
        document.getElementById('error-password-under7').classList.remove("d-none");
        cancel = "on";
      }
    }

空欄時に重複表示(空欄エラーと、7文字エラー)を避けるため、空欄時には7文字チェックは通過させない。

全文(装飾クラスは省略)

validator.js
  const checkForm = (e) => {
  const nameValue = document.getElementById("NameForm").value;
  const mailValue = document.getElementById("EmailForm").value;
  const passwordValue = document.getElementById("PasswordForm").value;
  const confirmPasswordValue = document.getElementById("confirmPasswordForm").value;
  const btn = document.getElementById("btn");
  let cancel = "off";

  document.getElementById('error-name-null').classList.add("d-none");
  document.getElementById('error-mail-null').classList.add("d-none");
  document.getElementById('error-password-null').classList.add("d-none");
  document.getElementById('differencePassword').classList.add("d-none");
  document.getElementById('error-password-under7').classList.add("d-none");

    // 名前空欄
    if (!(nameValue)) {
      document.getElementById('error-name-null').classList.remove("d-none");
      cancel = "on";
    }
    // メール空欄
    if (!(mailValue)) {
      document.getElementById('error-mail-null').classList.remove("d-none");
      cancel = "on";
    }
    // パスワード空欄
    if (!(passwordValue)) {
      document.getElementById('error-password-null').classList.remove("d-none");
      cancel = "on";
    } else {
      // パスワード7文字以下
      if ((passwordValue.length < 7)) {
        document.getElementById('error-password-under7').classList.remove("d-none");
        cancel = "on";
      }
    }
    // パスワード不一致
    if (!(passwordValue === confirmPasswordValue)) {
      document.getElementById('differencePassword').classList.remove("d-none");
      cancel = "on";    }
    if (cancel === "on"){
      return false;
    } else {
      return true;
    }
}
signup.js  #フォーム部分のみ 装飾用クラスは省略

        <!-- フォーム -->
        <form action="/home" method="post" onsubmit="return checkForm()">
          <!-- 名前 -->
            <input type="text" id="NameForm" >
            <span id="error-name-null" class="d-none">必ず入力してください</span>
          <!-- メール -->
            <input type="email" id="EmailForm">
            <span id="error-mail-null" class="d-none">必ず入力してください</span>
          <!-- パスワード -->
            <input type="password" id="PasswordForm">
            <span id="error-password-null" class="d-none">必ず入力してください</span>
            <span id="error-password-under7" class="d-none">7文字以上</span>
          <!-- パスワード確認 -->
            <input type="password" id="confirmPasswordForm">
            <span id="differencePassword" class="d-none">一致していません</span>
          <!-- ボタン -->
            <button id="btn">Register</button>
        </form>
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1