function defaultEditGrid(element, paramColumns, toolbarHtml, itemLevelColumnName, layoutData, screenMargin, flexColumns) { let jexcelInstance; let columns = paramColumns; let columnNames = []; for (let i = 0; i < paramColumns.length; i++) { columnNames[i] = paramColumns[i].name; } const itemLevelColumnIndex = columnNames.indexOf(itemLevelColumnName) function stringToColour(stringInput, alpha) { let stringUniqueHash = [...stringInput].reduce((acc, char) => { return char.charCodeAt(0) + ((acc << 5) - acc); }, 0); return `hsla(${stringUniqueHash % 360}, 85%, 40%, ${alpha})`; } var customUpdateTable = function(instance, cell, col, row, val, label, cellName) { if(col == 0 && val != null && val != ''){ //cell.style.backgroundColor = '#f46e42'; cell.style.textAlign = 'left'; var rowData = jexcelInstance.getRowData(Number(row)); if(rowData.length > 1){ // const itemLenIndex = columnNames.indexOf('itemLevel'); const depth = Number(rowData[itemLevelColumnIndex]); cell.style.textAlign = 'left'; const padding = depth == 1 ? 5 : (depth*10); cell.style.paddingLeft = padding+'px'; const colorVal = (padding*2)+''; const fromColor = stringToColour(colorVal, '20%'); const toColor = stringToColour(colorVal, '60%'); cell.style.background = `linear-gradient(to right, ${fromColor}, ${fromColor}, ${toColor}) no-repeat left`; cell.style.backgroundSize = (padding - 2) +'px 2px'; } }else{ const columnProp = columns[col]; if (columnProp.align != null) { cell.style.textAlign = columnProp.align; } } } //JEXCEL 관련 함수 시작 function getCellValue(columnName, rowNum){ const index = columnNames.indexOf(columnName); //var cell = gridInstance.records[rowNum][index]; //return cell.innerText; const cellId = String.fromCharCode(65+index) + rowNum; return jexcelInstance.getValue(cellId) } const beforePaste = function (instance, data){ console.log('beforePaste'); const selectedCell = jexcelInstance.selectedCell; const obj = jexcelInstance; var ax = Number(selectedCell[0]), ay = Number(selectedCell[1]), bx = Number(selectedCell[2]), by = Number(selectedCell[3]); // Paste filter var x = ax, y = ay, w = bx-x+1, h = by-y+1; // change paste range if select is from right to left if (bx < ax){ x = bx; w = ax-x+1; } // change paste range if select is from down to up if (by < ay){ y = by; h = ay-y+1; } // Controls var hash = obj.hash(data); var style = (hash == obj.hashString) ? obj.style : null; // Depending on the behavior if (obj.options.copyCompatibility == true && hash == obj.hashString) { var data = obj.data; } // Split new line var data = obj.parseCSV(data, "\t"); //modify data to allow wor extending paste range in multiples of input range if (w>1 & Number.isInteger(w/data[0].length )){ style = null; repeats = w/data[0].length; var arrayB = data.map(function(row,i){ var arrayC = Array.apply(null, {length: repeats * row.length}) .map(function(e,i){return row[i % row.length]}); return arrayC }); data = arrayB; } if (h>1 & Number.isInteger(h/data.length )){ style = null; var repeats = h/data.length; var arrayB = Array.apply(null, {length: repeats * data.length}) .map(function(e,i){return data[i % data.length]}); data = arrayB; } if (x != null && y != null && data) { // Records var i = 0; var j = 0; var records = []; var newStyle = {}; var oldStyle = {}; var styleIndex = 0; // Index var colIndex = parseInt(x); var rowIndex = parseInt(y); var row = null; // Go through the columns to get the data while (row = data[j]) { i = 0; var colIndex = parseInt(x); while (row[i] != null) { // Update and keep history var record = obj.updateCell(colIndex, rowIndex, row[i]); // Keep history records.push(record); // Style if (style) { var columnName = jexcel.getColumnNameFromId([colIndex, rowIndex]); newStyle[columnName] = style[styleIndex]; oldStyle[columnName] = obj.getStyle(columnName); obj.records[rowIndex][colIndex].setAttribute('style', style[styleIndex]); styleIndex++ } i++; if (row[i] != null) { if (colIndex >= obj.headers.length - 1) { obj.insertColumn(); } colIndex = obj.right.get(colIndex, rowIndex); } } j++; if (data[j]) { if (rowIndex >= obj.rows.length - 1) { obj.insertRow(); } var rowIndex = obj.down.get(x, rowIndex); } } // Select the new cells obj.updateSelectionFromCoords(x, y, colIndex, rowIndex); // Update history obj.setHistory({ action: 'setValue', records: records, selection: obj.selectedCell, newStyle: newStyle, oldStyle: oldStyle, }); // Update table obj.updateTable(); } return false; }; function moveSelectionRow(up){ const selectedCell = jexcelInstance.selectedCell; const correction = up ? -1 : 1 ; const selectionCorrection = up ? 0 : 2 ; if(selectedCell != null) { const x1 = Number(selectedCell[0]) ; const y1 = Number(selectedCell[1]) ; const x2 = Number(selectedCell[2]); const y2 = Number(selectedCell[3]); if(up){ if(y1 === 0) return; jexcelInstance.moveRow(y1 + correction, y2); }else{ const rowSize = jexcelInstance.getData().length; if(y2 + 1 === rowSize) return; jexcelInstance.moveRow(y2 + correction, y1); } const CODE_A = 65; const x1Code = String.fromCharCode(CODE_A+x1); const x2Code = String.fromCharCode(CODE_A+x2); const startCellCode = x1Code + (y1+selectionCorrection); const endCellCode = x2Code + (y2+selectionCorrection); jexcelInstance.updateSelection(jexcelInstance.getCell(startCellCode), jexcelInstance.getCell(endCellCode)); } } function updateSelectedDepth(increse){ const selectedCell = jexcelInstance.selectedCell; const depthColumn = itemLevelColumnIndex; if(selectedCell != null) { const y1 = Number(selectedCell[1]); const y2 = Number(selectedCell[3]); const top = y1 < y2 ? y1 : y2; const gap = (y1 < y2 ? y2 - y1 : y1 - y2) + 1; const values = []; for (let i = 0; i < gap; i++) { const cellNum = 'C'+(top+i+1); let value = Number(jexcelInstance.getValue(cellNum)); value = increse ? value + 1 : (value === 1 ? 1 : value - 1); values[i] = String(value); } updateValues(top, depthColumn, values); } } // function updateSelectedColumn(colIndex, value){ // const selectedCell = jexcelInstance.selectedCell; // if(selectedCell != null) { // const y1 = Number(selectedCell[1]); // const y2 = Number(selectedCell[3]); // const top = y1 < y2 ? y1 : y2; // const gap = (y1 < y2 ? y2 - y1 : y1 - y2) + 1; // // const values = []; // for (let i = 0; i < gap; i++) { // values[i] = value; // } // updateValues(top, colIndex, values); // } // } function updateValues(x, y, values){ var records = []; for (let i = 0; i < values.length; i++) { const rowIndex = x + i; // Update and keep history var record = jexcelInstance.updateCell(y, rowIndex, values[i]); // Keep history records.push(record); } // Update history jexcelInstance.setHistory({ action: 'setValue', records: records, selection: jexcelInstance.selectedCell, }); // Update table jexcelInstance.updateTable(); } function onTabKey(event){ const selectedCell = jexcelInstance.selectedCell; const x = Number(selectedCell[0]) + 1; const y = Number(selectedCell[1]) + 1; const rowSize = jexcelInstance.getData().length; const colSize = columnNames.length; if(x === colSize){ if(y === rowSize){ jexcelInstance.insertRow(); } const cellNum = 'A'+(y+1); jexcelInstance.updateSelection(jexcelInstance.getCell(cellNum)); event.preventDefault(); event.stopPropagation(); } console.log(x+','+y+','+rowSize+','+colSize); } function jexcelContextMenu (obj, x, y, e) { var items = []; if (y == null) { // Insert a new column if (obj.options.allowInsertColumn == true) { items.push({ title: obj.options.text.insertANewColumnBefore, onclick: function () { obj.insertColumn(1, parseInt(x), 1); } }); } if (obj.options.allowInsertColumn == true) { items.push({ title: obj.options.text.insertANewColumnAfter, onclick: function () { obj.insertColumn(1, parseInt(x), 0); } }); } // Delete a column if (obj.options.allowDeleteColumn == true) { items.push({ title: obj.options.text.deleteSelectedColumns, onclick: function () { obj.deleteColumn(obj.getSelectedColumns().length ? undefined : parseInt(x)); } }); } // Rename column if (obj.options.allowRenameColumn == true) { items.push({ title: obj.options.text.renameThisColumn, onclick: function () { obj.setHeader(x); } }); } // Sorting if (obj.options.columnSorting == true) { // Line items.push({type: 'line'}); items.push({ title: obj.options.text.orderAscending, onclick: function () { obj.orderBy(x, 0); } }); items.push({ title: obj.options.text.orderDescending, onclick: function () { obj.orderBy(x, 1); } }); } } else { // Insert new row if (obj.options.allowInsertRow == true) { items.push({ title: '행 삽입', onclick: function () { const selectedCell = obj.selectedCell; if (selectedCell == null) { obj.insertRow(1, parseInt(y), 1); } else { const y1 = Number(selectedCell[1]); const y2 = Number(selectedCell[3]); const top = y1 < y2 ? y1 : y2; const gap = (y1 < y2 ? y2 - y1 : y1 - y2) + 1; obj.insertRow(gap, top, 1); } } }); items.push({ title: 'Add Row', onclick: function () { const selectedCell = obj.selectedCell; if (selectedCell == null) { obj.insertRow(1, parseInt(y), 1); } else { const y1 = Number(selectedCell[1]); const y2 = Number(selectedCell[3]); const bottom = y1 > y2 ? y1 : y2; const gap = (y1 < y2 ? y2 - y1 : y1 - y2) + 1; obj.insertRow(gap, bottom); } } }); } if (obj.options.allowDeleteRow == true) { items.push({ title: 'Delete Row', onclick: function () { obj.deleteRow(obj.getSelectedRows().length ? undefined : parseInt(y)); } }); } } // Line items.push({type: 'line'}); // Copy items.push({ title: obj.options.text.copy, shortcut: 'Ctrl + C', onclick: function () { obj.copy(); } }); // Paste items.push({ title: obj.options.text.paste, shortcut: 'Ctrl + V', onclick: function () { obj.paste(); } }); // Line items.push({type: 'line'}); items.push({ title: '깊이', submenu: [ { title: '깊이증가', shortcut: 'Alt + →', onclick: function () { updateSelectedDepth(true); } }, { title: '깊이감소', shortcut: 'Alt + ←', onclick: function () { updateSelectedDepth(false); } }, ] }); items.push({ title: '행 이동', submenu: [ { title: '위로이동', shortcut: 'Alt + ↑', onclick: function () { moveSelectionRow(true); } }, { title: '아래로이동', shortcut: 'Alt + ↓', onclick: function () { moveSelectionRow(false); } }, ] }); return items; } function createEditGrid(element, columns, toolbarHtml, layoutData) { jexcelInstance = jexcel(element.get(0), { data: [[]], columns: columns, rowResize: false, rowDrag: true, columnResize: false, columnDrag: false, columnSorting: false, autoIncrement: false, allowInsertColumn: false, allowInsertOnTab: true, tableOverflow: true, allowManualInsertRow: false, tableHeight: 2500, onbeforepaste: beforePaste, allowDeletingAllRows: true, updateTable: customUpdateTable, contextMenu: jexcelContextMenu }); const superSetHistory = jexcelInstance.setHistory; jexcelInstance.setHistory = function(changes){ if("setWidth" === changes.action){ return ; } superSetHistory(changes); }; element.on("keydown", function (e) { if (e.altKey) { if (e.keyCode == 39) { updateSelectedDepth(true); return false; } if (e.keyCode == 37) { updateSelectedDepth(false); return false; } if (e.keyCode == 38) { moveSelectionRow(true); return false; } if (e.keyCode == 40) { moveSelectionRow(false); return false; } } if (!e.shiftKey && e.keyCode == 9) { onTabKey(e); } }); if(toolbarHtml != null && toolbarHtml != ''){ element.children().first().before(toolbarHtml); } const gridInstanceData = [[]]; for (let i = 0; i < layoutData.length; i++) { const row = layoutData[i]; gridInstanceData[i] = row; } jexcelInstance.setData(gridInstanceData); resizeGridInstance(); return jexcelInstance; } let resizing = false; function resizeGridInstance(){ let screenGap = screenMargin == null ? 113 : screenMargin; var screenWidth = $(window).width() - screenGap; var columnWidth = 0; columns.forEach( function (element){ columnWidth += element.width; } ); var gap = screenWidth - columnWidth; if(flexColumns == null) { var halfGap = gap / 2; jexcelInstance.setWidth(0, Number(columns[0].width) + halfGap); jexcelInstance.setWidth(1, Number(columns[1].width) + halfGap); }else{ const cnt = flexColumns.length const columnGap = gap / cnt; for (let flexColumn of flexColumns) { const index = columnNames.indexOf(flexColumn); jexcelInstance.setWidth(index, Number(columns[index].width) + columnGap); } } resizing = false; } $( window ).resize( function() { if(!resizing){ resizing = true; setTimeout(resizeGridInstance, 10); } }) return createEditGrid(element, paramColumns, toolbarHtml, layoutData); }