웹 개발을 하다보면 List 데이터로 View단에서 Grid를 만들어야 할 경우가 많다. 특히 비지니스성의 관리 화면일 경우에는 서버에서 값들을 조회해 그리드로 뿌리는 일이 절반이라고 해도 과언이 아니다.
Spring boot로 서버를 구성하고, 뷰 리졸버로 thymeleaf(타임리프) 를 사용할 경우 이 작업이 매우 간단하게 이루어진다.
(개인적으로 기존 jsp를 사용할 때나, 굳이 비동기로 처리할 이유가 없다면 제이쿼리 ajax를 사용하는 것보다도 더 편리하다고 생각한다.)
타임리프에서 제공하는 여러 속성들 중, 'th:each'와 'th:text'를 사용한 방법이다.
시스템에 등록된 사용자를 조회해서 출력하는 예제를 통해 직접 만들어 보았다.
1. Spring Controller에서 데이터 전송
미리 두 건의 사용자 데이터를 DB에 등록해 뒀다. 서버에서 이 두 건의 데이터를 조회해 thymeleaf view로 보내줬다. 아래는 예시 컨트롤러이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Controller public class UserController { @Autowired UserMgmtSvc userMgmtSvc; @RequestMapping("/moveUserList.do") private ModelAndView home() throws Exception { List<UserVO> userList = userMgmtSvc.selectUserList(new UserVO()); ModelAndView mv = new ModelAndView("user/userList"); mv.addObject("userList", userList); return mv; } } | cs |
컨트롤러에서 데이터를 모델에 담아 view로 전송해 준다.
2. 타임리프 사용을 위해 html 태그를 선언해준다.
1 2 | <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"> | cs |
타임리프 사용을 위해서는 html 태그에 위와 같이 네임스페이스 속성을 가져와야 한다.
3. thymeleaf 태그를 사용하여 리스트를 테이블로 구성한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <table id="userTable"> <thead> <tr> <th>Email</th> <th>Name</th> <th>User Status</th> <th>Super User</th> </tr> </thead> <tbody> <tr th:each="user : ${userList}"> <td th:text="${user.email}">emil</td> <td th:text="${user.fullNmKr}">name</td> <td th:text="${user.userStatCd}">stat</td> <td th:text="${user.superUser}">super</td> </tr> </tbody> </table> | cs |
<tbody> 태그를 보자.
"th:each"는 테이블의 <tr> 태그에서 java의 for-in 문과 비슷한 역할을 한다. 나는 사용자 리스트를 서버에서 'userList' 라는 변수에 담에 전송했다. 이 리스트를 받아 각각 'user'라는 변수에 담아 그리드를 구성하는 것이다. <td> 태그에서는 이 'user'변수의 데이터들을 각각 꺼내 그리드의 셀들을 넣어 주면 되겠다.
이것으로 리스트 데이터를 사용해 그리드를 그리는 작업이 끝난다. 이 외에 다른 처리가 전혀 필요 없다. 이대로 서버를 구동시켜 보면, 두 건의 데이터가 단순한 HTML 테이블 형태로 그려지는 것을 확인할 수 있을 것이다.
여기에 웹 상에서 쉽게 구할 수 있는 다양한 그리드 플러그인을 입혀 주기만 하면 그럴듯한 업무 그리드를 간단하게 구성할 수 있다.
나는 더 예쁜 UI를 위해 'datatables' JQuery plug-in을 사용했다.
'datatables' 플러그인은 강력한 기능을 가지고 있는 제이쿼리 그리드 플러그인이다. 다음번에 기회가 되면 이 플러그인에 대해 써 보도록 하겠다.