-
Toast grid 함수 및 이벤트 예시DEV/javascript 2022. 2. 17. 15:56
Toast grid를 사용하면서 가장 많이 쓴 이벤트와 함수를 남겨 두려고 한다.
https://nhn.github.io/tui.grid/latest/Grid
공식 페이지에 아주 깔끔하게 나열 되어 있으니 참고하자.
클릭 이벤트, 업데이트 이벤트, 클릭한 Row 색상 변경, 클릭한 Row 데이터 가져오기, 그리드 스크롤 최상단 이동(이건 사실 지원하는 함수는 아니지만... 아무튼) 정도로 충분하였다.
아래 코드를 참조하자.
// 그리드 생성 const GridObject = tui.Grid; GridObject = new Grid({ ... )} // 그리드에 data 삽입 GridObject.resetData(data) // 그리드 업데이트 이벤트 (그리드가 업데이트 됐을 때) GridObject.on('onGridUpdated', (ev) => { // 그리드 레이아웃 새로고침 (로드가 다 되지 않는 경우 그리드가 흰색 화면으로 출력될 때가 있다.) GridObject.refreshLayout(); }); // 그리드 클릭 이벤트 GridObject.on('click', ev => { // 클릭한 Row의 정보를 dataRow에 저장 let dataRow = GridObject.getRow(ev.rowKey); // 클릭한 Row의 색을 변경 (강조 효과, 클릭 했다는 효과를 줄 때) GridObject.addSelectionOnly(ev.rowKey); // 클릭한 컬럼 이름이 "..." 인 경우 if(ev.columnName == "_checked"){ ... } // 그리드 내용 초기화(Clear) GridObject.dataClear(); }); // 현재 클릭하여 Focus된 Row(Cell) 정보를 가져온다. const focusCell = GridObject.getFocusedCell() // 그리드 스크롤을 최상단으로 이동 // Grid 객체를 생성한 div(또는 담은 요소) id값을 지정하여 사용 가능하다. $('html, body').animate({ scrollTop : $('#gridDivId .tui-grid-body-area').scrollTop(0) } , 500);
* 추가!
하단 js/css를 추가해야 개별 함수 사용이 가능하다.
* 추가 JS
/** * TOAST UI Grid Settings * 토스트 그리드 기본 UI설정(색상 및 굵기 등의 스타일 설정) */ const GridSettings = { language: { localeCode: "ko", // localeCode : 언어 설정 (en, ko) data: { display: { noData: "검색 결과가 없습니다.", // noData : 빈 값일 때 표시하는 형식 }, } }, theme: { presetName: "clean", // presetName : 기본 테마 설정 (default, striped, clean) extOptions: { // <<커스텀 옵션설정>> outline: { // [ outline ] : 그리드 바깥 선 설정 border: '#bbbbbb', // border : 색깔 showVerticalBorder: true, // showVerticalBorder : 바깥 세로 선 여부(boolean) }, selection: { // [ selection ] : 행, 열의 헤더를 선택하면 해당 부분이 선택되며 나오는 색상 설정 // background: '#f5d1ba', // background : 바탕색 background : '#1eed11', border: '#bbbbbb', // border : 선 색 }, scrollbar: { // [ scrollbar ] : 스크롤바 border: 'rgb(205,205,205)', // border : 선 색 background: 'rgb(248,248,248)', // background : 바탕 색 emptySpace: 'rgb(240,240,240)', // emptySpace : 스크롤 빈 부분 색상 thumb: 'rgb(205,205,205)', // thumb : 스크롤 부분 색상 active: 'rgb(70,70,70)' // active : 마우스오버, 클릭할 때 색깔 }, frozenBorder: { // [ frozenBorder ] : 고정 컬럼 border: 'rgb(233,233,233)', // border : 선 색 }, area: { // [area] : 검색 후 표시된 열을 제외한 부분 ( 표의 높이 - 열의 높이 = area ) header: { background: 'rgb(233, 233, 233)', // header : 컬럼이 없는 헤더의 색상을 나타낸다. border: '#bbbbbb', // **border : [ cell ] - header 와 맞추는 것이 좋다. 현재는 오버되어 색상이 표기된다. }, body: { // body : 빈 열 값의 부분 색상 background: '#ffffff', }, }, row: { // [ row ] : 열 hover: { // hover : 마우스 오버시 background: '#e9f8e8', }, dummy: { // dummy : 비활성 시 background: '#f5d1ba', }, }, cell: { // [ cell ] : 각 셀의 색상 지정 normal: { border: '#bbbbbb', text: 'black', showVerticalBorder: true, showHorizontalBorder: true, }, header: { // header : 상단 제목 열 background: 'rgb(233, 233, 233)', border: '#bbbbbb', text: 'black', showVerticalBorder: true, showHorizontalBorder: true, }, selectedHeader: { // selectedHeader : 선택한 제목 색상 background: 'rgb(233, 233, 233)', }, rowHeader: { // rowHeader : 좌측 제목 행 background: 'rgb(233, 233, 233)', border: '#bbbbbb', text: 'black', showVerticalBorder: true, showHorizontalBorder: true, }, selectedRowHeader: { // selectedRowHeader : 선택한 열 색상 background: 'rgb(233, 233, 233)', }, focused: { // focused : 선택한 셀 색상 background: "#f5d1ba", border: "#bbbbbb", }, focusedInactive: { // focusedInactive : 선택 후 표 바깥을 선택하면 나타나는 색상 border: "#bbbbbb" }, summary: { // summary : 요약 열에 사용할 색상 background: '#f1f5ff', border: '#bbbbbb', text: 'black', showVerticalBorder: true, showHorizontalBorder: true, }, }, }, }, defaultOptions: { // << options >> header: { // [ header ] : 헤더의 속성 설정 height: 28, // height : 기본 높이 설정(px;num) align: 'center', // align : 가로정렬 ('left', 'center', 'right') valign: 'middle', // valign : 세로정렬 ('top', 'middle', 'bottom') }, minRowHeight: 25, // rowHeight : 열의 최소높이(px) ==> **25px이하로 설정하게 되면 스타일이 틀어지기 때문에 낮은 숫자로 변경되는 것을 권장하지 않습니다. rowHeight: 25, // rowHeight : 열의 높이(px) ==> **25px이하로 설정하게 되면 스타일이 틀어지기 때문에 낮은 숫자로 변경되는 것을 권장하지 않습니다. minBodyHeight: 50, // minBodyHeight : 표의 최소 크기 bodyHeight: 300, // bodyHeight : 표의 크기 width: "auto", // width : 너비 heightResizable: false, // heightResizable : 높이 마우스 조절 usageStatistics: false, // usageStatistics : hostname전송 여부 설정 scrollX: true, // scrollX : 가로 축 이동 추가 여부(boolean) scrollY: true, // scrollY : 세로 축 이동 추가 여부(boolean) copyOptions: { // [ copyOptions ] : 복사할 때 사용할 값 지정 useFormattedValue: true, // useFormattedValue : 포멧된 값을 복사 혹은 원본 데이터 복사 }, columnOptions: { // [ columnOptions ] minWidth: 50, // minWidth : 최소 너비 사이즈 resizable: true, // resizable : 컬럼의 고정 폭을 조정 여부(boolean). frozenCount: 0, // frozenCount : 고정 컬럼의 개수 frozenBorderWidth: 1, // frozenBorderWidth : 고정 컬럼의 경계선 너비(px) }, }, } /** * Customizing TOAST UI Grid * https://nhn.github.io/tui.grid/latest/Grid */ class Grid extends tui.Grid { #selectedRowKey; constructor(props) { const options = { ...GridSettings.defaultOptions, ...props }; super(options); this.#selectedRowKey = -1; } getSelectedRowKey() { return this.#selectedRowKey; } /** * unSelection */ unSelection(grid) { for ( var i = 0 ; i < grid.getRowCount() ; i++ ) { this.removeRowClassName(i, "cell-selection"); } //this.removeRowClassName(this.#selectedRowKey, "cell-selection"); } /** * Add style when selecting row * @param {object} ev */ addSelectionOnly( rowKey ) { if (typeof rowKey != "number") return; this.removeRowClassName(this.#selectedRowKey, "cell-selection"); this.addRowClassName(rowKey, "cell-selection"); this.#selectedRowKey = rowKey; } /** * Add style when selecting row * @param {object} ev */ addSelection(ev = {}) { if (typeof ev.rowKey != "number") return; let rowData = this.getRow(ev.rowKey); let checked = rowData._attributes.checked; if (checked) this.removeRowClassName(ev.rowKey, "cell-selection"); else this.addRowClassName(ev.rowKey, "cell-selection"); this.#selectedRowKey = ev.rowKey; } /** * Sort by clicking column header * @param {object} ev */ clickSort(ev = {}) { if (ev.targetType != "columnHeader") return; // this.removeRowClassName(this.#selectedRowKey, "cell-selection"); if (!ev.nativeEvent.target.className.includes("tui-grid-cell-header")) return; let sortingBtn = ev.nativeEvent.target.children[0]; if (!sortingBtn || !sortingBtn.className.includes("tui-grid-btn-sorting")) return; sortingBtn.click(); } /** * Check by clicking row * @param {object} ev * @param {object} grid * @param {boolean} onlyOne */ clickCheck(ev = {}, grid, onlyOne = false) { console.log(ev) if (typeof ev.rowKey != "number" && ev.columnName == "_checked" ) { let gridCount = grid.getRowCount(); let isCheckAll = gridCount == grid.getCheckedRows().length ? true : false ; if ( isCheckAll ) { for ( var i = 0 ; i < gridCount ; i++ ) { this.removeRowClassName(i, "cell-selection"); } } else { for ( var i = 0 ; i < gridCount ; i++ ) { this.addRowClassName(i, "cell-selection"); } } } else if (typeof ev.rowKey != "number") { return; } else { console.log(ev) let rowData = this.getRow(ev.rowKey); let checked = rowData._attributes.checked; if (onlyOne) this.uncheckAll(); if (checked) this.uncheck(ev.rowKey); else this.check(ev.rowKey) } } /** * Check by clicking row * @param {object} ev * @param {object} grid * @param {boolean} onlyOne */ checkboxCheck( grid, rowKey) { let rowData = grid.getRow(rowKey); let checked = rowData._attributes.checked; if (!checked) this.check(rowKey); } /** * Check by clicking row * @param {object} ev * @param {object} grid */ clickAllAddSelection(ev = {}, grid) { if (typeof ev.rowKey != "number" && ev.columnName == "_checked" ) { let gridCount = grid.getRowCount(); let isCheckAll = gridCount == grid.getCheckedRows().length ? true : false ; if ( isCheckAll ) { for ( var i = 0 ; i < gridCount ; i++ ) { this.removeRowClassName(i, "cell-selection"); } } else { for ( var i = 0 ; i < gridCount ; i++ ) { this.addRowClassName(i, "cell-selection"); } } } return; } /** * @param {number} rowCount */ resetDummyData(rowCount = 0) { const rows = []; const columns = this.getColumns(); for (let i = 0; i < rowCount; i++) { const row = {}; columns.forEach(col => { row[col.name] = (Math.random() * 10000000000).toFixed(); }); rows.push(row); } this.resetData(rows); } /** * @param {string} fileName */ exportExcel(fileName) { fileName = `${fileName || "excel"}.xls`; const gridData = this.getData(); const gridColumns = this.getColumns(); let tableStr = ""; //헤더 tableStr += "<thead><tr>"; for (let col of gridColumns) { if (col["hidden"] == false) { tableStr += `<th>${col["header"]}</th>`; } } tableStr += "</tr></thead>"; //내용 tableStr += "<tbody>"; for (let gridRow of gridData) { tableStr += "<tr>"; for (let col of gridColumns) { if (col["hidden"] == false) { tableStr += `<td style="mso-number-format:'\@'">${gridRow[col["name"]]}</td>`; } } tableStr += "</tr>"; } tableStr += "</tbody>"; const tableEl = $("<table></table>").html(tableStr); tableEl.find('input').each((index, elem) => $(elem).remove()); tableToExcel(tableEl, fileName); } /** * Get number of rows per page * @return {number} perPage */ getPaginationPerPage() { const pagenation = this.getPagination(); if (pagenation && pagenation._options) { return pagenation._options.itemsPerPage; } else { return null; } } /** * Returns the left position of the scrollbar. * @returns {number} scrollLeft */ getScrollLeft() { return this.store.viewport.scrollLeft; } /** * Return the object that contains all values in the specified row. * @returns {Object} The object that contains all values in the row. */ getSelection() { return this.getRow(this.#selectedRowKey); } /** * * @returns {Object} The object that contains all values in the row. */ getRowKey(grid, value) { let exist = grid.getData().filter(function(e){ return e[Object.keys(value)] == value[Object.keys(value)] ; }); if(exist.length == 1){ return exist[0].rowKey; }else{ return null; } } /** * Set the left position of the scrollbar. * @param {number} scrollLeft */ setScrollLeft(scrollLeft) { this.store.viewport.scrollLeft = scrollLeft; } /** * Set the current page * @param {number} page */ setPage(page) { this.resetData(this.getData(), { pageState: { page } }); } dataClear(){ this.#selectedRowKey = -1; this.resetData([]); } } /** * https://nhn.github.io/tui.grid/latest/Grid#applyTheme */ Grid.applyTheme(GridSettings.theme.presetName, GridSettings.theme.extOptions); /** * https://nhn.github.io/tui.grid/latest/Grid#setLanguage */ Grid.setLanguage(GridSettings.language.localeCode, GridSettings.language.data);
* 추가 CSS
/* TOAST Grid */ .tui-grid-layer-state { /* outline border */ border-left: 1px solid rgb(205, 205, 205) !important; } /* SELECTED ROW */ .tui-grid-cell.cell-selection { background-color: rgba(116, 185, 255, .1) !important; } /* HOVER ROW */ .tui-grid-row-hover>.tui-grid-cell { background-color: rgba(116, 185, 255, .1) !important; } /* DRAG ROW DELETE */ .tui-grid-layer-selection { display: none; } .tui-grid-scrollbar-left-bottom { border-width: 0 0; border-left-width: 1px; } .tui-grid-cell-has-input .tui-grid-cell-content { padding-top: 0px; padding-bottom: 0px; } .tui-grid-row-header-checkbox { padding: 0; } .tui-grid-layer-focus-deactive { display: none !important; } .tui-grid-layer-focus-border { display: none !important; }
Toast Grid 예시
https://seokbong.tistory.com/14
'DEV > javascript' 카테고리의 다른 글
Bootstrap 그리드 시스템 (Grid system : row, col) (0) 2022.02.21 Bootstrap 설치 및 사용하기 (0) 2022.02.21 Javascript Toast grid 예시 (1) 2022.02.16 Javascript 물음표 연산자와 물음표 두개 연산자 (? 연산자와 ?? 연산자) (0) 2022.02.15 jQuery 선택자(태그) 접근 방법 2 (여러 Id, Class 사용하여 접근하기) (0) 2022.02.15