1. 목적
thymeleaf로 테이블로 구성된 admin 페이지를 만들고 거기서 이미지 URL 값을 input 박스로 확인함과 동시에 save 버튼으로 수정도 할 수 있게 만들어주고 싶었다.
2. fragment
fragments는 아래처럼 구성했다. 여기서 중요한 부분은 td를 th:if를 이용해서 reward.ImageUrl이 null이 아니고 비어있지 않은 경우에는 th:each를 사용하고 아닐 경우 th:unless를 사용해서 빈 값임을 표시해준 것이다.
그리고 data-initial-value로 model로 넘어온 값을 표시하면서 동시에 th:value로 사용자가 수정한 값을 button을 눌렀을 때 제출하도록 설정했다.
<div th:fragment="rewards(rewards)">
<table>
<thead>
<tr>
<th>공간 ID</th>
<th>공간 이름</th>
<th>ID</th>
<th>이름</th>
<th>이미지 URL</th>
</tr>
</thead>
<tbody>
<tr th:each="reward : ${rewards}">
<td class="td-50" th:text="${reward.spaceId}"></td>
<td th:text="${reward.spaceName}"></td>
<td th:text="${reward.id}"></td>
<td class="td-50" th:text="${reward.name}"></td>
<td th:if="${reward.rewardImageUrl != null and not #lists.isEmpty(reward.rewardImageUrl)}">
<div th:each="imageUrl: ${reward.rewardImageUrl}">
<input type="text" th:value="${imageUrl.url}" data-initial-value="${imageUrl.url}" class="editUrl" />
<button name="save" class="btn" th:attr="data-image-id=${imageUrl.id}">Save</button>
</div>
</td>
<td th:unless="${reward.rewardImageUrl != null and not #lists.isEmpty(reward.rewardImageUrl)}">
<span>no url</span>
</td>
</tr>
</tbody>
</table>
<div id="message-container"></div>
</div>
3. Script
thymeleaf의 fragment로 받아오는 구조에서 유의할 점은, fragment에서는 script 태그가 작동하지 않는다는 것이다. fragment를 받아주는 html 페이지에서 script를 작성해야한다.
jquery data-{something} 문법
script로 function을 만들었다. 상기 페이지에서 th:attr="data-image-id=${imageUrl.id}"로 설정하였는데, 이것은 jquery에서 아래 imageId처럼 $(this).data("image-id")값으로 받아올 수 있다고 한다.
siblings
input box에서 class = editUrl로 data-initial-value, th:value를 둘 다 같은 값으로 잡았다. 그래서 data("image-id")로 잡은 값과 동일 클래스를 갖는 th:value로 넘겨준 값을 찾기 위해서 같은 부모의 형제 요소라는 뜻으로 siblings를 사용한다고 한다.
$.ajax, $(document)
$.ajax 부분을 통해서 내부 controller로 처리되는 곳에 요청을 보낸다. 그리고 $(document)로 표시된 부분에서 'save'라는 이름의 버튼이 클릭되었을 때 rewardImageSave 메서드가 실행되도록 만들었다. 위 fragment 코드에서 button의 name = 'save'로 지정해주었다.
messageContainer
요청 성공, 실패 시 결과를 표시해주기 위해서 messageContainer를 변수로 두고 여기에 response를 <div> 요소로 추가할 수 있도록 했다.
//중략
//여기가 fragment
<div th:replace="~{admin/fragments/rewards :: rewards(${rewards})}"></div>
<div id="content">
</div>
</body>
</html>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
var messageContainer = $('#message-container');
function rewardImageSave() {
var imageId = $(this).data("image-id");
// Retrieve newUrl from the input with class 'editUrl'
var newUrl = $(this).siblings('.editUrl').val();
// Update the Thymeleaf attribute directly
$(this).siblings('.editUrl').attr('th:value', newUrl);
$.ajax({
type: 'PUT',
url: '{요청을 보낼 내부 주소. host는 미포함. IDE가 잡아준다. ex)/api/v1/admin/...}' + imageId,
contentType: 'application/json',
data: JSON.stringify({
url: newUrl
}),
success: function (response) {
messageContainer.html('<div class="success-message">Update successful: ' + response + '</div>');
},
error: function (error) {
messageContainer.html('<div class="error-message">Error updating: ' + error.responseText + '</div>');
}
});
}
$(document).ready(function () {
$("button[name='save']").click(rewardImageSave);
});
</script>
'Project > Poppin' 카테고리의 다른 글
스프링부트: 시큐리티- 회원가입, 로그인 기능 추가하기, swagger 로그인 하기, @ControllerAdvice (0) | 2023.12.25 |
---|---|
S3 이미지 업로드 구현, Profile 설정 및 불러오기, Swagger 이미지 업로드(multipart) (0) | 2023.12.25 |
AWS Credential(AcceesKey, SecretKey), github Actions - ECR CI 설정하기 (0) | 2023.12.09 |
AWS EC2 다른 계정용 pem key 만들고 접속: Permission Denied error (1) | 2023.12.07 |
poppin (0) | 2023.12.04 |