以下の項目を満たすバリデーションをjavascriptで実装してみる。
テンプレートエンジンはejs。フレームワークはexpress
- パスワードが7文字以上
- パスワードが確認用と一致している
- 全ての項目が入力されている
- 問題なかったら、ホーム画面へ
ログイン画面とサインアプページへのルーティング設定済
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 とりあえずホーム画面のルーティング作成
const express = require('express');
const router = express.Router();
router.get('/', function(req, res, next) {
res.render('home');
});
module.exports = router;
});
2 ホーム画面の仮作成
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に登録してなかった。この辺の挙動はあまり理解していないが、とりあえず動作するようにしてみる。
const homeRouter = require('./routes/home');
app.use('/home', homeRouter);
を追記
再度アクセスしてみる。
オッケー
4 ejsを使用できるようにする。
(1)npm install ejsについてはdocker build時に実施済
(2)setメソッドで"view engine"というconfigに対し、テンプレートエンジンを指定
// テンプレートエンジンの指定
app.set("view engine", "ejs");
を追記
5 login画面でレンダリングできるかテストしてみる。
<% const item = 'apple' %>
<%= item %>
こんな感じで表示できるか確認。
できた。
ログインページでjavascriptの読み込み
<script type="text/javascript" src='/javascript/validator.js'></script>
javascriptファイルの作成
/src/public/javascript/validator.js
6 各フォームに空欄エラー文を仕込む
<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 空欄時の処理(名前入力欄)
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文字チェックは通過させない。
##全文(装飾クラスは省略)
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>