これまでは、Spring Bootによるチェック処理を利用してきたが、今回はJavaScriptによって同等のチェック処理を実装してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること。
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。

なお、上記の赤枠は、前提条件のプログラムから追加/変更したプログラムである。
input.htmlの内容は以下の通りで、「確認」ボタン押下時にcheckInputAndSubmit関数を呼び出すように修正している。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<link th:href="@{/demo.css}" rel="stylesheet" type="text/css" />
<script type="text/javascript" th:src="@{/demo.js}"></script>
<title>入力画面</title>
</head>
<body>
<p>下記必要事項を記載の上、「確認」ボタンを押下してください。</p><br/>
<form th:object="${demoForm}">
<table border="0">
<tr>
<td align="left" valign="top">名前:</td>
<td>
<input type="text" th:value="*{name}"
th:field="*{name}" th:errorclass="fieldError" />
<span th:if="*{#fields.hasErrors('name')}"
th:errors="*{name}" class="errorMessage"></span>
</td>
</tr>
<tr>
<td align="left" valign="top">生年月日:</td>
<td>
<input type="text" th:value="*{birthYear}" size="4"
maxlength="4" th:field="*{birthYear}" th:errorclass="fieldError"
th:classappend="${#fields.hasErrors('birthDayRequired')} ? 'fieldError'" />年
<select th:field="*{birthMonth}" th:errorclass="fieldError"
th:classappend="${#fields.hasErrors('birthYear')
|| #fields.hasErrors('birthDayRequired')} ? 'fieldError'">
<option value="">---</option>
<option th:each="item : *{getMonthItems()}"
th:value="${item.key}" th:text="${item.value}"/>
</select>月
<select th:field="*{birthDay}" th:errorclass="fieldError"
th:classappend="${#fields.hasErrors('birthYear')
|| #fields.hasErrors('birthDayRequired')} ? 'fieldError'">
<option value="">---</option>
<option th:each="item : *{getDayItems()}"
th:value="${item.key}" th:text="${item.value}"/>
</select>日
<span th:if="*{#fields.hasErrors('birthDayRequired')}"
th:errors="*{birthDayRequired}" class="errorMessage"></span>
<span th:if="*{#fields.hasErrors('birthYear')}"
th:errors="*{birthYear}" class="errorMessage"></span>
</td>
</tr>
<tr>
<td align="left" valign="top">性別:</td>
<td>
<for th:each="item : *{getSexItems()}">
<input type="radio" name="sex" th:value="${item.key}" th:text="${item.value}"
th:field="*{sex}" th:errorclass="fieldError" />
</for>
<span th:if="*{#fields.hasErrors('sex')}"
th:errors="*{sex}" class="errorMessage"></span>
<span th:if="*{#fields.hasErrors('sexInvalid')}"
th:errors="*{sexInvalid}" class="errorMessage"></span>
</td>
</tr>
<tr>
<td align="left" valign="top">メモ:</td>
<td>
<textarea rows="6" cols="40" th:value="*{memo}" th:field="*{memo}"></textarea>
</td>
</tr>
<tr>
<td align="left" valign="top">入力確認:</td>
<td>
<input type="checkbox" name="checked" th:value="確認済"
th:field="*{checked}" th:errorclass="fieldError" />
<span th:if="*{#fields.hasErrors('checked')}"
th:errors="*{checked}" class="errorMessage"></span>
</td>
</tr>
</table>
<br/><br/>
<input type="button" value="確認" onclick="checkInputAndSubmit('/confirm');" />
<input type="button" value="戻る" onclick="formSubmit('/confirmBack');" />
</form>
</body>
</html>また、JavaScriptの内容は以下の通りで、checkInput関数で入力チェックを行い、エラーでない場合にサブミットする処理を実装している。
'use strict';
// 引数で指定されたパスでサブミットする
function formSubmit(path){
if(!path){
alert('パスを指定してください');
return;
}
let form = document.getElementsByTagName('form')[0];
if(!form){
alert('フォームが取得できませんでした');
return;
}
form.action=path;
form.method="post";
form.submit();
}
// 入力画面の入力値のチェックを行った後で、
// 引数で指定されたパスでサブミットする
function checkInputAndSubmit(path){
if(!checkInput()){
return;
}
formSubmit(path);
}
// 入力画面の入力値のチェックを行う
function checkInput(){
//名前の未入力チェック
let nameElem = document.getElementById('name');
if(nameElem.value === ''){
alert('名前を入力してください。');
nameElem.focus();
return false;
}
//名前の全角入力チェック
if(!nameElem.value.match(/^[^\x01-\x7E\xA1-\xDF]+$/)){
alert('名前は全角で入力してください。')
nameElem.focus();
return false;
}
//生年月日の未入力チェック
let birthYearElem = document.getElementById('birthYear');
let birthMonthElem = document.getElementById('birthMonth');
let birthDayElem = document.getElementById('birthDay');
if(birthYearElem.value === ''
&& birthMonthElem.value === '' && birthDayElem.value === ''){
alert('生年月日を入力してください。');
birthYearElem.focus();
return false;
}
//生年月日の妥当性チェック
if(!isValidDate(birthYearElem.value, birthMonthElem.value, birthDayElem.value)){
alert('生年月日が存在しない日付になっています。');
birthYearElem.focus();
return false;
}
//生年月日の未来日チェック
if(isFutureDate(birthYearElem.value, birthMonthElem.value, birthDayElem.value)){
alert('生年月日が未来の日付になっています。');
birthYearElem.focus();
return false;
}
//性別の未入力チェック
let sexElem = document.getElementsByName('sex');
let sexValue = '';
for (let i = 0; i < sexElem.length; i++) {
if (sexElem[i].checked) {
sexValue = sexElem[i].value ;
break;
}
}
if(sexValue === ''){
alert('性別を入力してください。');
sexElem[0].focus();
return false;
}
//確認チェックの未入力チェック
let checkedElem = document.getElementsByName('checked');
if(!checkedElem[0].checked){
alert('確認チェックを入力してください。');
checkedElem[0].focus();
return false;
}
return true;
}
// 日付の妥当性チェックを行う
function isValidDate(year, month, day) {
let thisDate = new Date(year, month-1, day);
return (thisDate.getFullYear() == year
&& thisDate.getMonth() == month-1 && thisDate.getDate() == day);
}
// 日付の未来日チェックを行う
function isFutureDate(year, month, day){
let thisDate = new Date(year, month-1, day);
let nowDate = new Date();
return (thisDate.getTime() > nowDate.getTime());
}その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-js-check/demo
サンプルプログラムの実行結果
サンプルプログラムの実行結果は、以下の通り。
1) Spring Bootアプリケーションを起動し、「http://(サーバー名):(ポート番号)/」とアクセスし、入力画面に遷移する。

2) 何も入力しない状態で「確認」ボタンを押下すると、「名前を入力してください。」というエラーメッセージが表示される。


3) エラーメッセージのダイアログで「OK」ボタンを押下すると「名前」にカーソルが設定される。


4) 名前に半角文字を入力すると、以下のように、「名前は全角で入力してください。」というエラーメッセージが表示される。

5) 名前に全角文字を入力し、生年月日を入力せず「確認」ボタンを押下すると、「生年月日を入力してください。」というエラーメッセージが表示される。


6) 生年月日に不正な日付を入力し「確認」ボタンを押下すると、「生年月日を入力してください。」というエラーメッセージが表示される。


7) 生年月日に未来の日付を入力し「確認」ボタンを押下すると、「生年月日が未来の日付になっています。」というエラーメッセージが表示される。

8) 名前・生年月日を入力し、性別を入力せず「確認」ボタンを押下すると、「性別を入力してください。」というエラーメッセージが表示される。


9) 名前・生年月日・性別を入力し、入力確認チェックを入力せず「確認」ボタンを押下すると、「確認チェックを入力してください。」というエラーメッセージが表示される。


10) チェックエラーにならない状態で「確認」ボタンを押下すると、確認画面に遷移する。


要点まとめ
- Spring Bootによるチェック処理と同等の処理は、JavaScriptによっても実装することができる。





