Status Bar

The status bar can display TableSheet data and states using custom status bar items. For example, double click in any cell to see the status bar message change to edit.

The demo is being dynamically compiled to support real-time code editing... For quicker access to features, switch to the "JavaScript" tab for a smoother experience! :)
Description
app.jsx
app-func.jsx
app-class.jsx
index.html
styles.css
Copy to CodeMine

The status bar can display various sheet status and summary values. Select different ranges of cells to see how the information in the status bar changes.

This is the sample code:

//init status bar
var statusBar = new GC.Spread.Sheets.StatusBar.StatusBar(document.getElementById('statusBar'));
statusBar.bind(spread);
The status bar can display various sheet status and summary values. Select different ranges of cells to see how the information in the status bar changes. This is the sample code:
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import './styles.css'; import { AppFunc } from './app-func'; import { App } from './app-class'; // 1. Functional Component sample ReactDOM.render(<AppFunc />, document.getElementById('app')); // 2. Class Component sample // ReactDOM.render(<App />, document.getElementById('app'));
/*REPLACE_MARKER*/ /*DO NOT DELETE THESE COMMENTS*/ import * as React from 'react'; import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-tablesheet"; import { SpreadSheets } from '@mescius/spread-sheets-react'; import './styles.css'; var tableName = "Customer"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; var myView; function getBaseApiUrl() { return window.location.href.match(/http.+spreadjs\/demos\//)[0] + 'server/api'; } function getRowCount(selections) { var selectedRows = {}; for (var i = 0; i < selections.length; i++) { var row = selections[i].row; var rowCount = selections[i].rowCount; if (row === -1) { return rowCount; } for (var c = 0; c < rowCount; c++) { selectedRows[row + c] = true; } } return Object.keys(selectedRows).length; } export function AppFunc() { const initSpread = (spread) => { let statusBar = initStatusBar(spread); spread.suspendPaint(); spread.clearSheets(); spread.options.autoFitType = GC.Spread.Sheets.AutoFitType.cellWithHeader; //init a data manager var dataManager = spread.dataManager(); //add customer table var customerTable = dataManager.addTable("myTable", { remote: { read: { url: apiUrl } } }); //init a table sheet var sheet = spread.addSheetTab(0, "TableSheet1", GC.Spread.Sheets.SheetType.tableSheet); sheet.options.allowAddNew = false; //hide new row //bind a view to the table sheet myView = customerTable.addView("myView", [ { value: "Id", width: 80 }, { value: "CompanyName", width: 200, caption: "Company Name" }, { value: "ContactName", width: 150, caption: "Contact" }, { value: "ContactTitle", width: 200, caption: "Title" }, { value: "Address", width: 200 }, { value: "City", width: 150, caption: "City" }, { value: "State", width: 100, caption: "State" }, { value: "Region", width: 100, caption: "Region" } ]); myView.fetch().then(function () { sheet.setDataView(myView); if (statusBar) { var recordItem = statusBar.get("recordCountItem"); if (recordItem) { recordItem.dataSourceLength = myView.length(); recordItem.visibleLength = myView.visibleLength(); recordItem.onUpdate(); } } }); spread.resumePaint(); } const initStatusBar = (spread) => { //define custom status item class RecordCountItem extends GC.Spread.Sheets.StatusBar.StatusItem { constructor(name, options) { super(name, options); this._value = 1; this.dataSourceLength = 0; this.visibleLength = 0; } onCreateItemView(container) { var element = this._element; if (!element) { element = this._element = document.createElement("span"); element.innerHTML = " Rows: <b>" + this.visibleLength + "</b> of <b>" + this.dataSourceLength + "</b> - Record Count: <b>" + this._value + "</b>"; } container.appendChild(element); } onBind(context) { var _this = this; context.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e, args) { _this._value = getRowCount(args.newSelections); _this.onUpdate(); }); context.bind(GC.Spread.Sheets.Events.RangeFiltered, function (e, args) { _this.dataSourceLength = myView.length(); _this.visibleLength = myView.visibleLength(); _this.onUpdate(); }); context.bind(GC.Spread.Sheets.Events.RangeFilterCleared, function (e, args) { _this.dataSourceLength = myView.length(); _this.visibleLength = myView.visibleLength(); _this.onUpdate(); }); } onUpdate() { super.onUpdate(); this._element.innerHTML = " Rows: <b>" + this.visibleLength + "</b> of <b>" + this.dataSourceLength + "</b> - Record Count: <b>" + this._value + "</b>"; } } //init status bar var recordCountItem = new RecordCountItem('recordCountItem', { menuContent: 'Record Count', value: 0 }); var statusBar = new GC.Spread.Sheets.StatusBar.StatusBar(document.getElementById('statusBar'), { items: [recordCountItem] }); statusBar.bind(spread); return statusBar; } return ( <div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => initSpread(spread)}> </SpreadSheets> </div> <div id="statusBar"></div> </div> ); }
/*REPLACE_MARKER*/ /*DO NOT DELETE THESE COMMENTS*/ import * as React from 'react'; import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-tablesheet"; import { SpreadSheets } from '@mescius/spread-sheets-react'; import './styles.css'; var tableName = "Customer"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; var myView; function getBaseApiUrl() { return window.location.href.match(/http.+spreadjs\/demos\//)[0] + 'server/api'; } function getRowCount(selections) { var selectedRows = {}; for (var i = 0; i < selections.length; i++) { var row = selections[i].row; var rowCount = selections[i].rowCount; if (row === -1) { return rowCount; } for (var c = 0; c < rowCount; c++) { selectedRows[row + c] = true; } } return Object.keys(selectedRows).length; } const Component = React.Component; export class App extends Component { constructor(props) { super(props); } render() { return ( <div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => this.initSpread(spread)}> </SpreadSheets> </div> <div id="statusBar"></div> </div> ); } initSpread(spread) { let statusBar = this.initStatusBar(spread); spread.suspendPaint(); spread.clearSheets(); spread.options.autoFitType = GC.Spread.Sheets.AutoFitType.cellWithHeader; //init a data manager var dataManager = spread.dataManager(); //add customer table var customerTable = dataManager.addTable("myTable", { remote: { read: { url: apiUrl } } }); //init a table sheet var sheet = spread.addSheetTab(0, "TableSheet1", GC.Spread.Sheets.SheetType.tableSheet); sheet.options.allowAddNew = false; //hide new row //bind a view to the table sheet myView = customerTable.addView("myView", [ { value: "Id", width: 80 }, { value: "CompanyName", width: 200, caption: "Company Name" }, { value: "ContactName", width: 150, caption: "Contact" }, { value: "ContactTitle", width: 200, caption: "Title" }, { value: "Address", width: 200 }, { value: "City", width: 150, caption: "City" }, { value: "State", width: 100, caption: "State" }, { value: "Region", width: 100, caption: "Region" } ]); myView.fetch().then(function () { sheet.setDataView(myView); if (statusBar) { var recordItem = statusBar.get("recordCountItem"); if (recordItem) { recordItem.dataSourceLength = myView.length(); recordItem.visibleLength = myView.visibleLength(); recordItem.onUpdate(); } } }); spread.resumePaint(); } initStatusBar(spread) { //define custom status item class RecordCountItem extends GC.Spread.Sheets.StatusBar.StatusItem { constructor(name, options) { super(name, options); this._value = 1; this.dataSourceLength = 0; this.visibleLength = 0; } onCreateItemView(container) { var element = this._element; if (!element) { element = this._element = document.createElement("span"); element.innerHTML = " Rows: <b>" + this.visibleLength + "</b> of <b>" + this.dataSourceLength + "</b> - Record Count: <b>" + this._value + "</b>"; } container.appendChild(element); } onBind(context) { var _this = this; context.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e, args) { _this._value = getRowCount(args.newSelections); _this.onUpdate(); }); context.bind(GC.Spread.Sheets.Events.RangeFiltered, function (e, args) { _this.dataSourceLength = myView.length(); _this.visibleLength = myView.visibleLength(); _this.onUpdate(); }); context.bind(GC.Spread.Sheets.Events.RangeFilterCleared, function (e, args) { _this.dataSourceLength = myView.length(); _this.visibleLength = myView.visibleLength(); _this.onUpdate(); }); } onUpdate() { super.onUpdate(); this._element.innerHTML = " Rows: <b>" + this.visibleLength + "</b> of <b>" + this.dataSourceLength + "</b> - Record Count: <b>" + this._value + "</b>"; } } //init status bar var recordCountItem = new RecordCountItem('recordCountItem', { menuContent: 'Record Count', value: 0 }); var statusBar = new GC.Spread.Sheets.StatusBar.StatusBar(document.getElementById('statusBar'), { items: [recordCountItem] }); statusBar.bind(spread); return statusBar; } }
<!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="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>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } #statusBar { height: 25px; width: 100%; } .sample-spreadsheets { width: 100%; height: calc(100% - 25px); overflow: hidden; }
(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/umd/react.production.min.js', 'react-dom': 'npm:react-dom/umd/react-dom.production.min.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);