By default, the TableSheet will configure the remote requests by an object. If you want to handle the request manually, just replace the object of the function, and the data and column changes will be passed to the function.
The details of the data changes are in the Request and Response section of the Overview.
AutoSync Mode
Handle requests in the AutoSync mode:
Batch Mode
Handle requests in the Batch mode:
Change data source options
When a Table uses CRUD functions instead of CRUD options, these functions can't be saved and restored after JSON serialization / deserialization because of security issue.
Setting the Table’s data source options after the fromJSON method is invoked could make the Table working again.
Reload data
When a Table’s fetch method is invoked and its reload argument is true, the Table will load data again.
And a View’s fetch method has same reload argument with a Table’s fetch method.
<template>
<div class="sample-tutorial">
<gc-spread-sheets class="sample-spreadsheets" @workbookInitialized="initSpread">
</gc-spread-sheets>
<div id="options-container" class="options-container">
<fieldset>
<legend>Active Row Operations</legend>
<div class="field-line">
<input id="remove" type="button" value="Remove" @click="removeRow()">
</div>
<div class="field-line">
<input id="save" type="button" value="Save" @click="saveRow()">
</div>
<div class="field-line">
<input id="reset" type="button" value="Reset" @click="resetRow()">
</div>
</fieldset>
<fieldset>
<legend>Save All Rows</legend>
<div class="field-line">
<input id="save-all" type="button" value="Save All" @click="saveAllRows()">
</div>
</fieldset>
<fieldset>
<legend>Batch Operations</legend>
<div class="field-line">
<input type="button" value="Submit" id="submit" @click="submitChanges()">
</div>
<div class="field-line">
<input type="button" value="Discard" id="discard" @click="discardChanges()">
</div>
</fieldset>
</div>
</div>
</template>
<script setup>
import GC from "@mescius/spread-sheets";
import { ref } from "vue";
import "@mescius/spread-sheets-tablesheet";
import "@mescius/spread-sheets-vue";
var tableName = "DefineEmployee";
var baseApiUrl = getBaseApiUrl();
var apiUrl = baseApiUrl + "/" + tableName;
// var apiColumnUrl = baseApiUrl + "/tables/" + tableName + "/columns";
var batchApiUrl = baseApiUrl + "/" + tableName + 'Collection';
var tablesheetName = 'MyTableSheet';
function sendRequest(url, options) {
options.method = options.method || 'POST';
options.headers = {
'Content-Type': 'application/json; charset=utf-8'
};
if (options.body) {
options.body = JSON.stringify(options.body);
}
return fetch(url, options).then(resp => {
if (resp.ok) {
return resp.json();
} else {
throw resp.statusText;
}
});
}
const spreadRef = ref(null);
const tablesheet = ref(null);
const selections = ref([{ row: 0, rowCount: 1, col: 0, colCount: 1 }]);
function initSpread(spread) {
spreadRef.value = spread;
spread.suspendPaint();
spread.clearSheets();
spread.options.autoFitType = GC.Spread.Sheets.AutoFitType.cellWithHeader;
//init a data manager
var dataManager = spread.dataManager();
var myTable = dataManager.addTable("myTable", {
remote: {
read: function readFunction() {
return sendRequest(apiUrl, {
method: 'GET'
});
},
// update: function (item) {
// return sendRequest(apiUrl, { body: item, method: 'PUT' });
// },
// create: function (item) {
// return sendRequest(apiUrl, { body: item });
// },
// delete: function (item) {
// return sendRequest(apiUrl, { body: item, method: 'DELETE' });
// },
// getColumns: function () {
// return sendRequest(apiColumnUrl, { method: 'GET' });
// },
// updateColumn: function (change) {
// return sendRequest(apiColumnUrl, { body: change, method: 'PUT' });
// },
// addColumn: function (change) {
// return sendRequest(apiColumnUrl, { body: change });
// },
// removeColumn: function (change) {
// return sendRequest(apiColumnUrl, { body: change, method: 'DELETE' });
// },
batch: function batchFunction(changes) {
return sendRequest(batchApiUrl, {
body: changes
});
}
},
batch: true,
schema: {
columns: {
"Id": {
dataType: "number"
},
"LastName": {
dataType: "string"
},
"FirstName": {
dataType: "string"
},
"HomePhone": {
dataType: "string"
},
"Notes": {
dataType: "string"
}
}
}
});
//init a table sheet
var sheet = spread.addSheetTab(0, tablesheetName, GC.Spread.Sheets.SheetType.tableSheet);
// sheet.options.enableDefineColumn = true;
tablesheet.value = sheet;
var rowActions = GC.Spread.Sheets.TableSheet.BuiltInRowActions;
var options = sheet.rowActionOptions();
options.push(
rowActions.removeRow,
rowActions.saveRow,
rowActions.resetRow,
);
sheet.rowActionOptions(options);
//bind a view to the table sheet
myTable.fetch().then(function () {
var view = myTable.addView("myView", [{
value: "Id",
width: 50,
caption: "ID"
},
{
value: "FirstName",
width: 100,
caption: "First Name"
},
{
value: "LastName",
width: 100,
caption: "Last Name"
},
{
value: "HomePhone",
width: 100,
caption: "Phone"
},
{
value: "Notes",
width: 100,
caption: "Notes"
}
]); //the View has all default columns of the Table
sheet.setDataView(view);
});
spread.bind(GC.Spread.Sheets.Events.SelectionChanged, (e, args) => {
selections.value = args.newSelections;
});
spread.resumePaint();
}
function removeRow() {
traverseSelectionsRowsWithOperation((row) => {
tablesheet.value.removeRow(row);
});
}
function saveRow() {
traverseSelectionsRowsWithOperation((row) => {
tablesheet.value.saveRow(row);
});
}
function resetRow() {
traverseSelectionsRowsWithOperation((row) => {
tablesheet.value.resetRow(row);
});
}
function saveAllRows() {
spreadRef.value.commandManager().SaveAll.execute(spreadRef.value, {
sheetName: tablesheetName
});
}
function submitChanges() {
tablesheet.value.submitChanges();
}
function discardChanges() {
tablesheet.value.cancelChanges();
}
function traverseSelectionsRowsWithOperation(operation) {
var selectionsList = selections.value;
if (selectionsList) {
for (var i = 0; i < selectionsList.length; i++) {
var selection = selectionsList[i];
var row = selection.row;
var rowCount = selection.rowCount;
for (var r = row + rowCount - 1; r >= row; r--) {
operation(r);
}
}
}
}
function getBaseApiUrl() {
return window.location.href.match(/http.+spreadjs\/demos\//)[0] + 'server/api';
}
</script>
<style scoped>
#app {
height: 100%;
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
fieldset {
padding: 6px;
margin: 0;
margin-top: 10px;
}
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
.sample-spreadsheets {
width: calc(100% - 280px);
height: 100%;
overflow: hidden;
float: left;
}
.options-container {
float: right;
width: 280px;
padding: 12px;
height: 100%;
box-sizing: border-box;
background: #fbfbfb;
overflow: auto;
}
fieldset span,
fieldset input,
fieldset select {
display: inline-block;
text-align: left;
}
fieldset input[type=text] {
width: calc(100% - 58px);
}
fieldset input[type=button] {
width: 100%;
text-align: center;
}
fieldset select {
width: calc(100% - 50px);
}
.field-line {
margin-top: 4px;
}
.field-inline {
display: inline-block;
vertical-align: middle;
}
fieldset label.field-inline {
width: 100px;
}
fieldset input.field-inline {
width: calc(100% - 100px - 12px);
}
.required {
color: red;
font-weight: bold;
}
#fields {
display: none;
}
#fields.show {
display: block;
}
#changesPanel {
width: 100%;
height: 300px;
}
</style>
<!DOCTYPE html>
<html style="height:100%;font-size:14px;">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>SpreadJS VUE</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css"
href="$DEMOROOT$/en/vue3/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<script src="$DEMOROOT$/en/vue3/node_modules/systemjs/dist/system.src.js"></script>
<script src="./systemjs.config.js"></script>
<script src="./compiler.js" type="module"></script>
<script>
var System = SystemJS;
System.import("./src/app.js");
System.import('$DEMOROOT$/en/lib/vue3/license.js');
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>
(function (global) {
SystemJS.config({
transpiler: 'plugin-babel',
babelOptions: {
es2015: true
},
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
packageConfigPaths: [
'./node_modules/*/package.json',
"./node_modules/@mescius/*/package.json",
"./node_modules/@babel/*/package.json",
"./node_modules/@vue/*/package.json"
],
map: {
'vue': "npm:vue/dist/vue.esm-browser.js",
'tiny-emitter': 'npm:tiny-emitter/index.js',
'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js',
"systemjs-babel-build": "npm:systemjs-plugin-babel/systemjs-babel-browser.js",
'@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js',
'@mescius/spread-sheets-vue': 'npm:@mescius/spread-sheets-vue/index.js',
'@mescius/spread-sheets-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/index.js'
},
meta: {
'*.css': { loader: 'systemjs-plugin-css' },
'*.vue': { loader: "../plugin-vue/index.js" }
}
});
})(this);