2008. 12. 9. 12:28

[javascript : merge]

   
원래는 java에 대한 FAQ를 계속 작성할려고 했는데, 실력도 안되고 해서....
     님들은 jsp프로젝트에서 jsp의 비율이 어느정도 된다고 생각하시나요?
     제 개인적인 생각은 jsp는 20%정도 밖에는 안된다고 생각합니다.
    오히려, javascript가 30%, SQL이 40%이상 되지 않을까 생각하는데요.
    물론, 재 개인 의견이지마요. 그래서, javascript, sql에 대해서도 한번씩 정리
    하려고 합니다.(핑계임.)

     프로젝트를 하다 보면, 쿼리의 결과를 리스트로 보여주어야 할때
    많은 경우 merge를 해야하는 경우가 발생합니다. (없었다면 할 수 없구요)

     예로 다음과 같은 데이타의 결과를 보여주는 화면이 있습니다.
    =========================================
    대분류 | 중분류 | 소분류 | 상품
    -----------------------------------------
      A      |   가     |   1       | TEST
    -----------------------------------------
      A      |   가     |   2       | TEST1
    -----------------------------------------
      A      |   나     |   1       | TEST2
    -----------------------------------------
      B      |   가     |   1       | TEST3
    -----------------------------------------
      B      |   가     |   2       | TEST4
    =========================================
    (표1)

     그런데, 사용자가 원하는 화면은 아래의 표2와 같습니다..
    =========================================
    대분류 | 중분류 | 소분류 | 상품
    -----------------------------------------
             |           |   1       | TEST
             |  가      -------------------------
      A     |           |   2       | TEST1
             ----------------------------------
             |   나     |   1       | TEST2
    -----------------------------------------
             |           |   1       | TEST3
      B     |  가      -------------------------
             |           |   2       | TEST4
    =========================================
    (표2)
     표2와 같은 화면은 HTML의 table로 구성하기가 어렵습니다.
     이유는 먼저 rowspan 값을 정해 주어야 하는데, 한개씩 row를 가져와서 몇개를
    rowspan할 것인지 판단하는 것은 배보다 배꼽이 더 큽니다.

     좀 착한 사용자를 만난다면 맨 위의 표1나 아래의 표3에 만족해 줄 수도 있습니다.
    =========================================
    대분류 | 중분류 | 소분류 | 상품
    -----------------------------------------
      A      |   가     |   1      | TEST
    -----------------------------------------
              |           |   2      | TEST1
    -----------------------------------------
              |   나     |   1      | TEST2
    -----------------------------------------
      B      |   가     |   1      | TEST3
    -----------------------------------------
              |           |   2      | TEST4
    =========================================
    (표3)

     저 같은경우도 표3과 같은형태로 많이 작없했습니다. 전 표3의 형태가 가장 보기가
    좋았는데요. 하지만, 이 경우도 대,중,소,세등 컬럼이 많아질 경우 코드가 복잡해
    집니다.

    그래서, jsp에서는 표1처럼 뿌려주면, javascript에서 표2처럼 변경하게 만들었습니다.
    소스는 길지 않습니다. 그냥 보면 이해가 갈꺼라고 생각합니다.
    (주석,설명이 귀찮아서 핑계입니다.)
    ----------------------------------------------------------------------------
    <SCRIPT>
    /****************************************************
        tbl      : 병합할 대상 table object
        startRow : 병합 시작 row, title 한 줄일 경우 1
        cNum     : 병합 실시할 컬럼번호, 0부터 시작
        length   : 병합할 row의 길이, 보통 1
        add      : 비교할 기준에 추가할 컬럼번호
                  A | 1
                  B | 1
                 을 서로 구분하고 싶다면, add에 0번째
                 컬럼을 추가
    *****************************************************/
    function mergeCell(tbl, startRow, cNum, length, add)
    {
        var isAdd = false;
        if(tbl == null) return;
        if(startRow == null || startRow.length == 0) startRow = 1;
        if(cNum == null || cNum.length == 0) return ;
        if(add  == null || add.length == 0) {
            isAdd = false;
        }else {
            isAdd = true;
            add   = parseInt(add);
        }
        cNum   = parseInt(cNum);
        length = parseInt(length);

        rows   = tbl.rows;
        rowNum = rows.length;

        tempVal  = '';
        cnt      = 0;
        startRow = parseInt(startRow);

        for( i = startRow; i < rowNum; i++ ) {
            curVal = rows[i].cells[cNum].innerHTML;
            if(isAdd) curVal += rows[i].cells[add].innerHTML;
            if( curVal == tempVal ) {
                if(cnt == 0) {
                    cnt++;
                    startRow = i - 1;
                }
                cnt++;
            }else if(cnt > 0) {
                merge(tbl, startRow, cnt, cNum, length);
                startRow = endRow = 0;
                cnt = 0;
            }else {
            }
            tempVal = curVal;
        }

        if(cnt > 0) {
            merge(tbl, startRow, cnt, cNum, length);
        }
    }

    /*******************************************
        mergeCell에서 사용하는 함수
    ********************************************/
    function merge(tbl, startRow, cnt, cellNum, length)
    {
        rows = tbl.rows;
        row  = rows[startRow];

        for( i = startRow + 1; i < startRow + cnt; i++ ) {
            for( j = 0; j < length; j++) {
                rows[i].deleteCell(cellNum);
            }
        }
        for( j = 0; j < length; j++) {
            row.cells[cellNum + j].rowSpan = cnt;
        }
    }


/*******************************************

 * 공백병합 표3의 경우에 사용.

 * tbl      : 병합할 대상 table object

 * startRow : 병합 시작 row, title 한 줄일 경우 1

 * cNum     : 병합 실시할 컬럼번호, 0부터 시작

* 예) mergeCellSpace($('list_tbl'), 1, 1);

 *******************************************/

function mergeCellSpace(tbl, startRow, cNum) {

if(tbl == null) return;

    if(startRow == null || startRow.length == 0) startRow = 1;

    if(cNum == null || cNum.length == 0) return ;

    

var rows = tbl.rows;

    var targetCell;

    var cnt = 1;

    for(var i = startRow; i < rows.length; i++ ) {

     var cell = rows[i].cells[cNum];

     if(cell.innerHTML.length > 0) {

     if(cnt > 1) {

     targetCell.rowSpan = cnt;

     cnt = 1;

     }

     targetCell = cell;

     }else {

     cnt++;

     rows[i].deleteCell(cNum);

     }

    }

    if(cnt > 1) targetCell.rowSpan = cnt;

}

    </SCRIPT>
    ----------------------------------------------------------------------------
    예제는 파일에 첨부합니다.

==================================================
최초작성일 : 2002년 1월 29일
최종수정일 : 2008년12월  9일
--------------------------------------------------
  본 문서는 자유롭게 배포/복사 할 수 있으나 반드시
  이 문서의 저자에 대한 언급을 삭제하시면 안됩니다.
  (이 내용은 javaservice.net에서 copy.)
--------------------------------------------------
  이호훈(siva6)
  E-mail: siva6@dreamwiz.com
==================================================

 

-------------------------------------------------------------------------------

대분류 중분류 소분류 상품
A 1 TEST
2 TEST1
1 TEST2
B 1 TEST3
2 TEST4

-------------------------------------------------------------------------------

[출처] [javascript : merge]|작성자 시바