Programming/JavaScript

[Javascript] table에 동적으로 행(row), 열(column)추가, 삭제하기, td 너비 일정하게 유지하기

 

See the Pen Dynamic generation Table Row by BEGINNERWW (@beginnerww) on CodePen.

 

 

 

<table>태그에 동적으로 row(행) 추가하기

 

    - 본 코드는 10줄씩 출력되고 페이징 기능을 고려하여 작성하였다.

 

추가 클릭 이벤트 onClick="userAdd()"  

 

 1. var trCnt = document.getElementsByTagName('tr').length;

    -  tr 태그의 갯수를 구한다.

 2. 기존에 입력되어있는 데이터가 있을 경우 해당 데이터의 index를 담고 있는 변수 baseCamp를 trCnt에 대입한다.

 3. row가 10줄이상이 된 시점(즉, 11행)이 되었을때 첫번째 row 를 숨긴다.

 4. $('#tbHead').after(inner);

   - thead 아래 tr을 추가한다.

1	var targetBtn = event.target;
2	var parentTr = targetBtn.parentNode.parentNode;
3	var tdNode = parentTr.childNodes;
4	var tdArr = new Array();

5	for(var i = 0; i < tdNode.length; i++){
6		tdArr.push(tdNode[i].textContent);		
	}

 

수정 클릭 이벤트 function onClickUpdate()

 

 1줄 event.target >> click event를 실행된 객체, 즉 수정btn 자체를 의미한다.

 2줄 수정btn의 부모노드 td의 부모노드 tr

 3줄 클릭한 버튼이 있는 tr의 자식노드(td들)

 4~6줄 tdNode에서 td의 값, 우리눈에 보이는 텍스트 값을 가져오기 위해 array 객체를 생성하고 반복문을 통해 배열 객체에 담아준다.

 

취소 클릭 이벤트 function onClickCancle(trCnt)

 

 1. var row = document.querySelectorAll('.updateRow');

   - 수정 클릭 후 취소 이벤트인지 추가 클릭 후 취소 이벤트인지 확인할 수 있도록 수정 클릭시 class=updateRow를 추가해주었었다.

   - 해당 클래스를 모두 찾아 row에 대입한다. 

 2. 입력칸이 활성화되어있는 row를 삭제한다.

 3. row가 11줄일 때 숨겨두었던 첫번째 row를 보여준다.

 4. 수정 중인 tr의 숫자 즉, 변수 row가 값을 가지고 있을때

    .updateRow 인 노드를 보여주고, 해당 tr에 추가되었던 updateRow 클래스를 삭제한다.


1,2,3 모두 동적으로 생성한 table

 

ajax로 받아온 데이터를 바탕으로 동적으로 table 생성하기

 

- 조회조건이 회사, 기간이었기 때문에 해당 table은 thead부분과 모듈명이 조건에 따라 다르게 적용된다.

- 따라서 row와 column 모두 정해진 갯수가 없어 테이블 데이터를 모두 동적으로 넣어주었다.

 

 

1. 기준이 되는 기간과 모듈을 테이블에 넣어준다.

 

 

2. 데이터 넣어주기

 

See the Pen 테이블1 by anna (@hianna) on CodePen.

   function addColumn() {
1     const table = document.getElementById('fruits');
  
2     for(let i = 0; i < table.rows.length; i++)  {
3        const newCell =table.rows[i].insertCell(-1);
4        newCell.innerText = 'New';
     }
   }

이 코드를 보고 참고해서 구현했다.

 

1줄 .getElementById로 table element를 찾아 변수 table에 대입한다.

2줄 table.rows.length 테이블 row 수 만큼 반복한다.

3~4줄 table.rows[i]에 가장 뒤에 cell(td)를 추가하고 태그 안에 텍스트 'New' 를 넣어준다.

 

1. 테이블에 행 추가/삭제 - insertRow(idx), deleteRow(idx)
2. 테이블에 셀 추가/삭제 - insertCell(idx), deleteCell(idx)

default 값은 모두 -1이고 insertRow(), insertCell() 은 새로 추가된 요소를 가리키는 reference를 리턴한다.
-1은 가장 마지막에 추가/삭제를 실행하고, 가장 첫번째에 이벤트가 발생하려면 인덱스를 0으로 주면된다.

 

ajax success 전체 코드 보기 👇👇👇 

더보기

var moduleList = result[0].moduleList;
var regdata = result[0].regdata;
var completeData = result[0].completeData;
var date = [];
var start = [];
var end = []

if(selectOpt == 'week'){
  for(var i = 0; i < result[0].regdata.length; i++){
    date.push(regdata[i].RCEPT_DT);
    start.push(regdata[i].START);
    end.push(regdata[i].END);
  }
}else{
  for(var i = 0; i < result[0].regdata.length; i++){
   date.push(regdata[i].RCEPT_DT);
  }
}

date = Array.from(new Set(date));
date.sort();
if(date[0] == 0){
   date.splice(0,1);
}

var str = '';
var head = '<tr><th rowspan=2>모듈명</th>';
$.each(date, function(index, value){
   head += '<th colspan=3>'+ value + '</th>';
})
head += '</tr>';
$('#tbHead').append(head);

var table = document.getElementById('srState');
head='<tr>'
var newCell = table.rows[0].insertCell(-1);
for(var i = 0; i < date.length; i++){
   head +='<th>접수</th><th>완료</th><th>완료율</th>';
}
head += '</tr>';
$('#tbHead').append(head);

for(var i = 1 ; i < moduleList.length ; i++){
    str += '<tr id="'+ moduleList[i].DETAIL_CD +'"><td>'+ moduleList[i].DETAIL_CD_NM+"</td></tr>";
}
$("#srState").append(str);

 

mkTable(result, selectOpt, date);

 

function mkTable(result, modules, selectOpt, date){
  var regdata = result[0].regdata;
  var completeData = result[0].completeData;
  var table = document.getElementById('srState');
  var newCell;
  var cnt;
  var j = 0, k = 0, l = 0;

  for(var col = 0; col < date.length; col++){
      cnt = 1;

      for(var i = 2; i < table.rows.length && cnt < 4; i++){
      //접수
          if(cnt == 1){
              newCell = table.rows[i].insertCell(-1);
              newCell.innerHTML = '<td>'+ regdata[j].REG+'</td>';
              j++;

              if( i == (table.rows.length-1)){
                   cnt++;
                   i = 1;
               }
      //완료
         }else if(cnt == 2){
            newCell = table.rows[i].insertCell(-1);
            newCell.innerHTML = '<td>'+ completeData[k].REG+'</td>';
            k++

            if( i == (table.rows.length-1)){
                cnt++;
                i = 1;
            }
      //완료율
         }else if(cnt == 3){
            var per = '0%';
            if(parseInt(completeData[l].REG) != 0){
                per = (completeData[l].REG / regdata[l].REG * 100) + '%';
            }
            newCell = table.rows[i].insertCell(-1);
            newCell.innerHTML = '<td>'+ per +'</td>';
            l++;
 
            if( i == (table.rows.length-1)){
               cnt++;
            }  
        }
     }
  }
}

 

날짜가 많아서 테이블 width가 길어져 scroll이 자동으로 나오게 css 수정했으나 td 크기에 맞게 쪼그라들어 보이는 문제가 발생했다.

예전에 동적으로 만든 태그에 상위 요소의 width, height를 정의하지 않아서 고정이 안되었던적이 있어서

인라인 방식으로 tr, td, table ... 기타 등등 확인하고 추가했는데 사이즈가 반영되지 반영되지 않았다.

 

<colgroup>
	<col width = "16.6%">
	<col width = "16.6%">
	<col width = "16.6%">
	<col width = "16.6%">
	<col width = "16.6%">
	<col width = "16.6%">
</colgroup>

 

이 문제점을 해결하기 위해 colgroup은 사용할수 없다, 컬럼의 갯수가 정해져있지 않고 기간 설정에 따라 달라지기 때문이다.

 

colgroup 은 table의 컬럼의 일정한 width를 주어 일정한 간격을 유지하게 해준다.

그러나, 글자가 넘치는 것을 방지할수 없다.

 

 

table 태그의 css에 style="table-layout: fixed; word-break:break-all;" 추가를 해주면 cell size가 고정되면서 자동으로 줄바꿈도 된다.

 

table-layout : fixed; cell size를 고정해준다.

word-break : break-all; 글자수가 cell size보다 넘칠경우 자동으로 줄바꿈해준다.

 

 


출처 👇👇👇