봄날은 갔다. 이제 그 정신으로 공부하자

node.js로 웹서비스 만들기 (10. Table row 동적 추가, 삭제, 순서 변경하기) 본문

학습

node.js로 웹서비스 만들기 (10. Table row 동적 추가, 삭제, 순서 변경하기)

길재의 그 정신으로 공부하자 2023. 7. 18. 11:11

 

개발하다보니 Table row를 동적으로 추가,삭제, 위치 변경해야 하는 이슈가 발생했습니다.

이번 글은 페이지 로딩 시 스크립트를 사용해 Table row를 추가하고 이후 동적으로 추가, 삭제, 위치를 변경하는 기능 구현한 과정을 기록한 글입니다.

 

ejs 파일 생성

우선 Table row를 표시할 ejs 파일을 아래와 같이 추가해줍니다.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
    <script src="//code.jquery.com/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.0/css/bootstrap-datepicker3.min.css">
    <script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.0/js/bootstrap-datepicker.min.js"></script>
    <script src="/js/bootstrap-datepicker.kr.js" charset="UTF-8"></script>
    <title>날짜별 퀴즈 등록하기</title>
  </head>
  <body>
    <div class="mt-3">
      <h4 class="text-center">날짜별 퀴즈 등록하기</h4>
    </div>
    <div class="text-right mr-3 mb-3 width=100px">
        <img src="https://d1.awsstatic.com/acs/characters/Logos/Docker-Logo_Horizontel_279x131.b8a5c41e56b77706656d61080f6a0217a3ba356d.png" style="width: 100px;">
        관리자님 반갑습니다.
        <button type="submit" class="btn btn-secondary" id="logout">로그아웃</button>  
    </div>
    <div class="container-fluid">
      <div class="row">
        ...
        <div class="col" style="background-color: #fff">
            <div class="input-group">
                <span class="input-group-text" style="width: 90px">현재 선택</span>
                <input id="selectedCount" type="text" class="form-control" value="전체: 0개 (오전: 0개, 오후: 0개)" disabled>
                
                <button type="button" class="btn btn-primary ml-3" id="done" style="width: 300px">등록 완료</button>  
            </div>

            <div class="input-group date mt-2">
                <span class="input-group-text" style="width: 90px">노출 날짜</span>
                <input type="text" id="datePicker" class="form-control"><span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
            </div>

            <div class="input-group mt-2">
                <button type="button" class="btn btn-danger" id="deleteSelect" style="width: 90px">선택 삭제</button>                  
                <div class="ml-5">
                    오전 퀴즈: 
                    <button type="button" class="btn btn-warning ml-1" id="addAmQuizFromList" style="width: 120px">목록에서 선택</button>
                    <button type="button" class="btn btn-warning ml-1" id="addAmQuizFromCreateOx" style="width: 110px">추가(OX퀴즈)</button>
                    <button type="button" class="btn btn-warning ml-1" id="addAmQuizFromCreateSngCho" style="width: 110px">추가(4지선다)</button>
                </div>
                <div class="ml-5">
                    오후 퀴즈: 
                    <button type="button" class="btn btn-warning ml-1" id="addPmQuizFromList" style="width: 120px">목록에서 선택</button>  
                    <button type="button" class="btn btn-warning ml-1" id="addPmQuizFromCreateOx" style="width: 110px">추가(OX퀴즈)</button>
                    <button type="button" class="btn btn-warning ml-1" id="addPmQuizFromCreateSngCho" style="width: 110px">추가(4지선다)</button>              
                </div>
            </div>

            <table id="dateQuizTable" class="table mt-2">
                <colgroup>
                    <col width='50'><col width='80'><col width='50'><col width='50'><col width='80'><col width='350'><col width='140'><col width='150'>
                </colgroup>
                <thead>
                    <tr>
                        <th>선택</th>
                        <th>오전/오후</th>
                        <th>순서</th>
                        <th>ID</th>
                        <th>퀴즈 타입</th>
                        <th>퀴즈 내용</th>
                        <th>퀴즈 등록일</th>
                        <th>순서 변경</th>
                    </tr>
                </thead>
                <tbody id="dateQuizTableBody">
                </tbody>
            </table>
        </div>    
      </div>
    </div>    
  </body>
</html>

 

 

ejs를 사용해 페이지 로딩 시 table row 생성

ejs 문법을 사용해 html내에서 페이지 로딩 시 아래와 같이 table row를 추가할 수 있습니다.

<table class="table">
	<colgroup>
		<col width='80'><col width='90'><col width='150'><col width='400'><col width='400'><col width='80'>
    </colgroup>
    <thead>
    	<tr>
        	<th>NO.</th>
            <th>타입</th>
            <th>등록일</th>
            <th>퀴즈 내용</th>
            <th>정답 설명</th>
            <th>관리</th>
    	</tr>
	</thead>
    <tbody>
    	<% for(i = 0; i < list.length; i++) { %>
        <tr>
        	<td><%=list[i].qid %></td>
            <td>
            	<%if(list[i].type == 0){%>
            		OX
	            <%}else if(list[i].type == 1){%>
    	            4지선다
        	    <%}%>
            </td>
            <td><%=list[i].createdAt %></td>
            <td><%=list[i].contents %></td>
            <td><%=list[i].comment %></td>
            <td>
            	<button type="button" class="btn btn-warning click" style="width: 100px" onClick="actionDetail(<%=list[i].qid %>)">자세히보기</button>
            </td>
		</tr>
        <% } %>
	</tbody>
</table>

 

하지만 제가 원하는 것은 페이지 로딩 시 테이블을 생성하고 끝나는게 아니라 사용자 액션에 맞게 테이블이 동적으로 변화하는 것이므로 jQuery를 사용해 table row를 추가, 삭제 그리고 순서 변경을 해보도록 하겠습니다.

 

jQuery를 사용해 Table row 추가

html 코드를 작성했으면 같은 파일에 동적으로 Table row를 추가해주는 코드를 추가합니다.

<script>
    // 테이블 row 모두 제거
    $("#dateQuizTableBody").empty();

    // 테이블에 추가할 퀴즈 아이템을 가져옴.
    var items = getItems('quizItems');
    // jQuery의 each메소드를 사용하여 테이블에 row 추가
    $.each(items, function(index, element){
    	// row html 코드 생성
        var innerHtml = "";
        innerHtml += '<tr>';
        innerHtml += '  <td> <input class="form-check-input ml-2" type="checkbox" value="" name="checkSelected"> </td>';
        innerHtml += '  <td>' + element.ampm + '</td>';
        innerHtml += '  <td>' + (index + 1) + '</td>';
        innerHtml += '  <td>' + element.qid + '</td>';
        innerHtml += '  <td>' + element.type + '</td>';
        innerHtml += '  <td>' + element.contents + '</td>';
        innerHtml += '  <td>' + element.createdAt + '</td>';
        innerHtml += '  <td><button type="button" class="btn btn-warning click" style="width: 60px" onClick="actionUp(' + element.qid + ')">위로</button><button type="button" class="btn btn-warning click ml-1" style="width: 60px" onClick="actionDown(' + element.qid + ')">아래로</button></td>';
        innerHtml += '</tr>';
        // 테이블 row 추가 (맨끝에 추가됨.)
        $("#dateQuizTableBody").append(innerHtml);
    });
</script>

 

위치 지정해서 table row 추가하기

// row html 코드 생성
var insertIndex = 2;
var innerHtml = "";
innerHtml += '<tr>';
innerHtml += '  <td> <input class="form-check-input ml-2" type="checkbox" value="" name="checkSelected"> </td>';
innerHtml += '  <td>' + element.ampm + '</td>';
innerHtml += '  <td>' + (index + 1) + '</td>';
innerHtml += '  <td>' + element.qid + '</td>';
...
innerHtml += '</tr>';
// 테이블의 두번째로 row 추가되므로 eq(2)의 before() 메소드를 사용해야 함.
$("#dateQuizTableBody > tr").eq(insertIndex).before(innerHtml);

 

table row 순서 변경하기 (clone 메소드를 사용)

clone 메소드를 사용하여 테이블의 두번째 row를 한칸 위로 이동하는 코드를 작성해보도록 하겠습니다.

var currentIndex = 1; 
var tb = $("#dateQuizTableBody");
var tr = tb.children();
var cloneTr = td.clone(true); // 추가할 table row 클론 생성
$("#dateQuizTableBody > tr:eq(" + (currentIndex-1) + ") td:eq(0)”).html(currentIndex); // 이전 row 현재 인덱스로 변경
$("#dateQuizTableBody > tr").eq(currentIndex).remove(); // 기존 위치 row 제거
$("#dateQuizTableBody > tr").eq(currentIndex-1).before(cloneTr); // 클론을 이동할 위치에 추가

 

이렇게 했을 때 처음은 잘 되는데 두번째부터 아래 테이블 row 계산 jQuery에 문제가 생겼습니다.

   var trCount = $("#dateQuizTableBody tr").length;

디버깅을 해보니 remove() 메소드 때문인 것으로 확인되었고 이를 해결하기 위해 삽질하다가 결국 clone 메소드 사용을 포기하고 

아래와 같이 작업해주었습니다.

var currentIndex = 1; 
var innerHtml = "";
innerHtml += '<tr>';
innerHtml += '  <td>' + (currentIndex-1) + '</td>';
innerHtml += '  <td>' + contents + '</td>';
...
innerHtml += '</tr>';
$("#dateQuizTableBody > tr:eq(" + (currentIndex-1) + ") td:eq(0)”).html(currentIndex); // 이전 row 현재 인덱스로 변경
$("#dateQuizTableBody > tr").eq(currentIndex).remove(); // 기존 위치 row 제거
$("#dateQuizTableBody > tr").eq(i-1).before(innerHtml);

 

추가. table의 row 값 가져오는데 사용한 jQuery

아래와 같이 테이블 row length을 알아 낸 후 for 문을 사용하여 값을 가져왔습니다.

추가. Row 위치 변경에서 기존 값 가져오는데 사용한 방법
var trCount = $("#dateQuizTableBody tr").length;  // row 갯수
var tb = $("#dateQuizTableBody");
var tr = tb.children();
for(i=0;i<trCount; i++){
	var td = tr.eq(i).children();           
    var index = td.eq(0).text();
    var contents= td.eq(1).text();
    ...
}

 

Comments