日記の編集と削除できるよう実装していきます。
編集
編集は詳細画面から編集ボタンを選択することで編集できるようにします。
編集画面は新規登録と同じなので、同じHTMLを利用していきます。
form
編集用のFormを「PutForm.java」作成していきます。
※PostFormとほぼ同じです。役割が異なるのでわけています。
package diary.form;
import java.util.Date;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class PutForm {
private boolean updateFlag;
private int id;
private String categoryForm;
@NotNull (message = "日付を入力してください。")
private Date dateForm;
@NotNull (message = "題名を入力してください。")
@Size(min = 1, max = 25, message="25文字以内で入力してください。")
private String titleForm;
private String contentForm;
public boolean getUpdateFlag() {
return updateFlag;
}
public void setUpdateFlag(boolean updateFlag) {
this.updateFlag = updateFlag;
}
public String getCategoryForm() {
return categoryForm;
}
public void setCategoryForm(String categoryForm) {
this.categoryForm = categoryForm;
}
public Date getDateForm() {
return dateForm;
}
public void setDateForm(Date dateForm) {
this.dateForm = dateForm;
}
public String getTitleForm() {
return titleForm;
}
public void setTitleForm(String titleForm) {
this.titleForm = titleForm;
}
public String getContentForm() {
return contentForm;
}
public void setContentForm(String contentForm) {
this.contentForm = contentForm;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Repository
「IDiaryDao.java」にメソッドを追加します。
// 日記を更新する
int update(PutForm form);
「DairyDao.java」にメソッドを追加します。
// 日記を編集する
@Override
public int update(PutForm form) {
int count = 0;
String sql = "UPDATE diary "
+ "SET category=:category, title=:title, content=:content, date=:date, update_datetime=:update_datetime "
+ "WHERE id=:id";
// パラメータ設定用Map
Map<String, Object> param = new HashMap<>();
param.put("id", form.getId());
param.put("category", form.getCategoryForm());
param.put("title", form.getTitleForm());
param.put("content", form.getContentForm());
param.put("date", form.getDateForm());
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
param.put("update_datetime", timestamp);
count = jdbcTemplate.update(sql, param);
return count;
}
Service
「DiaryService.java」にメソッドを追加していきます。
public int update(PutForm form) {
return dao.update(form);
}
Controller
「DiaryController.java」にメソッドを追加していきます。
実施していることは日記登録で記載した内容とほとんど同じになります。
/**
* 日記を編集
* @param putForm
* @param model
* @return
*/
@PostMapping(path="/update", params="update")
public String update(
@ModelAttribute PutForm form,
BindingResult result,
Model model
) {
if(result.hasErrors()) {
model.addAttribute("error", "パラメータエラーが発生しました。");
return "form";
}
int count = diaryservice.update(form);
return "redirect:/diary";
}
編集の場合フォーム画面へ遷移する際に多くのパラメータを渡すため、formPageメソッドを「@GetMapping」から「@PostMapping」に変更します。
また、新規登録か編集なのかで分岐しています。「updateFlag」の値はHTML内で設定します。
/**
* 新規登録へ遷移
* @param model
* @return resources/templates/form.html
*/
@PostMapping("/form")
public String formPage(
@ModelAttribute PutForm form,
Model model
) {
model.addAttribute("putForm", form);
//新規登録か編集で分岐
if (form.getUpdateFlag()) {
model.addAttribute("update", true);
} else {
model.addAttribute("update", false);
}
return "form";
}
一覧ページへ戻る用のbackPage(メソッドにも修正を加えます。
pathにupdateを追加しています。
@PostMapping(path={"/insert", "/form", "/update"}, params="back")
public String backPage(
Model model
) {
return "redirect:/diary";
}
画面修正
まずは「detail.html」を修正します。
formタグ内の末部に以下2行を追加します。
<input type="hidden" name="updateFlag" th:value=true>
<input type="hidden" name="id" th:value="${diary.id}">
<input type="hidden" name="categoryForm" th:value="${diary.category}">
<input type="hidden" name="titleForm" th:value="${diary.title}">
<input type="hidden" name="dateForm" th:value="${diary.date}">
<input type="hidden" name="contentForm" th:value="${diary.content}">
つぎに「form.html」修正をします。
変更箇所が多いためformタグ内全てを記載しています。
<form id="form" class="needs-validation" novalidate method="POST" th:action="${update}? @{/diary/update}: @{/diary/insert}" th:object="${putForm}" onsubmit="return check()">
<p class="p-1 h4" th:text="${update}? 編集: 新規作成"></p>
<div class="row justify-content-center">
<div class="form-group col-8">
<label for="dateForm">日付</label>
<input type="text" class="form-control" name="dateForm" id="date_sample" th:value="${#dates.format(putForm.dateForm, 'yyyy/MM/dd')}" required>
<div class="invalid-feedback">必須入力です</div>
</div>
</div>
<div class="row justify-content-center">
<div class="form-group col-8">
<label for="categoryForm">分類</label>
<select id="categoryForm" class="form-select col-8" name="categoryForm" th:value="*{categoryForm}" required>
<option selected></option>
<option value="1" th:selected="*{categoryForm} == 1">仕事</option>
<option value="2" th:selected="*{categoryForm} == 2">趣味</option>
<option value="3" th:selected="*{categoryForm} == 3">その他</option>
</select>
<div class="invalid-feedback">必須入力です</div>
</div>
</div>
<div class="row justify-content-center">
<div class="form-group col-8">
<label for="title">題名</label>
<input type="text" class="form-control" name="titleForm" id="title" th:value="*{titleForm}" required>
<div class="invalid-feedback">25文字以内で入力してください</div>
</div>
</div>
<div class="row justify-content-center">
<div class="form-group col-8">
<label for="floatingTextarea">内容</label>
<textarea class="form-control" placeholder="日記の内容" name="contentForm" th:text="*{contentForm}" style="height: 200px"></textarea>
</div>
</div>
<input type="hidden" name="id" th:value="*{id}">
<div class="row justify-content-end">
<div class="col-1">
<button type="submit" class="btn btn-primary" th:name="${update}? update: insert" th:text="${update}? 更新: 登録" onClick="btn='insert'"></button>
</div>
<div class="col-1">
<button type="submit" class="btn btn-light" name="back" onClick="btn='back'">一覧へ</button>
</div>
</div>
</form>
動作確認
編集の動作確認をしていきます。
①「詳細」→「編集」と画面遷移し、変更前の値が設定されていることを確認
②値を変更して各項目が更新されていることを確認
DBを確認して更新日も実施時間に更新されているかも含めて確認
③新規登録できるかを確認
新規登録に影響のあるform.htmlやControllerを修正したため、念の為確認
④「一覧へ」ボタンを選択し一覧画面へ戻れるかを確認
ここまでうまくいけば編集機能の完了となります。
削除
一覧画面に削除ボタンをつくっていました。
ボタンを押すと日記を削除できる機能を実装します。
削除なので、ボタン選択した後に確認ダイアログを表示しようと思います。
Repository
「IDiaryDao.java」にメソッドを追加します。
// 日記を削除する
int delete(int id);
「DiaryDao.java」にメソッドを追加します。
// 日記を削除する
@Override
public int delete(int id) {
int count = 0;
String sql = "DELETE FROM diary "
+ "WHERE id = :id";
// パラメータ設定用Map
Map<String, Object> param = new HashMap<>();
param.put("id", id);
count = jdbcTemplate.update(sql, param);
return count;
}
Service
「DiaryService.java」にメソッドを追加していきます。
public int delete(int id) {
return dao.delete(id);
}
Controller
「DiaryController.java」にメソッドを追加していきます。
/**
* 日記を削除
* @param id
* @param model
* @return
*/
@PostMapping("/delete")
public String delete(
@RequestParam int id,
Model model
) {
int count = diaryservice.delete(id);
return "redirect:/diary";
}
画面修正
「list.html」を修正していきます。
変更箇所は3つです。
・「delete」用のformタグを作成
・idをControllerに渡せるように「input type=”hidden”」を利用
・モーダルを作成
tbodyタグ内を抜粋しております。
<tbody>
<tr th:each="item: ${list}">
<td th:text=${item.date}></td>
<td th:text=${item.name}></td>
<td th:text=${item.title}></td>
<td>
<a class="btn btn-primary" th:href="@{/diary/{id}(id=${item.id})}">詳細</a>
</td>
<td>
<form method="POST" th:action="@{/diary/delete}">
<input type="hidden" th:value="${item.id}" name="id">
<button type="button" class="btn btn-danger" data-bs-toggle="modal" th:data-bs-target="'#id' + ${item.id}">削除</button>
<!-- Modal -->
<div class="modal fade" th:id="'id' + ${item.id}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
削除してもよろしいですか?
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-danger">削除</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">閉じる</button>
</div>
</div>
</div>
</div>
</form>
</td>
</tr>
</tbody>
動作確認
動作確認していきます。
①モーダルが開くことを確認
削除ボタンを選択して、モーダルを開きます。
②削除を選択するとデータが削除されることを確認
③モーダルの「閉じる」「✖️」を選択すると
モーダルが閉じることを確認
最後に
ここまで終えることでSpringを利用して「CRUD機能」を実装することができました。
思ったよりだいぶながくなってしまいました。。。
次回はSpringの機能を利用して、ログイン画面を実装していきます。