今回は、Spring BootのWEB画面上で、ボタンの二度押し防止機能を実装してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること。
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。

なお、上記の赤枠は、前提条件のプログラムから変更したプログラムである。
HTMLファイルの内容は以下の通りで、「Ajax検索」ボタンと「画面再表示」ボタンを用意し、ボタン押下時に、それぞれJavaScriptの関数「getUserData」「reload」が呼ばれるようになっている。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<!-- jQueryの読み込み -->
<!-- demo.js内でjQueryを利用するため、jQueryをdemo.jsより先に読み込む -->
<script type="text/javascript" th:src="@{/jquery-3.4.1.min.js}"></script>
<script type="text/javascript" th:src="@{/demo.js}"></script>
<title>index page</title>
</head>
<body>
<form id="reloadForm" method="post" th:action="@{/}">
「Ajax検索」または「画面再表示」ボタンを押下してください。<br/>
<input type="button" id="ajaxSearchBtn" value="Ajax検索" onclick="getUserData();" />
<input type="button" id="reloadBtn" value="画面再表示" onclick="reload();" />
<br/><br/><br/>
★以下に検索されたデータが表示されます
<table id="userDataTbl" border="0">
<tr>
<th align="left" valign="top" width="180">名前</th>
<th align="left" valign="top" width="160">生年月日</th>
<th align="left" valign="top" width="60">性別</th>
<th align="left" valign="top" width="320">メモ</th>
</tr>
</table>
</form>
</body>
</html>また、JavaScriptファイルの内容は以下の通り。
'use strict';
window.addEventListener("DOMContentLoaded", function(){
// 画面がロードされたことを確認
alert('画面がロードされました');
});
function getUserData(){
// Ajax検索ボタンが押下されたことを確認
alert('Ajax検索ボタンが押下されました')
// jQueryのAjaxにてDemoControllerクラスのsearchメソッドを呼び出す
$.ajax({
url: "/search",
dataType: "text",
type: "GET"
// Ajaxが正常終了した場合
}).done(function(data, textStatus, jqXHR) {
// 該当するデータが無かった場合
if(!data){
alert("該当するデータはありませんでした");
return;
}
// 画面のtableタグの全てのtrタグを削除
$('#userDataTbl').find("tr:gt(0)").remove();
// 該当するデータがあった場合は、取得したUserDataオブジェクトのリストを
// 画面のtableタグに表示
// その際、名前・性別・メモはデコードする
const userDataList = JSON.parse(data);
let i = 0;
for(i = 0; i < userDataList.length; i++){
let trTag = $("<tr />");
trTag.append($("<td></td>").text(decodeURI(userDataList[i].name)));
trTag.append($("<td></td>").text(userDataList[i].birthY + '年'
+ userDataList[i].birthM + '月' + userDataList[i].birthD + '日'));
trTag.append($("<td></td>").text(decodeURI(userDataList[i].sex)));
trTag.append($("<td></td>").text(decodeURI(userDataList[i].memo)));
$('#userDataTbl').append(trTag);
}
// Ajax検索ボタンを非活性化
$('#ajaxSearchBtn').prop("disabled", true);
// Ajaxが異常終了した場合
}).fail(function(jqXHR, textStatus, errorThrown ) {
alert("エラーが発生し、データが取得できませんでした");
});
}
function reload(){
// 画面再表示ボタンが押下されたことを確認
alert('画面再表示ボタンが押下されました');
// 処理をサブミットし、初期表示画面を表示
$('#reloadForm').submit();
// 画面再表示ボタンを非活性化
$('#reloadBtn').prop("disabled", true);
}関数「getUserData」はAjax通信後に、Ajax検索ボタンを非活性にし、関数「reload」はサブミット後に画面再表示ボタンを非活性にしている。さらに、画面ロード時に画面がロードされた旨のダイアログが表示されるようになっている。
その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-web-avoid-doubleclick/demo
サンプルプログラムの実行結果
1) Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスすると、以下の画面が表示され、「画面がロードされました」というダイアログが表示されるため、「OK」を押下

3) 「Ajax検索ボタンが押下されました」というダイアログが表示されるため、「OK」を押下

4) データが表示されると共に、「Ajax検索」ボタンが非活性になり、「Ajax検索」ボタンの二度押しができなくなっている

6) 「画面再表示ボタンが押下されました」というダイアログが表示されるため、「OK」を押下

7) サブミット後に画面が再ロードされ、「画面がロードされました」というダイアログが表示されるため、「OK」を押下

8) 「画面再表示」ボタン押下後に、サブミット処理を行った後「画面再表示」ボタンを非活性にしたが、画面が再ロードされたため、「画面再表示」ボタンが活性になっている

要点まとめ
- ボタンを非活性にするには、jQueryを利用する場合、prop()メソッドを用いてdisabled属性をtrueにすればよい。この処理により、ボタンの二度押しを防ぐことができる。
- サブミット処理によりページ遷移が発生する場合は、サブミット直後にボタンを非活性にした場合でも、その後画面が再ロードされるため、非活性にしたボタンが再度活性になっている。







