본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Javascript/[중요] Javascript

Jquery auto table rowSpan(Jquery 자동 테이블 병합, 자동 table rowspan)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2020. 11. 18.

Jquery를 활용하여 자동으로 같은 데이터를 병합해야되는 일이 생겼습니다.

테이블을 병합해야 되는 경우는 대략 아래와 같았습니다.

0번과 1번 열에 대해서 자동으로 같은 텍스트를 병합해야 했습니다.

 

데이터가 고정적이면 사실 어렵지 않습니다.

그냥 td테그에 rowSpan값을 주면 해결되는 일이기 때문 입니다.

그런데, 데이터가 동적으로 변경되는 경우였기 때문에 그렇게 할 수가 없었습니다..ㅠ

 

작업을 하기에 앞서서 조건을 먼저 판단하여 보았습니다.

* 최초 조건
1. 테이블을 최조 검사하는 행위인지
2. tr 내부의 td의 텍스트가 같은지
3. tr 내부의 td의 텍스트가 다른지

 

테이블을 병합하려면 td테그에서 rowspan 속성에 값을 부여하여야 합니다.

그리고 1번 ~ 3번까지의 경우에 대해서 반복문을 위해서 Jquery의 find와 each함수를 사용 하였습니다.

위 조건에서 td 태그에 rowSpan속성을 부여해야되는 경우는 2가지 경우입니다.

1. 테이블을 최조 검사하는 행위인지
2. tr 내부의 td의 텍스트가 같은지
  2-1. 같은 열의 형테인데 tr의 인덱스가 테이블의 마지막 길이와 같다면 (그려라!)
3. tr 내부의 td의 텍스트가 다른지
  3-1. 1번 또는 2번의 경우가 실행되고 나서 들어온 경우인지 (그려라!)

 

먼저 조건문을 만들었습니다.

var loop = null;  //텍스트 이름을 담을 변수 입니다.
var start_idx = 0;  //최초 td테그의 인덱스를 담을 변수 입니다.
var add_num = 1;    //마지막 td 테그의 인덱스를 담을 변수 입니다.
$(target).find('tr').each(function (idx) {
    var target_text = $(this).find('td').eq(index).text();
    if (!loop) {  //최초 동작이면
        loop = target_text;
        start_idx = idx;
    } else if (target_text == loop) {  //같은 열이 발견된 것 이라면
        //같은열이긴 한데 근데 마지막이면
        if (idx == $(target).find('tr').length - 1) {

        }
    } else { //다른 텍스트가 발견된 것 이라면
        if (머지필요) {    //머지가 필요한 경우라면
        }
    }
});

 

최초 동작인 경우에는 대상 td의 텍스트를 바로 담아주었습니다.

다음 비교문에서는 같은 열인경우와 같은 열인데 테이블의 마지막 크기와 같은 경우를 넣어주었습니다.

2개의 조건에 맞지 않다면 다른 텍스트가 발견된 것이며,

다른 텍스트가 발견되었는데 머지가 필요한 경우를 추가하였습니다.

 

그러면 위 조건에 따라서 내용을 채워봅니다.

function mergeTable(target, index) {
    var loop = null;
    var start_idx = 0;  //최초 td테그의 인덱스를 담을 변수 입니다.
    var add_num = 1;    //마지막 td 테그의 인덱스를 담을 변수 입니다.
    $(target).find('tr').each(function (idx) {
        var target_text = $(this).find('td').eq(index).text();
        if (!loop) {  //최초 동작이면
            loop = target_text;
            start_idx = idx;
        } else if (target_text == loop) {  //같은 열이 발견된 것 이라면
            add_num++;
            //같은열이긴 한데 근데 마지막이면
            if (idx == $(target).find('tr').length - 1) {
                $(target).find('tr').eq(start_idx).find('td').eq(index).attr("rowSpan", add_num).css('vertical-align', 'middle');
                for (var i = start_idx + 1; i < start_idx + add_num; i++) {
                    $(target).find('tr').eq(i).find('td').eq(index).remove();
                }
            }
        } else { //다른 텍스트가 발견된 것 이라면
            if (add_num != 1) {    //머지가 필요한 경우라면
                $(target).find('tr').eq(start_idx).find('td').eq(index).attr("rowSpan", add_num).css('vertical-align', 'middle');
                for (var i = start_idx + 1; i < start_idx + add_num; i++) {
                    $(target).find('tr').eq(i).find('td').eq(index).remove();
                }
            }
            start_idx = idx;
            loop = target_text;
            add_num = 1;
        }
    });
}

 

위 코드는 실제로 동작하는데 문제는 없습니다.

그런데 해당 함수를 2번이상 호출하면 remove()에 의해서 인덱스 계산이 매우 어려워 집니다.

그러므로 해당 부분을 hide로 바꾸어 줍니다.

function mergeTable(target, index) {
    var loop = null;
    var start_idx = 0;  //최초 td테그의 인덱스를 담을 변수 입니다.
    var add_num = 1;    //마지막 td 테그의 인덱스를 담을 변수 입니다.
    $(target).find('tr').each(function (idx) {
        var target_text = $(this).find('td').eq(index).text();
        if (!loop) {  //최초 동작이면
            loop = target_text;
            start_idx = idx;
        } else if (target_text == loop) {  //같은 열이 발견된 것 이라면
            add_num++;
            //같은열이긴 한데 근데 마지막이면
            if (idx == $(target).find('tr').length - 1) {
                $(target).find('tr').eq(start_idx).find('td').eq(index).attr("rowSpan", add_num).css('vertical-align', 'middle');
                for (var i = start_idx + 1; i < start_idx + add_num; i++) {
                    $(target).find('tr').eq(i).find('td').eq(index).hide(); //hide로 변경
                }
            }
        } else { //다른 텍스트가 발견된 것 이라면
            if (add_num != 1) {    //머지가 필요한 경우라면
                $(target).find('tr').eq(start_idx).find('td').eq(index).attr("rowSpan", add_num).css('vertical-align', 'middle');
                for (var i = start_idx + 1; i < start_idx + add_num; i++) {
                    $(target).find('tr').eq(i).find('td').eq(index).hide(); //hide로 변경
                }
            }
            start_idx = idx;
            loop = target_text;
            add_num = 1;
        }
    });
}

 

실제로 동작해 본 화면 입니다.

0번과 2번 인덱스에 대해서 병합을 해 보았습니다.

 

문제없이 잘 동작하는 것을 볼 수 있습니다.

알고리즘 자체가 크게 어렵지 않으므로 부가적인 기능을 붙이기에도 용이합니다.

 

데이터가 동적으로 변하면서 병합이 요구되면, 이러한 방법을 통해서 해결 가능합니다.

물론, 다른 플러그인을 사용해도 무방하겠습니다!

Jquery를 활용하여 테이블 내부에 열 병합(table rowspan)에 대해서 간단하게 살펴 보았습니다.

 

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글