Overview

The row actions are optional special columns attached to the row header that make it easy to perform operations on the row data using the UI, such as saving, removing and resetting the data.

The new row is a special row at the bottom of a TableSheet that will automatically insert a new row when data is added.

Row Action The row action is enabled by default and is on the row header of the TableSheet. There are some built-in row actions that can be added: Name Description pinRow pin a row dirtyStatus show the data changes in a row warningInfo show warning infomation in a row removeRow remove a row saveRow save the data changes in a row resetRow reset the data changes in a row Adding remove, save, reset actions: New Row The new row is enabled by default and is at the bottom of the table sheet. You can hide or show it with:
import * as React from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; import { AppFunc } from './app-func'; import { App } from './app-class'; // 1. Functional Component sample createRoot(document.getElementById('app')).render(<AppFunc />); // 2. Class Component sample // createRoot(document.getElementById('app')).render(<App />);
/*REPLACE_MARKER*/ /*DO NOT DELETE THESE COMMENTS*/ import * as React from 'react'; import { useState } from 'react' import { createRoot } from 'react-dom/client'; import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-tablesheet"; import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react'; import './styles.css'; var tableName = "Employee"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; export function AppFunc() { const [spread, setSpread] = useState(null); const [tablesheet, setTablesheet] = useState(null); const [toggleRowActionTitle, setToggleRowActionTitle] = useState('hide remove/save/reset'); const [newRowVisible, setNewRowVisible] = useState(true); let initSpread = function (value) { setSpread(value); value.suspendPaint(); value.clearSheets(); value.options.autoFitType = GC.Spread.Sheets.AutoFitType.cellWithHeader; //init a data manager var dataManager = value.dataManager(); var myTable = dataManager.addTable("myTable", { data:employees }); //init a table sheet var sheet = value.addSheetTab(0, "MyTableSheet", GC.Spread.Sheets.SheetType.tableSheet); var rowActions = GC.Spread.Sheets.TableSheet.BuiltInRowActions; let options = sheet.rowActionOptions(); options.push( rowActions.removeRow, rowActions.saveRow, rowActions.resetRow, ); sheet.rowActionOptions(options); setTablesheet(sheet); //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: "PhotoPath", width: 100, caption: "Attachment" }, { value: "Notes", width: 100, caption: "Comments" } ]); //the View has all default columns of the Table sheet.setDataView(view); }); value.resumePaint(); } let toggleNewRow = function (checked) { setNewRowVisible(checked); tablesheet.options.allowAddNew = checked; } let toggleRowActions = function () { let sheet = tablesheet; let options = sheet.rowActionOptions(); if (options.length === 1) { setToggleRowActionTitle('hide remove/save/reset'); var rowActions = GC.Spread.Sheets.TableSheet.BuiltInRowActions; options.push( setTooltip(rowActions.removeRow, 'Remove'), setTooltip(rowActions.saveRow, 'Save'), setTooltip(rowActions.resetRow, 'Reset'), ); } else { setToggleRowActionTitle('show remove/save/reset'); options.splice(1, options.length); } sheet.rowActionOptions(options); } return ( <div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => { initSpread(spread); }}></SpreadSheets> </div> <div id="options-container" class="options-container"> <fieldset> <legend>Row Action</legend> <div class="field-line"> <input type="button" id="change-option" value={toggleRowActionTitle} onClick={() => toggleRowActions()} /> </div> </fieldset> <fieldset> <legend>New Row</legend> <div class="field-line"> <span>visible: </span><input type="checkbox" onChange={(e) => { toggleNewRow(e.target.checked) }} checked={newRowVisible} id="show-button" /> </div> </fieldset> </div> </div> ); } function setTooltip(options, tooltip) { options.tooltip = tooltip; return options; } function getBaseApiUrl() { return window.location.href.match(/http.+spreadjs\/demos\//)[0] + 'server/api'; }
/*REPLACE_MARKER*/ /*DO NOT DELETE THESE COMMENTS*/ import * as React from 'react'; import { createRoot } from 'react-dom/client'; import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-tablesheet"; import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react'; import './styles.css'; const Component = React.Component; var tableName = "Employee"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; export class App extends Component { constructor(props) { super(props); this.spread = null; this.tablesheet = null; this.state = { toggleRowActionTitle: 'hide remove/save/reset', newRowVisible: true }; } render() { const { toggleRowActionTitle, newRowVisible } = this.state; return ( <div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => { this.initSpread(spread); }}></SpreadSheets> </div> <div id="options-container" class="options-container"> <fieldset> <legend>Row Action</legend> <div class="field-line"> <input type="button" id="change-option" value={toggleRowActionTitle} onClick={()=>this.toggleRowActions()} /> </div> </fieldset> <fieldset> <legend>New Row</legend> <div class="field-line"> <span>visible: </span><input type="checkbox" onChange={(e) => { this.setState({ newRowVisible: e.target.checked }, () => { this.toggleNewRow() }); }} checked={newRowVisible} id="show-button" /> </div> </fieldset> </div> </div> ); } initSpread(spread) { this.spread = 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", { data:employees }); //init a table sheet var sheet = spread.addSheetTab(0, "MyTableSheet", GC.Spread.Sheets.SheetType.tableSheet); var rowActions = GC.Spread.Sheets.TableSheet.BuiltInRowActions; let options = sheet.rowActionOptions(); options.push( rowActions.removeRow, rowActions.saveRow, rowActions.resetRow, ); sheet.rowActionOptions(options); this.tablesheet = sheet; //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: "PhotoPath", width: 100, caption: "Attachment" }, { value: "Notes", width: 100, caption: "Comments" } ]); //the View has all default columns of the Table sheet.setDataView(view); }); spread.resumePaint(); } toggleNewRow() { this.tablesheet.options.allowAddNew = this.state.newRowVisible; } toggleRowActions() { let sheet = this.tablesheet; let options = sheet.rowActionOptions(); if (options.length === 1) { this.setState({ toggleRowActionTitle: 'hide remove/save/reset' }); var rowActions = GC.Spread.Sheets.TableSheet.BuiltInRowActions; options.push( setTooltip(rowActions.removeRow, 'Remove'), setTooltip(rowActions.saveRow, 'Save'), setTooltip(rowActions.resetRow, 'Reset'), ); } else { this.setState({ toggleRowActionTitle: 'show remove/save/reset' }); options.splice(1, options.length); } sheet.rowActionOptions(options); } } function setTooltip(options, tooltip) { options.tooltip = tooltip; return options; } function getBaseApiUrl() { return window.location.href.match(/http.+spreadjs\/demos\//)[0] + 'server/api'; }
<!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" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/react/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <!-- SystemJS --> <script src="$DEMOROOT$/en/react/node_modules/systemjs/dist/system.src.js"></script> <script src="$DEMOROOT$/spread/source/data/employees.js" type="text/javascript"></script> <script src="systemjs.config.js"></script> <script> System.import('$DEMOROOT$/en/lib/react/license.js').then(function () { System.import('./src/app'); }); </script> </head> <body> <div id="app" style="height: 100%;"></div> </body> </html>
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; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true, react: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/index.js', '@mescius/spread-sheets-react': 'npm:@mescius/spread-sheets-react/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', 'react': 'npm:react/cjs/react.production.js', 'react-dom': 'npm:react-dom/cjs/react-dom.production.js', 'react-dom/client': 'npm:react-dom/cjs/react-dom-client.production.js', 'scheduler': 'npm:scheduler/cjs/scheduler.production.js', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'jsx' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);