Dev/Thymleaf

#ids.seq 사용하기 ( feat. prev 와 next )

린네의 2024. 2. 26. 18:29

 

 

th:each 사용시 내부에서 ids.seq 를 사용하면 index(ID count) 처리를 할 수 있다.  이 때 index 는 1 부터 시작한다.

 

  • prev   

  each 문에 의해 loop 를 돌 때마다 index 값은 1개씩 증가하는데,  prev 는 바로 이전에 해당하는 index 값이 반환 됨을 알 수 있다.

이 때 주의 해야할 점은 객체를 사용하지 않으면 index 는 생성되지 않는다.   따라서  객체를 사용하지 않았는데  prev 를 쓴다면  다음과 같은 예외가 발생한다. 

 

org.attoparser.ParseException: Cannot obtain previous ID count for ID

 

 

간단한 예제를 들어보자.

 

 <li class="list-group-item" th:each="material : ${materials}">
<input type="checkbox"  th:field="*{materialIds}" th:value="${material.id}" autocomplete="off">
    <label class="btn" th:for="${#ids.prev('materialIds')}" th:text="${material.name}"></label>
</li>

 

위 코드에서 materialsId  라는 객체가 input 에서 먼저 사용되었기 때문에 #ids.prev('materialsIds')  의 결과는 materialsId1 을 반환한다. 

 

따라서 결과는 다음과 같다.

<li class="list-group-item">
    <input type="checkbox" value="1" autocomplete="off" id="materialIds1" name="materialIds">
    <input type="hidden" name="_materialIds" value="on">
    <label class="btn" for="materialIds1">진피</label>
 </li>

 

 

여기서 <label> 과 <input> 의 선언순서가 바뀌었을 때 org.attoparser.ParseException: Cannot obtain previous ID count for ID 예외가 발생하는 것이다.

 

 

  • next

next 는 이후의 시퀀스 값을 가져 온다.  prev 와 다르게 다음 index 를 먼저 계산해서 부여하기 때문에 객체선언보다 먼저 쓸 수 있다.

 

다음 코드를 보자.

<li class="list-group-item" th:each="material : ${materials}">
<label class="btn" th:for="${#ids.next('materialIds')}" th:text="${material.name}"></label>
<input type="checkbox"  th:field="*{materialIds}" th:value="${material.id}" autocomplete="off">    
</li>

 

materialIds 보다 먼저 선언 되었음에도 불구하고 prev 처럼 오류가 발생하지 않는다. 

 

결과를 보면 #ids.next('materialIds') 가 선언된 시점으로부터 다음 객체의 index 에 해당하는 값이 반환 되는 것을 볼 수 있다.

<li class="list-group-item">
<label class="btn" for="materialIds1">진피</label>
<input type="checkbox" value="1" autocomplete="off" id="materialIds1" name="materialIds">
<input type="hidden" name="_materialIds" value="on">
</li>

 

이해를 돕기 위해 한가지 예제를 더 작성해봤다.

 

만약 next 를 사용하는데 객체 뒤에 쓴다면 어떻게 될까?

<li class="list-group-item" th:each="material : ${materials}">
<input type="checkbox"  th:field="*{materialIds}" th:value="${material.id}" autocomplete="off">    
<label class="btn" th:for="${#ids.next('materialIds')}" th:text="${material.name}"></label>
</li>

 

 

간단하다. 다음 값인 materialsId2 가 반환된다.

<li class="list-group-item">
<input type="checkbox" value="1" autocomplete="off" id="materialIds1" name="materialIds">
<input type="hidden" name="_materialIds" value="on">
<label class="btn" for="materialIds2">진피</label>
</li>

 

 

 

일반적으로는 checkbox 와 Label 설정을할 때 많이 사용한다.  prev 를 사용할 경우에는 label 을 기준으로  input 을 먼저,  next 는 용input 을 나중에 둬서 편하게 사용할 수 있다.

 

 

 

구현된 결과