이벤트

ReportSheet에는 보고서 데이터를 변경하거나 제출하는 동안 바인딩할 수 있는 데이터 입력 이벤트가 있습니다.

아래 이벤트를 사용하여 사용자는 모든 데이터 변경의 유효성을 검사하거나 데이터 변경 중 작업을 취소할 수 있으며, 서버의 피드백 결과를 받은 다음 UI에 결과를 표시할 수도 있습니다.

새 창에서 데모를 열어 디자이너 열기 ReportSheet는 아래 데이터 입력 이벤트를 지원합니다. 다음 코드를 사용하여 데이터 입력 이벤트를 바인딩할 수 있습니다. ReportSheetDataChanging 및 ReportSheetDataChanged ReportSheetDataChanging은 업데이트, 삽입 또는 삭제로 인해 보고서 시트가 변경되는 경우에 발생합니다. 데이터 작업의 유효성을 검사하거나 취소하도록 허용합니다. ReportSheetDataChanged는 업데이트, 삽입 또는 삭제로 인해 보고서 시트 데이터가 변경된 경우에 발생합니다. 데이터 변경 사항을 서버에 제출하도록 허용합니다. ReportSheetRecordsSubmitting 및 ReportSheetRecordsSubmitted ReportSheetRecordsSubmitting는 보고서 시트가 서버에 변경 사항을 제출하기 전에 발생합니다. 모든 데이터 변경 사항의 최종 유효성을 검사하거나 작업을 취소하도록 허용합니다. ReportSheetRecordsSubmitted는 보고서 시트가 서버에 변경 사항을 제출한 후에 발생합니다. 사용자가 서버의 제출 결과에 대한 UI 피드백을 제공하도록 허용합니다.
window.onload = async () => { const loadingTip = addLoadingTip(); const { spread, designer } = createSpreadAndDesigner(); const res = await fetch('$DEMOROOT$/ko/sample/features/report-sheet/data-entry/events/spread.json'); await spread.fromJSON(correctTableUrl(await res.json())); loadingTip.remove(); _bindDataEntrySubmitEvents(spread); if (designer) { designer.refresh(); } } function createSpreadAndDesigner() { const demoHost = document.getElementById('demo-host'); if (window !== top) { return { spread: new GC.Spread.Sheets.Workbook(demoHost, { sheetCount: 1 }), } } else { const designer = new GC.Spread.Sheets.Designer.Designer(demoHost, undefined, undefined, { sheetCount: 1 }); return { designer, spread: designer.getWorkbook(), } } } function addLoadingTip() { const div = document.createElement('div'); div.style.position = 'absolute'; div.style.inset = '0'; div.style.display = 'flex'; div.style.alignItems = 'center'; div.style.justifyContent = 'center'; div.style.background = 'white'; div.style.zIndex = '100'; div.textContent = 'Loading data from server ...'; document.body.appendChild(div); return div; } function correctTableUrl(json) { const baseUrl = '$DEMOROOT$'; const localUrl = 'http://localhost:8070/spreadjs/demos'; const replaceUrl = (obj) => { if (obj && obj.url && obj.url.startsWith(localUrl)) { obj.url = obj.url.replace(localUrl, baseUrl); } } if (json.dataManager && json.dataManager.tables) { json.dataManager.tables.forEach((table) => { if (table.dataSourceOption && table.dataSourceOption.remote) { Object.values(table.dataSourceOption.remote).forEach(replaceUrl); } }); } return json; } let time; function _showWindowTip (message, success) { let tipContainer = document.querySelector('.tip-container'); if (!tipContainer) { const div = document.createElement('div'); div.classList.add("tip-container"); document.body.appendChild(div); tipContainer = div; } let innerContainer = document.createElement('div'); innerContainer.className = `tip-inner-container ${success ? 'success' : 'failed'}`; innerContainer.innerHTML = ` <h1>${success ? "Success" : "Failed"}</h1> <p>${message}</p> `; tipContainer.appendChild(innerContainer); if (time) { clearTimeout(time); } time = setTimeout(() => { tipContainer.innerHTML = ""; clearTimeout(time); time = 0; }, 4000); } function _bindDataEntrySubmitEvents (spread) { let reportSheet = spread.getActiveSheetTab(); if (reportSheet) { reportSheet.bind(GC.Spread.Sheets.Events.ReportSheetDataChanging, (event, args) => { let { row, col, newValue, type } = args; if (type === "update") { if (col <= 4 && typeof newValue !== "string") { args.cancel = true; _showWindowTip("New value should be string at col " + col); } else if (col === 5 && typeof newValue !== "number") { args.cancel = true; _showWindowTip("New value should be number at col " + col); } else { type = type[0].toUpperCase() + type.substring(1); _showWindowTip(`${(type)} at cell Row: ${row} col: ${col}`, true); } } else { type = type[0].toUpperCase() + type.substring(1); _showWindowTip(`${type} at cell Row: ${row} col: ${col}`, true); } }); reportSheet.bind(GC.Spread.Sheets.Events.ReportSheetRecordsSubmitted, (event, args) => { let { updateSuccessRecords, updateFailedRecords, deleteSuccessRecords, deleteFailedRecords } = args; let updateSuccessCells = [], deleteSuccessCells = [], updateFailedCells = [], deleteFailedCells = []; updateSuccessRecords.forEach((r) => { for (let key in r.info) { if (r.info.hasOwnProperty(key) && r.info[key].state === "updated") { updateSuccessCells.push({ row: r.info[key].row, col: r.info[key].col, }); } } }); deleteSuccessRecords.forEach((r) => { for (let key in r.info) { if (r.info.hasOwnProperty(key)) { deleteSuccessCells.push({ row: r.info[key].row, col: r.info[key].col, }); } } }); updateFailedRecords.forEach((r) => { for (let key in r.info) { if (r.info.hasOwnProperty(key) && r.info[key].state === "updated") { updateFailedCells.push({ row: r.info[key].row, col: r.info[key].col, reason: r.reason === undefined ? "null" : r.reason }); } } }); deleteFailedRecords.forEach((r) => { for (let key in r.info) { if (r.info.hasOwnProperty(key)) { deleteFailedCells.push({ row: r.info[key].row, col: r.info[key].col, reason: r.reason === undefined ? "null" : r.reason }); } } }); updateSuccessCells.forEach((cell, i) => { setTimeout(() => { _showWindowTip(`Update successfully at cell Row: ${cell.row} col: ${cell.col}`, true); }, i * 100); }); setTimeout(() => { deleteSuccessCells.forEach((cell, i) => { setTimeout(() => { _showWindowTip(`Delete successfully at cell Row: ${cell.row} col: ${cell.col}`, true); }, i * 100); }); }, updateSuccessCells.length * 100); setTimeout(() => { updateFailedCells.forEach((cell, i) => { setTimeout(() => { _showWindowTip(`Update failed at cell Row: ${cell.row} col: ${cell.col}, reason is ${cell.reason}`); }, i * 100); }); }, (updateSuccessCells.length + deleteSuccessCells.length) * 100); setTimeout(() => { deleteFailedCells.forEach((cell, i) => { setTimeout(() => { _showWindowTip(`Delete failed at cell Row: ${cell.row} col: ${cell.col}, reason is ${cell.reason}`); }, i * 100); }); }, (updateSuccessCells.length + deleteSuccessCells.length + updateFailedCells.length) * 100); }); } }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="spreadjs culture" content="ko-kr" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-designer/styles/gc.spread.sheets.designer.min.css"> <link rel="stylesheet" type="text/css" href="styles.css"> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-print/dist/gc.spread.sheets.print.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-reportsheet-addon/dist/gc.spread.report.reportsheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-resources-ko/dist/gc.spread.sheets.resources.ko.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script> const designerDependencyScripts = [ '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-barcode/dist/gc.spread.sheets.barcode.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-slicers/dist/gc.spread.sheets.slicers.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-formula-panel/dist/gc.spread.sheets.formulapanel.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-io/dist/gc.spread.sheets.io.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-resources-ko/dist/gc.spread.sheets.resources.ko.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-designer-resources-ko/dist/gc.spread.sheets.designer.resource.ko.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-designer/dist/gc.spread.sheets.designer.all.min.js', '$DEMOROOT$/spread/source/js/designer/license.js', ] function appendScriptNode (src) { const script = document.createElement('script'); script.src = src; script.async = false; script.type = 'text/javascript'; document.head.appendChild(script); } if (top === window) { // not in iframe designerDependencyScripts.forEach(appendScriptNode); } </script> <script src="app.js" type="text/javascript"></script> </head> <body> <div class="sample-tutorial"> <div id="demo-host"></div> </div> </body> </html>
body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } #demo-host { width: 100%; height: 100%; overflow: hidden; float: left; } .tip-container { position: absolute; display: flex; align-items: center; justify-content: start; z-index: 100; min-width: 300px; min-height: 60%; max-height: 100%; right: 0; top: 0; overflow: hidden; flex-direction: column; } .tip-inner-container { position: relative; display: flex; height: 52px; background-color: white; flex-direction: column; min-width: 200px; margin-bottom: 10px; padding: 0px 25px 0 10px; border-radius: 10px; box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 5px 0px, rgba(0, 0, 0, 0.1) 0px 2px 3px 0px; align-items: start; animation-name: tip-animation; animation-duration: 4s; animation-fill-mode: forwards; color: rgb(51, 51, 51); font-family: sans-serif; } .success { border-left: solid 8px rgb(154, 233, 140); } .failed { border-left: solid 8px rgb(227, 144, 143); } .tip-inner-container h1 { margin: 0; padding-top: 5px; font-size: 17.6px; font-weight: 500; } .tip-inner-container p { margin: 0; padding-top: 5px; font-size: 12.8px; } @keyframes tip-animation { 0% { left: 300px; opacity: 0; } 20% { left: 10px; opacity: 1; } 75% { left: 10px; opacity: 1; } 100% { left: 300px; opacity: 0; } }