今回は、Spring BootのWEB画面上で、ボタンの二度押し防止機能を実装してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること。
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。
なお、上記の赤枠は、前提条件のプログラムから変更したプログラムである。
HTMLファイルの内容は以下の通りで、「Ajax検索」ボタンと「画面再表示」ボタンを用意し、ボタン押下時に、それぞれJavaScriptの関数「getUserData」「reload」が呼ばれるようになっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <!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ファイルの内容は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | '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にすればよい。この処理により、ボタンの二度押しを防ぐことができる。
- サブミット処理によりページ遷移が発生する場合は、サブミット直後にボタンを非活性にした場合でも、その後画面が再ロードされるため、非活性にしたボタンが再度活性になっている。