본문 바로가기
개발/React

리액트 - Handsontable Customization Options (Merge Cells, 셀 합치기)

by 피로물든딸기 2023. 9. 29.
반응형

리액트 전체 링크

 

참고

- 로컬 스토리지 사용 방법과 세션 스토리지 비교

 

- Project Settings (전체 코드)

- True / False Options

- Selected Options

- Number Options

- width, height, placeholder, sort

- 주석, comment, memo, tooltip

- Merge Cells, 셀 합치기

- Search 구현

- Columns Data Type

- Cell 커스터마이징

- afterSelection으로 수식 입력줄 구현하기

- Download CSV 구현 (콤마, 줄바꿈, 따옴표 처리)

- Mui Drawer로 Handsontable Option 관리하기

- Column Width, Row Height 로컬 스토리지에 저장하기

- Mui 토글 버튼으로 셀 스타일 편집 기능 만들기 

- 셀 스타일 로컬 스토리지에 저장하기 (전체 코드)

- Handsontable 깃허브 연동하기 (data, style, comment, merge 저장하기)


셀 합치기 기능을 구현하려면, mergeCells 옵션에서 배열로 합칠 셀에 대한 정보를 넣으면 된다. (초기화)

  mergeCells: [
    {row: 1, col: 1, rowspan: 3, colspan: 3},
    {row: 3, col: 4, rowspan: 2, colspan: 2},
  ],

 

Context Menu에서 Merge cellsUnmerge cells 옵션이 나타나는 것을 알 수 있다.

 

빈 배열을 넣어주면, 초기화 없이 기능만 사용할 수 있다.

  mergeCells: [],

 

참고로 6.2.2 ver에서는 cell을 merge할 때, 셀의 border가 하얗게 변하는 버그가 있다.

로컬 스토리지를 이용해 다시 셀을 합칠 때는 사라진다.


afterMergeCells, afterUnmergeCells

 

afterMergeCells는 Merge cells를 누르면 호출되는 callback 함수다.

https://handsontable.com/docs/6.2.2/Hooks.html?#event:afterMergeCells 

 

아래 함수를 옵션에 추가해보자.

  afterMergeCells: (cellRange, mergeParent, auto) => {
    console.log(cellRange);
    console.log(mergeParent);
    console.log(auto);
  },

 

afterUnmergeCells는 셀 병합을 해제할 때 호출되는 callback 함수다.

https://handsontable.com/docs/6.2.2/Hooks.html#event:afterUnmergeCells

 

마찬가지로 로그를 추가해서 확인해 보자.

  afterUnmergeCells: (cellRange, auto) => {
    console.log(cellRange);
    console.log(auto);
  },


셀 병합하기

 

comment를 저장하는 방식으로 callback 함수를 이용하여 merge되는 셀을 저장할 수 있다.

하지만 merge된 cell과 merge된 cell을 다시 합칠 때는 mergeCells 배열에 저장할 정보가 애매해진다.

 

test 버튼을 잠시 추가하여 셀에 대한 정보를 확인해 보자.

  const test = () => {
    console.log(myHandOnTable.getCellMeta(0, 0));
  }

  return (
    <div>
      <button onClick={test}>test</button>
      ...

 

병합된 셀이 아닌 (0, 0) 셀에 대한 정보는 아래와 같다.

 

병합된 셀 중 하나인 (3, 4) 셀을 확인해 보자.

console.log(myHandOnTable.getCellMeta(3, 4));

 

spannedtrue라는 정보가 추가되어 있다..

 

병합된 셀 중 하나인 (4, 4) 셀을 확인해 보자.

console.log(myHandOnTable.getCellMeta(4, 4));

 

이 경우, 고정된 셀은 (3, 4)로 보기 때문에 hiddentrue가 된다.

 

따라서 셀을 병합하거나 해제할 때, spannedtrue인 경우만 로컬 스토리지에 저장한다.

 

이제 comment를 로컬 스토리지에 저장한 방식대로 아래 함수를 추가하자.

const MERGE_CELLS_KEY = "MERGE_CELLS_KEY";

const getMergeCells = () => { 
  let mergeCells = localStorage.getItem(MERGE_CELLS_KEY);
  
  if(mergeCells === null) return [];

  return JSON.parse(mergeCells);
}

 

mergeCells 옵션에는 다음과 같이 초기화된다.

mergeCells: getMergeCells(),

 

Unmerge의 경우, 해당 row와 col에 포함되는 데이터를 제거한다.

  afterUnmergeCells: (cellRange, auto) => {
    let temp = getMergeCells().filter(
      (item) =>
        (item.row === cellRange.from.row &&
          item.col === cellRange.from.col) === false
    );

    localStorage.setItem(MERGE_CELLS_KEY, JSON.stringify([...temp]));
  },

 

afterMergeCellsgetCellMeta 함수를 사용해야 하기 때문에 addHook으로 callback 함수를 추가해야 한다.

중복된 merge cell을 제거하기 위해 spannedtrue인 경우만 필터링하였다.

  const makeTable = () => {
    const container = document.getElementById("hot-app");
    container.innerHTML = "";
    
    const myTable = new Handsontable(container, options);

    myTable.addHook("afterMergeCells", function(cellRange, mergeParent, auto) {
      let temp = getMergeCells();
      temp.push(mergeParent);
      temp = temp.filter(
        (item) => myTable.getCellMeta(item.row, item.col).spanned === true
      );

      localStorage.setItem(MERGE_CELLS_KEY, JSON.stringify([...temp]));
    });
  };

 

이제 병합된 셀의 정보가 잘 유지되는지 확인해 보자.

반응형

댓글