共通JavaScript(common.js)の実装|パスワード表示切替・削除確認ダイアログ
1. はじめに
Java 8、Spring MVC 3.2.3、JSPを使用した業務Webアプリケーションの開発において、複数の画面で共通して利用するJavaScriptを common.js にまとめます。
今回は、次の2つの機能を実装します。
- パスワードの表示・非表示:パスワード入力欄の内容を一時的に表示する。
- 削除前の確認ダイアログ:データ削除の実行前に、ユーザーへ確認を求める。
サイドバーの開閉など、今回必要のない機能は除外します。また、jQueryなどの外部ライブラリは使用せず、標準JavaScriptで実装します。
開発環境
| 項目 | 使用技術 |
|---|---|
| Java | Java 8(1.8) |
| Servlet | Servlet 3.0 |
| Webフレームワーク | Spring MVC 3.2.3 |
| ビルドツール | Apache Maven 3.8.6 |
| IDE | Eclipse 18.9(使用環境の表記) |
| データベース | SQLite |
| 画面テンプレート | JSP |
| Webサーバー | Apache Tomcat(想定) |
JavaScriptはブラウザー上で動作するため、これらのJava側の技術構成に直接依存しません。
2. common.jsのソースコード
配置例:src/main/webapp/resources/js/common.js
(function () {
"use strict";
// パスワードの表示・非表示を切り替える
function initPasswordToggle() {
var buttons = document.querySelectorAll("[data-password-toggle]");
Array.prototype.forEach.call(buttons, function (button) {
button.addEventListener("click", function () {
var targetId = button.getAttribute("data-password-toggle");
var input = document.getElementById(targetId);
// 対象の入力欄が存在しない場合は処理しない
if (!input) {
return;
}
var showing = input.type === "password";
input.type = showing ? "text" : "password";
button.textContent = showing ? "非表示" : "表示";
button.setAttribute("aria-pressed", String(showing));
button.setAttribute(
"aria-label",
showing
? "パスワードを非表示にする"
: "パスワードを表示する"
);
});
});
}
// 削除前に確認ダイアログを表示する
function initDeleteConfirmation() {
var forms = document.querySelectorAll("[data-confirm-delete]");
Array.prototype.forEach.call(forms, function (form) {
form.addEventListener("submit", function (event) {
var message = form.getAttribute("data-confirm-delete")
|| "このデータを削除しますか?この操作は取り消せません。";
if (!window.confirm(message)) {
event.preventDefault();
}
});
});
}
// HTMLの読み込み完了後に初期化する
function init() {
initPasswordToggle();
initDeleteConfirmation();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
}());
3. パスワードの表示・非表示の仕組み
パスワード入力欄の type 属性を切り替えることで実現します。
-
type="password":入力した文字を伏せて表示する。 -
type="text":入力した文字をそのまま表示する。
JSPでの実装例
<div class="form-group">
<label for="password">パスワード</label>
<input
type="password"
id="password"
name="password"
autocomplete="current-password"
>
<button
type="button"
data-password-toggle="password"
aria-pressed="false"
aria-label="パスワードを表示する"
>表示</button>
</div>
この例では、JavaScript側で data-password-toggle="password" を読み取り、id="password" の入力欄を取得します。
ボタンを押すと入力欄が text に切り替わり、ボタンの表示も「非表示」に変わります。もう一度押すと、元の状態に戻ります。
type="button" は重要です。指定しない場合、フォーム内のボタンが送信ボタンとして扱われる可能性があります。
なお、パスワードの表示切替は画面上の表示方法を変えるだけで、パスワードのハッシュ化や暗号化を行う機能ではありません。
4. 削除前の確認ダイアログの仕組み
削除フォームの送信時に window.confirm() を呼び出し、ユーザーの選択によって処理を分岐させます。
- 「OK」:フォームの送信を許可する。
- 「キャンセル」:
event.preventDefault()によってフォームの送信を中止する。
JSPでの実装例
<form
action="${pageContext.request.contextPath}/users/delete"
method="post"
data-confirm-delete="このユーザーを削除しますか?"
>
<input type="hidden" name="userId" value="${user.id}">
<button type="submit">削除</button>
</form>
data-confirm-delete に確認メッセージを指定しています。
この属性を省略した場合は、JavaScriptに定義したデフォルトメッセージが使用されます。
var message = form.getAttribute("data-confirm-delete")
|| "このデータを削除しますか?この操作は取り消せません。";
これにより、ユーザー削除、部品削除、設備情報削除など、画面ごとに異なる確認メッセージを指定できます。
セキュリティ上の注意点
確認ダイアログは誤操作を防ぐための画面機能であり、セキュリティ対策そのものではありません。
実際の削除処理では、サーバー側でも次の対策が必要です。
- ログインユーザーに削除権限があるか確認する。
- CSRF対策を実施する。
- 対象データの存在と削除条件を検証する。
JavaScriptを無効にしたり、直接リクエストを送信したりしても、不正な削除ができない設計にする必要があります。
5. JavaScriptで使用している変数の解説
JavaScriptの変数は、処理の対象や一時的な値を保持するために使用します。
| 変数 | 内容 | 役割 |
|---|---|---|
buttons |
パスワード切替ボタンの一覧 | 対象となるボタンをまとめて取得する |
button |
個々のボタン要素 | クリックイベントを登録する |
targetId |
対象入力欄のID |
data-password-toggle から取得する |
input |
パスワード入力欄 | 表示形式を切り替える対象 |
showing |
表示状態を示す真偽値 | 表示中か非表示中かを判定する |
forms |
削除確認対象のフォーム一覧 | 対象フォームをまとめて取得する |
form |
個々のフォーム要素 | 送信イベントを登録する |
message |
確認ダイアログの文章 |
confirm() に表示するメッセージ |
event |
送信イベントの情報 | キャンセル時に送信を中止する |
ここでの変数はJavaのローカル変数と同じように、処理の中で利用する値を保持します。ただし、button や input には文字列ではなく、ブラウザーが扱うHTML要素のオブジェクトが格納されます。
var を使用しているのは、今回のJavaScriptを古いブラウザーも含む環境で扱いやすくするためです。Java 8を使用していること自体が var の使用条件になるわけではありません。
6. HTMLとJavaScriptを連携させるdata属性
今回の実装では、JavaScriptに画面ごとのIDやメッセージを直接書き込まず、HTML側の data-* 属性で指定します。
| 属性 | 設定例 | 意味 |
|---|---|---|
data-password-toggle |
data-password-toggle="password" |
表示切替の対象となる入力欄のID |
data-confirm-delete |
data-confirm-delete="削除しますか?" |
削除前に表示する確認メッセージ |
この設計には、次のメリットがあります。
- 共通JavaScriptを画面ごとに変更する必要がない。
- JSP側で対象の入力欄や確認メッセージを指定できる。
- 同じ機能を複数の画面で再利用できる。
- JavaScriptとHTMLの役割を分離でき、保守しやすい。
例えば、部品一覧画面では「この部品を削除しますか?」、ユーザー一覧画面では「このユーザーを削除しますか?」と指定するだけで、同じJavaScriptを利用できます。
7. JSPからcommon.jsを読み込む
共通レイアウトのJSP、または各画面のJSPで、次のように読み込みます。
<script src="${pageContext.request.contextPath}/resources/js/common.js"></script>
pageContext.request.contextPath はWebアプリケーションのコンテキストパスを取得するJSPの式です。
例えば、アプリケーションが /myapp で公開されている場合、実際の参照先は /myapp/resources/js/common.js になります。
この書き方により、Tomcat上でアプリケーションのコンテキストパスが変わっても、参照先を固定値で書き直す必要がありません。
なお、Spring MVCのリソース設定で /resources/** を公開対象にしておく必要があります。設定していない場合、JavaScriptファイルが404エラーになることがあります。
8. まとめ
今回の common.js は、パスワードの表示切替と削除前の確認という、業務Webアプリケーションで再利用しやすい2つの機能に限定しました。
特に重要なのは、JavaScriptに画面固有の情報を埋め込まず、HTMLの data-* 属性から取得する設計です。
Spring MVCやJSPによる開発でも、画面表示、JavaScriptによる操作、サーバー側の業務処理を分離することで、機能追加や保守を行いやすくなります。
今後、入力チェックの補助や検索条件の操作などを共通化する場合も、同じ考え方を応用できます。