開発環境
・macOS Monterey Version 12.6.3
・Spring Tool Suite Version: 4.17.2.RELEASE
・MySQL 8.0.32
・Sequel Ace Version 4.0.5
実現したい処理
新規登録画面に入力欄(テキスト、テキストエリア)、ファイル選択ボタン、宛先選択ボタン、保存ボタンを表示する。
→宛先選択ボタン押下時にモーダルウインドウを表示する。
モーダルウインドウ内に、ユーザー名やメールアドレスが登録されているDBから検索した文字列とチェックボックスをテーブルに表示し、最下部に決定ボタンと閉じるボタンを表示する。
→チェックボックスにチェックを入れ (複数選択可)、モーダルウインドウ内の決定ボタンを押下すると、モーダルウインドウを閉じる。
→新規登録画面に戻り、保存ボタンを押下すると、チェックボックスの入力から取得されたIDが文字列としてDBに登録される。(複数選択された場合はカンマ区切りとなる)
※この時使用するDBは、モーダル内で使用したものとは別。
サンプルコード
▷DB
・新規登録画面で登録する際に使用するテーブル
selected_idsが今回チェックボックスの入力に対応させるカラムとなる。
(今回はAllow Nullにチェックが入っているが、外した方が良いかも)
・モーダル内に表示させるテーブル
今回はID取得に焦点を当てているため、ほかのカラムは適当でOK。
▷HTML
scriptタグ内の関数によって、チェックボックスから取得したIDを処理している。
<body>
<!--見出し-->
<div class="header">
<h2>新規登録</h2>
</div>
<!--フォーム-->
<form method="post" th:action="@{/upload}" enctype="multipart/form-data" class="input">
<section class="button_area">
<input type="button" onclick="location.href='#'" value="戻る"
control-id="ControlID-1">
</section>
<!--動画(ファイルが存在する場合のみ表示される)-->
<span th:if="${base64video}">
<div class="video">
<video controls th:src="${'data:video/mp4;base64,' + base64video}"></video>
</div>
</span>
<!--テーブル-->
<table class="input_area">
<tbody>
<tr>
<td>概要</td>
<!--入力-->
<td><input type="text" th:value="${outline}" name="outline" control-id="ControlID-2" /></td>
</tr>
<tr>
<td>説明</td>
<!--入力-->
<td><textarea name="explanation" control-id="ControlID-3">[[${explanation}]]</textarea></td>
</tr>
<tr>
<td>ファイル</td>
<!--入力-->
<td>
<label>
<input type="file" accept="video/*" class="file_upload" name="video"
onchange="selectFile(this)">ファイルを選択
</label>
<div id="fileUploadText">
<p id="fileUploadTextMsg" style="display: none;">ファイルが選択されました</p>
</div>
</td>
</tr>
<tr>
<td>宛先</td>
<!--入力-->
<td>
<!--宛先選択ボタン-->
<div class="chooseAddress">
<input type="button" id="openModal" value="宛先選択">
</div>
</td>
</tr>
</tbody>
</table>
<!--保存ボタン-->
<section class="button_save">
<input type="hidden" id="selected_ids" name="selected_ids" th:value="${selected_ids}">
<input type="submit" value="保存" control-id="ControlID-4">
</section>
</form>
<!--モーダル(宛先選択画面)-->
<div id="modal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h2>ユーザー</h2>
</div>
<div class="modal-body">
<div class="modal-inptArea">
<input type="text" class="inpt" id="modal_input" name="name" placeholder="検索するユーザー名を入力" />
<input type="submit" id="searchButton" value="検索">
</div>
<!-- 表 -->
<section class="chart">
<table>
<tbody>
<tr th:each="user : ${userlists}">
<td>
<!--チェックボックス-->
<input type="checkbox" name="checks" th:value="${user.id}">
</td>
<td th:text="${user.name}"></td>
<td th:text="${user.mail}"></td>
</tr>
</tbody>
</table>
</section>
<!--モーダル内ボタン-->
<div id="btnArea3">
<!--決定ボタン-->
<input type="submit" id="decide" class="accent" name="decideBtn" value="決定">
<!--閉じるボタン-->
<button type="button" id="buttonClose" class="accent" name="fallbackBtn">
閉じる
</button>
</div>
</div>
</div>
</div>
<!--JS-->
<script>
$(function () {
//モーダル表示/非表示
const $buttonOpen = $('#openModal');
const $buttonDecide = $('#decide');
const $buttonClose = $('#buttonClose');
const $modal = $('#modal');
// 宛先選択ボタンがクリックされた時
$buttonOpen.click(function () {
$modal.addClass("block");
});
// 閉じるボタンがクリックされた時
$buttonClose.click(function () {
$modal.removeClass("block");
});
// 決定ボタンをクリックしたときの処理
$('#modal #decide').click(function () {
//チェックボックスから取得したidをカンマ区切りで配列に格納する
let selectedIds = [];
$('#modal input[name="checks"]:checked').each(function () {
selectedIds.push($(this).val());
});
$('#selected_ids').val(selectedIds.join(','));
//モーダルを閉じる
$modal.removeClass("block");
});
});
</script>
</body>
▷Java
package com.controller;
//import文は省略
@Controller
public class CreateController {
// taskテーブル用リポジトリ
@Autowired
private TaskRepository taskRep;
@Autowired
private UserRepository userRep;
// 画面名
private static final String PAGE_NAME = "create";
// 作成画面
@GetMapping("/create")
@Transactional
public String disp(Model model, User user) {
// モーダル用:Userテーブルから全てのレコードを取得する
List<User> userlist = userRep.findAll();
// モデル設定
model.addAttribute("userlists", userlist);
model.addAttribute("taskForm", new TaskForm());
// 画面遷移
return PAGE_NAME;
}
// 概要、説明、動画ファイル、宛先をDBに登録する
@PostMapping("/upload")
@Transactional
public String upload(@RequestParam("video") MultipartFile video, @RequestParam("outline") String outline,
@RequestParam("explanation") String explanation, @RequestParam("selected_ids") String selected_ids,
Model model, User user) throws IOException {
// インスタンス
Task task = new Task();
// videoをbyte型に変換
byte[] cvideo = video.getBytes();
// base64にエンコード
String encodedVideo = Base64.getEncoder().encodeToString(cvideo);
//setter
task.setVideo(cvideo);
task.setOutline(outline);
task.setExplanation(explanation);
task.setSelectedIds(selected_ids);
// DB登録
taskRep.save(task);
// モデル
model.addAttribute("outline", outline);
model.addAttribute("explanation", explanation);
model.addAttribute("base64video", encodedVideo);
model.addAttribute("selected_ids", selected_ids);
//画面遷移
return disp (model, user);
}
}
以上