본문 바로가기
관리자

Project/Poppin

Thymeleaf로 input 확인 및 수정 Admin 페이지 만들기(jquery, script)

728x90
반응형

 

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>
728x90
반응형