-
[Javascript] Table Cell Merge(테이블 셀 병합) - 중복값 처리나는야 개발자/Javascript 2022. 4. 4. 17:26
오늘은 내가 프로젝트를 진행하면서 표와 관련되어 큰 필요성을 느꼈던 한 가지를 정리하려고 한다.
의외로 많은 분들이 공감하는 부분중 하나일테니 두고두고 써먹자 !!
(나도 두고두고 써먹기)중요도 : ★★★☆☆
바로바로 ~~
TABLE CELL MERGE !! a.k.a 중복값 병합
좋은 plugin을 사용한다면 큰 무리없을 수도 있으나,
내가 하나부터 열까지 주먹구구식으로 개발을 해야한다면 그야말로 큰 어려움이 아닐수가 없다 ㅜㅜ
* 특히!! 띄엄띄엄 위치해 있는 반복된 값들에 대한 처리는 더더욱 어려울 것이다.
바로 시작해보자...
우선 test용 코드를 작성해보자 !!
[작성 예시]
<!doctype html> <html> <head> <script src="https://code.jquery.com/jquery-latest.min.js"></script> <style> table{ border-collapse: collapse; border: 1px solid black; } table th, table td{ border: 1px solid black; text-align: center; padding: 15px 30px; } </style> </head> <div> <table> <thead> <tr> <th>이름</th> <th>학번</th> <th>과목</th> <th>점수</th> </tr> </thead> <tbody> <tr> <td>권영진</td> <td>20220404</td> <td>사회</td> <td>98</td> </tr> <tr> <td>권영진</td> <td>20220404</td> <td>국어</td> <td>100</td> </tr> <tr> <td>궈녕진</td> <td>20220404</td> <td>물리</td> <td>92</td> </tr> <tr> <td>거녕진</td> <td>20220404</td> <td>영어</td> <td>92</td> </tr> <tr> <td>거녕진</td> <td>20220404</td> <td>영어</td> <td>92</td> </tr> <tr> <td>궈녕진</td> <td>20220404</td> <td>수학</td> <td>96</td> </tr> <tr> <td>궈녕진</td> <td>20220404</td> <td>화학</td> <td>96</td> </tr> </tbody> </table> </div> <script> // 테이블을 병합하는 FUNCTION function mergeCell(idx){ let tr_all = document.querySelectorAll('tbody > tr'); let compare_text = null, select_text = null; let all_tr_list = [], current_tr_list = []; tr_all.forEach((tr)=>{ let tr_idx = tr.rowIndex; if(compare_text == null){ current_tr_list.push(tr); compare_text = $(tr).find('td').eq(idx).text(); }else{ select_text = $(tr).find('td').eq(idx).text(); if(select_text == compare_text){ current_tr_list.push(tr); }else{ all_tr_list.push(current_tr_list); current_tr_list = [tr]; compare_text = select_text; } } // 전체 tr의 길이와 선택된 tr의 index가 일치할 경우 (끝) if(tr_idx === tr_all.length){ all_tr_list.push(current_tr_list); all_tr_list.forEach((current_tr_list)=>{ if(current_tr_list.length > 1){ current_tr_list.forEach((current_tr,current_tr_idx)=>{ if(current_tr_idx == 0) $(current_tr).find('td').eq(idx).prop('rowSpan', current_tr_list.length); else $(current_tr).find('td').eq(idx).hide(); }) } }) } }) } </script> </html>
작성 코드를 실행시켜보자 !!
[결과 화면]
이를 조금더 편리(?)하게 사용하려면,
받는 Index를 List형태로 하여 처음부터 반복적으로 Cell Merge가 발생하도록 하면 되겠다.
[작성 예시]
<!doctype html> <html> <head> <script src="https://code.jquery.com/jquery-latest.min.js"></script> <style> table{ border-collapse: collapse; border: 1px solid black; } table th, table td{ border: 1px solid black; text-align: center; padding: 15px 30px; } </style> </head> <div> <table> <thead> <tr> <th>이름</th> <th>학번</th> <th>과목</th> <th>점수</th> </tr> </thead> <tbody> <tr> <td>권영진</td> <td>20220404</td> <td>사회</td> <td>98</td> </tr> <tr> <td>권영진</td> <td>20220404</td> <td>국어</td> <td>100</td> </tr> <tr> <td>궈녕진</td> <td>20220404</td> <td>물리</td> <td>92</td> </tr> <tr> <td>거녕진</td> <td>20220404</td> <td>영어</td> <td>92</td> </tr> <tr> <td>거녕진</td> <td>20220404</td> <td>영어</td> <td>92</td> </tr> <tr> <td>궈녕진</td> <td>20220404</td> <td>수학</td> <td>96</td> </tr> <tr> <td>궈녕진</td> <td>20220404</td> <td>화학</td> <td>96</td> </tr> </tbody> </table> </div> <script> // 테이블을 병합하는 FUNCTION function mergeCell(idxList){ let tr_all = document.querySelectorAll('tbody > tr'); let compare_text = null, select_text = null; let all_tr_list = [], current_tr_list = []; idxList.forEach((idx)=>{ tr_all.forEach((tr)=>{ let tr_idx = tr.rowIndex; if(compare_text == null){ current_tr_list.push(tr); compare_text = $(tr).find('td').eq(idx).text(); }else{ select_text = $(tr).find('td').eq(idx).text(); if(select_text == compare_text){ current_tr_list.push(tr); }else{ all_tr_list.push(current_tr_list); current_tr_list = [tr]; compare_text = select_text; } } // 전체 tr의 길이와 선택된 tr의 index가 일치할 경우 (끝) if(tr_idx === tr_all.length){ all_tr_list.push(current_tr_list); all_tr_list.forEach((current_tr_list)=>{ if(current_tr_list.length > 1){ current_tr_list.forEach((current_tr,current_tr_idx)=>{ if(current_tr_idx == 0) $(current_tr).find('td').eq(idx).prop('rowSpan', current_tr_list.length); else $(current_tr).find('td').eq(idx).hide(); }) } }) } }) }) } </script> </html>
실행 시켜보자
[결과 화면]
이렇게 두가지 방식(?)에 대해 작성하고 테스트를 진행해 보았다.
해당 함수를 사용할 때에는 기본적으로 merge할 data는 sort를 하여 가져오는 것으로, merge 시킬 준비를 해주는것이 좋다 !!
-- 참조를 하였다면 출처를 밝혀주시고, 사용 시 댓글에 감사 인사 달아주시면 큰 힘이 됩니다 !!
-- 모두가 한 단계 더 성장 할 수 있기를 바랍니다.
* thead의 tr의 수가 늘어나면 늘어난 수 만큼 tbody의 tr이 rowspan되지 않는 문제가 있어 아래와 같이 코드를 수정하였습니다. 참고 바랍니다 !
<!doctype html> <html> <head> <script src="https://code.jquery.com/jquery-latest.min.js"></script> <style> table{ border-collapse: collapse; border: 1px solid black; } table th, table td{ border: 1px solid black; text-align: center; padding: 15px 30px; } </style> </head> <div> <table id="target"> <thead> <tr> <th>이름</th> <th>학번</th> <th>과목</th> <th>점수</th> </tr> </thead> <tbody> <tr> <td>권영진</td> <td>20220404</td> <td>사회</td> <td>98</td> </tr> <tr> <td>권영진</td> <td>20220404</td> <td>국어</td> <td>100</td> </tr> <tr> <td>궈녕진</td> <td>20220404</td> <td>물리</td> <td>92</td> </tr> <tr> <td>거녕진</td> <td>20220404</td> <td>영어</td> <td>92</td> </tr> <tr> <td>거녕진</td> <td>20220404</td> <td>영어</td> <td>92</td> </tr> <tr> <td>궈녕진</td> <td>20220404</td> <td>수학</td> <td>96</td> </tr> <tr> <td>궈녕진</td> <td>20220404</td> <td>화학</td> <td>96</td> </tr> </tbody> </table> <table id="target2"> <thead> <tr> <th>이름</th> <th>학번</th> <th>과목</th> <th>점수</th> </tr> </thead> <tbody> <tr> <td>권영진</td> <td>20220404</td> <td>사회</td> <td>98</td> </tr> <tr> <td>권영진</td> <td>20220404</td> <td>국어</td> <td>100</td> </tr> <tr> <td>궈녕진</td> <td>20220404</td> <td>수학</td> <td>96</td> </tr> <tr> <td>궈녕진</td> <td>20220404</td> <td>화학</td> <td>96</td> </tr> </tbody> </table> </div> <script> // 테이블을 병합하는 FUNCTION function mergeCell(tableId, idxList){ let tr_all = document.getElementById(tableId).querySelectorAll('tbody > tr'), tr_last_index = tr_all[tr_all.length - 1].rowIndex; let compare_text = null, select_text = null; let all_tr_list = [], current_tr_list = []; idxList.forEach((idx)=>{ tr_all.forEach((tr)=>{ let tr_idx = tr.rowIndex; if(compare_text == null){ current_tr_list.push(tr); compare_text = $(tr).find('td').eq(idx).text(); }else{ select_text = $(tr).find('td').eq(idx).text(); if(select_text == compare_text){ current_tr_list.push(tr); }else{ all_tr_list.push(current_tr_list); current_tr_list = [tr]; compare_text = select_text; } } // 전체 tr의 길이와 선택된 tr의 index가 일치할 경우 (끝) if(tr_idx === tr_last_index){ all_tr_list.push(current_tr_list); all_tr_list.forEach((current_tr_list)=>{ if(current_tr_list.length > 1){ current_tr_list.forEach((current_tr,current_tr_idx)=>{ if(current_tr_idx == 0) $(current_tr).find('td').eq(idx).prop('rowSpan', current_tr_list.length); else $(current_tr).find('td').eq(idx).hide(); }) } }) } }) }) } </script> </html>
감사합니다 !!
'나는야 개발자 > Javascript' 카테고리의 다른 글
[Javascript/기초] 변수 선언(const/var/let) (0) 2022.03.08