### Handsontable Setup and UI Elements Source: https://handsontable.com/docs/javascript-data-grid/recipes/data-management/load-data-rest-api Initializes Handsontable, registers modules, and sets up UI elements like buttons and status output. This code is required for the example to run. ```typescript import Handsontable from 'handsontable/base'; import { registerAllModules } from 'handsontonode/registry'; registerAllModules(); type ApiUser = { id: number; name: string; username: string; email: string; address?: { city?: string }; company?: { name?: string }; }; const STATUS_LOADING = 'Loading users...'; const STATUS_READY = 'Users loaded. Sort a column, then click "Refresh" to see that the column sort order is preserved.'; const STATUS_REFRESHING = 'Refreshing...'; const STATUS_REFRESHED = 'Data refreshed -- column sort order was preserved.'; const STATUS_ERROR = 'Failed to load users. Try again.'; const rootContainer = document.querySelector('#example2') as HTMLDivElement; const controlsContainer = document.createElement('div'); const controls = document.createElement('div'); const statusOutput = document.createElement('output'); const refreshButton = document.createElement('button'); const retryButton = document.createElement('button'); const gridContainer = document.createElement('div'); controlsContainer.className = 'example-controls-container'; controls.className = 'controls'; statusOutput.id = 'example2-status'; refreshButton.type = 'button'; refreshButton.textContent = 'Refresh'; refreshButton.hidden = true; retryButton.type = 'button'; retryButton.textContent = 'Retry'; retryButton.hidden = true; controls.appendChild(refreshButton); controls.appendChild(retryButton); controlsContainer.appendChild(controls); controlsContainer.appendChild(statusOutput); rootContainer.appendChild(controlsContainer); rootContainer.appendChild(gridContainer); ``` -------------------------------- ### Install Handsontable Source: https://handsontable.com/docs/javascript-data-grid/recipes/themes/custom-theme Install Handsontable and the React wrapper package in your project. ```bash pnpm add handsontable @handsontable/react-wrapper (or `npm install` / `yarn add`). Use `@handsontable/react-wrapper` for `HotTable` + `HotColumn` and `HotTableRef`. ``` -------------------------------- ### Install Moment.js and Pikaday Source: https://handsontable.com/docs/javascript-data-grid/recipes/cell-types/moment-date Install the necessary libraries for date handling and the calendar picker. ```bash npm install moment @handsontable/pikaday ``` -------------------------------- ### Install Handsontable and React Wrapper Source: https://handsontable.com/docs/javascript-data-grid/recipes/themes/base-theme Install the necessary Handsontable and React wrapper packages using pnpm. If setting up a new Base Web project, also install Base UI and Styletron. ```bash pnpm add handsontable@0.0.0-next-deba76c-20260408 @handsontable/react-wrapper@0.0.0-next-deba76c-20260408 ``` ```bash pnpm add baseui styletron-engine-atomic styletron-react ``` -------------------------------- ### Install Flatpickr and date-fns Source: https://handsontable.com/docs/javascript-data-grid/recipes/cell-types/flatpickr Install the necessary packages using npm. ```bash npm install flatpickr date-fns ``` -------------------------------- ### Install Handsontable and MUI Wrapper Source: https://handsontable.com/docs/javascript-data-grid/recipes/themes/mui-theme Install the necessary Handsontable packages and the React wrapper using npm. ```bash npm install handsontable @handsontable/react-wrapper @mui/material @emotion/react @emotion/styled ``` -------------------------------- ### Install Dependencies and Build All Packages Source: https://handsontable.com/docs/javascript-data-grid/custom-builds Installs all project dependencies using pnpm and then builds all Handsontable packages from the root directory. ```bash pnpm install pnpm run build ``` -------------------------------- ### Install Moment.js Source: https://handsontable.com/docs/javascript-data-grid/recipes/cell-types/moment-time Install Moment.js using npm. This is a prerequisite for using the moment-time cell type. ```bash npm install moment ``` -------------------------------- ### Install Gems with Bundler Source: https://handsontable.com/docs/javascript-data-grid/recipes/data-management/server-side-rails Run `bundle install` to install the gems specified in your Gemfile. ```bash bundle install ``` -------------------------------- ### Install Dependencies Source: https://handsontable.com/docs/javascript-data-grid/recipes/cell-types/pikaday Install the necessary libraries for Pikaday integration: @handsontable/pikaday and moment.js. ```bash npm install @handsontable/pikaday moment ``` -------------------------------- ### Example Container Styling Source: https://handsontable.com/docs/javascript-data-grid/accessibility CSS for styling the main container of the accessibility examples, setting up flex display and font. ```css .example-container { gap: 1rem; display: flex; flex-direction: column; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; } ``` -------------------------------- ### Install Symfony Framework and Routing Source: https://handsontable.com/docs/javascript-data-grid/recipes/data-management/server-side-symfony Installs the core Symfony framework bundle and the routing component. ```bash composer require symfony/framework-bundle symfony/routing ``` -------------------------------- ### Basic Dropdown Cell Type Implementation Source: https://handsontable.com/docs/javascript-data-grid/dropdown-cell-type This example demonstrates the basic setup for using the dropdown cell type. It configures two columns to use the dropdown type, each with a predefined list of color options. Ensure Handsontable modules are registered before initializing. ```javascript import Handsontable from 'handsontable/base'; import { registerAllModules } from 'handsontable/registry'; // Register all Handsontable's modules. registerAllModules(); const container = document.querySelector('#example1'); new Handsontable(container, { height: 'auto', data: [ ['Tesla', 2017, 'black', 'black'], ['Nissan', 2018, 'blue', 'blue'], ['Chrysler', 2019, 'yellow', 'black'], ['Volvo', 2020, 'white', 'gray'], ], colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'], columns: [ {}, { type: 'numeric' }, { type: 'dropdown', source: ['yellow', 'red', 'orange', 'green', 'blue', 'gray', 'black', 'white'], }, { type: 'dropdown', source: ['yellow', 'red', 'orange', 'green', 'blue', 'gray', 'black', 'white'], }, ], autoWrapRow: true, autoWrapCol: true, licenseKey: 'non-commercial-and-evaluation', }); ``` ```javascript import Handsontable from 'handsontable/base'; import { registerAllModules } from 'handsontable/registry'; // Register all Handsontable's modules. registerAllModules(); const container = document.querySelector('#example1')!; new Handsontable(container, { height: 'auto', data: [ ['Tesla', 2017, 'black', 'black'], ['Nissan', 2018, 'blue', 'blue'], ['Chrysler', 2019, 'yellow', 'black'], ['Volvo', 2020, 'white', 'gray'], ], colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'], columns: [ {}, { type: 'numeric' }, { type: 'dropdown', source: ['yellow', 'red', 'orange', 'green', 'blue', 'gray', 'black', 'white'], }, { type: 'dropdown', source: ['yellow', 'red', 'orange', 'green', 'blue', 'gray', 'black', 'white'], }, ], autoWrapRow: true, autoWrapCol: true, licenseKey: 'non-commercial-and-evaluation', }); ``` -------------------------------- ### REST and GraphQL Examples Source: https://handsontable.com/docs/javascript-data-grid/server-side-data-fetching Examples demonstrating end-to-end integration patterns with a browser grid and a backend server using REST and GraphQL. ```APIDOC ## Examples (REST and GraphQL) These examples pair a browser grid with a small backend server. ### REST (warehouse stock) - **Description**: Demonstrates integration with an Express-style JSON API for managing warehouse stock (SKU, bin, quantity). - **API**: `GET`, `PATCH`, `POST`, `DELETE` on `/api/stock-lines`. - **Reference Server**: `server-rest.mjs`. ### GraphQL (support queue) - **Description**: Demonstrates integration with a GraphQL API for managing paged open tickets, sorting, and mutations. - **Schema**: Aligned to a helpdesk-style schema. - **Reference Server**: `server-graphql.mjs`. **Note**: The JavaScript, React, Vue 3, and Angular examples under `examples/next/docs/` run both backends on default ports 4010 and 4011. TypeScript projects can import `DataProviderQueryParameters`, `DataProviderFetchOptions`, and related interfaces from `handsontable/plugins/dataProvider`. ``` -------------------------------- ### Install Numbro Source: https://handsontable.com/docs/javascript-data-grid/recipes/cell-types/numbro Install the Numbro library using npm. This is a prerequisite for using Numbro with Handsontable. ```bash npm install numbro ``` -------------------------------- ### Value Formatter Examples for Price and Weight Source: https://handsontable.com/docs/javascript-data-grid/cell-renderer Examples demonstrating the use of `valueFormatter` to format a 'price' column with a currency symbol and a 'weight' column with units. ```javascript columns: [ { data: 'price', valueFormatter(value) { return value ? `$${value.toFixed(2)}` : ''; } }, { data: 'weight', valueFormatter(value) { return value ? `${value} kg` : ''; } } ] ``` -------------------------------- ### Full example: Import and register ContextMenu plugin Source: https://handsontable.com/docs/javascript-data-grid/modules A complete example demonstrating the import of the Handsontable base module, the `registerPlugin` function, and the `ContextMenu` plugin, followed by the registration of the plugin. ```javascript import Handsontable from 'handsontable/base'; import { registerPlugin, ContextMenu, } from 'handsontable/plugins'; registerPlugin(ContextMenu); ``` -------------------------------- ### Select Non-Adjacent Ranges Source: https://handsontable.com/docs/javascript-data-grid/api/core This example demonstrates selecting multiple, distinct ranges of cells that may not be adjacent. Each range is defined by its start and end coordinates. ```javascript hot.selectCells([[1, 1, 2, 2], [10, 10, 20, 20]]); ``` -------------------------------- ### Setup Checkbox for Enter Key Editing Source: https://handsontable.com/docs/javascript-data-grid/accessibility Configures a checkbox to control the 'enterBeginsEditing' setting. This determines if pressing Enter in a cell immediately starts editing. ```javascript setupCheckbox(document.querySelector('#enable-cell-enter-editing'), (checked) => { hotOptions.enterBeginsEditing = checked; hot.updateSettings({ enterBeginsEditing: hotOptions.enterBeginsEditing, }); console.log('Updated setting: enable-cell-enter-editing to', hot.getSettings().enterBeginsEditing); }); ``` -------------------------------- ### Enable Loading Plugin with Default Configuration Source: https://handsontable.com/docs/javascript-data-grid/api/loading This example shows how to enable the Loading plugin with its default settings. ```javascript // enable the `Loading` plugin with default configuration loading: true, ``` -------------------------------- ### Get Current Page Information Source: https://handsontable.com/docs/javascript-data-grid/rows-pagination This example shows how to retrieve the current page number and the total number of pages available in the pagination. These values can be used for UI display. ```javascript const currentPage = hot.pagination.getCurrentPage(); const totalPages = hot.pagination.getTotalPages(); console.log(`Current Page: ${currentPage + 1}, Total Pages: ${totalPages}`); ``` -------------------------------- ### Bootstrap Project Script Source: https://handsontable.com/docs/javascript-data-grid/recipes/data-management/server-side-expressjs Run this script to set up the project environment, including starting PostgreSQL, applying TypeORM migrations, seeding data, and launching the Express backend. ```bash bash setup.sh # or: make setup ``` -------------------------------- ### Get Copyable Text from Range Source: https://handsontable.com/docs/javascript-data-grid/api/core Returns a string representation of a selected range, with columns separated by tabs and rows by newlines. Requires start and end row/column indices. ```javascript hot.getCopyableText(startRow, startCol, endRow, endCol); ``` -------------------------------- ### Get Copyable Text Data Source: https://handsontable.com/docs/javascript-data-grid/api/data-map Returns the data as tab-separated text, suitable for clipboard copying to external applications. Optionally specify start and end selection positions. ```javascript dataMap.getCopyableText([start], [end]); ``` -------------------------------- ### getOuterTopStartCorner Source: https://handsontable.com/docs/javascript-data-grid/api/cell-range Gets the top left (in LTR) or top right (in RTL) corner coordinates of your range. If the corner contains header coordinates (negative values), the top and start coordinates are pointed to that header. ```APIDOC ## getOuterTopStartCorner ### Description Gets the top left (in LTR) or top right (in RTL) corner coordinates of your range. If the corner contains header coordinates (negative values), the top and start coordinates are pointed to that header. ### Method GET ### Endpoint _cellRange.getOuterTopStartCorner() ⇒ CellCoords ``` -------------------------------- ### getOuterTopEndCorner Source: https://handsontable.com/docs/javascript-data-grid/api/cell-range Gets the top right (in LTR) or top left (in RTL) corner coordinates of your range. If the corner contains header coordinates (negative values), the top and start coordinates are pointed to that header. ```APIDOC ## getOuterTopEndCorner ### Description Gets the top right (in LTR) or top left (in RTL) corner coordinates of your range. If the corner contains header coordinates (negative values), the top and start coordinates are pointed to that header. ### Method GET ### Endpoint _cellRange.getOuterTopEndCorner() ⇒ CellCoords ``` -------------------------------- ### getOuterBottomStartCorner Source: https://handsontable.com/docs/javascript-data-grid/api/cell-range Gets the bottom left (in LTR) or bottom right (in RTL) corner coordinates of your range. If the corner contains header coordinates (negative values), the top and start coordinates are pointed to that header. ```APIDOC ## getOuterBottomStartCorner ### Description Gets the bottom left (in LTR) or bottom right (in RTL) corner coordinates of your range. If the corner contains header coordinates (negative values), the top and start coordinates are pointed to that header. ### Method GET ### Endpoint _cellRange.getOuterBottomStartCorner() ⇒ CellCoords ``` -------------------------------- ### Enable Loading Plugin with Custom Configuration Source: https://handsontable.com/docs/javascript-data-grid/api/loading This example demonstrates enabling the Loading plugin with custom icon, title, and description. ```javascript // enable the `Loading` plugin with custom configuration loading: { icon: 'A custom loading icon in SVG format', title: 'Custom loading title', description: 'Custom loading description', } ``` -------------------------------- ### getEditedCellRect Source: https://handsontable.com/docs/javascript-data-grid/api/base-editor Gets an object containing information about the edited cell's size and position relative to the table viewport. The object includes top, start, width, maxWidth, height, and maxHeight properties. ```APIDOC ## getEditedCellRect ### Description Gets the object that provides information about the edited cell size and its position relative to the table viewport. ### Returns - Object | undefined: An object with properties: `top`, `start`, `width`, `maxWidth`, `height`, `maxHeight`. ### Method _baseEditor.getEditedCellRect() ⇒ Object | undefined_ ``` -------------------------------- ### getOuterBottomEndCorner Source: https://handsontable.com/docs/javascript-data-grid/api/cell-range Gets the bottom right (in LTR) or bottom left (in RTL) corner coordinates of your range. If the corner contains header coordinates (negative values), the top and start coordinates are pointed to that header. ```APIDOC ## getOuterBottomEndCorner ### Description Gets the bottom right (in LTR) or bottom left (in RTL) corner coordinates of your range. If the corner contains header coordinates (negative values), the top and start coordinates are pointed to that header. ### Method GET ### Endpoint _cellRange.getOuterBottomEndCorner() ⇒ CellCoords ``` -------------------------------- ### Handsontable Initialization with Custom Summary Source: https://handsontable.com/docs/javascript-data-grid/column-summary Initialize Handsontable with a custom column summary that counts even numbers. This example demonstrates the full setup, including data generation, module registration, and the custom function logic. ```javascript import Handsontable from 'handsontable/base'; import { registerAllModules } from 'handsontable/registry'; // Register all Handsontable's modules. registerAllModules(); // generate an array of arrays with dummy numeric data const generateData = (rows = 3, columns = 7, additionalRows = true) => { let counter = 0; const array2d = [...new Array(rows)].map((_) => [...new Array(columns)].map((_) => counter++)); if (additionalRows) { array2d.push([]); array2d.push([]); } return array2d; }; const container = document.querySelector('#example9'); new Handsontable(container, { licenseKey: 'non-commercial-and-evaluation', // initialize a Handsontable instance with the generated numeric data data: generateData(5, 7), height: 'auto', colHeaders: true, rowHeaders: true, // enable the `ColumnSummary` plugin columnSummary: [ // configure a column summary { // set the `type` option to `'custom'` type: 'custom', destinationRow: 0, destinationColumn: 5, reversedRowCoords: true, // add your custom summary function customFunction(endpoint) { // implement a function that counts the number of even values in the column const hotInstance = this.hot; let evenCount = 0; // a helper function const checkRange = (rowRange) => { let i = rowRange[1] || rowRange[0]; let counter = 0; do { if (parseInt(hotInstance.getDataAtCell(i, endpoint.sourceColumn), 10) % 2 === 0) { counter++; } i--; } while (i >= rowRange[0]); return counter; }; // go through all declared ranges for (const r in endpoint.ranges) { if (endpoint.ranges.hasOwnProperty(r)) { evenCount += checkRange(endpoint.ranges[r]); } } return evenCount; }, forceNumeric: true, }, ], autoWrapRow: true, autoWrapCol: true, }); ``` -------------------------------- ### Migrate Currency Formatting: Before Source: https://handsontable.com/docs/javascript-data-grid/migration-from-16.2-to-17.0 Demonstrates the 'Before' state for currency formatting using `pattern` and `culture` from numbro.js. ```javascript // Before numericFormat: { pattern: '0,0.00 $', culture: 'en-US' } ``` -------------------------------- ### Configure Columns with a Function (JavaScript) Source: https://handsontable.com/docs/javascript-data-grid/configuration-options Apply `readOnly: true` to columns with physical index 2 or 8 by providing a function to the `columns` option. This example also shows module registration and basic Handsontable setup. ```javascript import Handsontable from 'handsontable/base'; import { registerAllModules } from 'handsontable/registry'; // Register all Handsontable's modules. registerAllModules(); const container = document.querySelector('#example2'); const data = [ ['A1', 'B1', 'C1', 'D1', 'E1', 'F1', 'G1', 'H1', 'I1', 'J1'], ['A2', 'B2', 'C2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2', 'J2'], ['A3', 'B3', 'C3', 'D3', 'E3', 'F3', 'G3', 'H3', 'I3', 'J3'], ['A4', 'B4', 'C4', 'D4', 'E4', 'F4', 'G4', 'H4', 'I4', 'J4'], ['A5', 'B5', 'C5', 'D5', 'E5', 'F5', 'G5', 'H5', 'I5', 'J5'], ]; const hot = new Handsontable(container, { licenseKey: 'non-commercial-and-evaluation', data, width: 'auto', height: 'auto', rowHeaders: true, colHeaders: true, readOnly: false, columns: (index) => { return { type: index > 0 ? 'numeric' : 'text', readOnly: index === 2 || index === 8, }; }, autoWrapRow: true, autoWrapCol: true, }); // checks a cell's options // returns `false` hot.getCellMeta(0, 0).readOnly; // returns `true` hot.getCellMeta(0, 2).readOnly; ``` -------------------------------- ### Configure Columns with a Function (TypeScript) Source: https://handsontable.com/docs/javascript-data-grid/configuration-options Apply `readOnly: true` to columns with physical index 2 or 8 using a function in the `columns` option, with TypeScript typings. This example also includes module registration and basic Handsontable setup. ```typescript import Handsontable from 'handsontable/base'; import { registerAllModules } from 'handsontable/registry'; // Register all Handsontable's modules. registerAllModules(); const container = document.querySelector('#example2')!; const data: Handsontable.CellValue[][] = [ ['A1', 'B1', 'C1', 'D1', 'E1', 'F1', 'G1', 'H1', 'I1', 'J1'], ['A2', 'B2', 'C2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2', 'J2'], ['A3', 'B3', 'C3', 'D3', 'E3', 'F3', 'G3', 'H3', 'I3', 'J3'], ['A4', 'B4', 'C4', 'D4', 'E4', 'F4', 'G4', 'H4', 'I4', 'J4'], ['A5', 'B5', 'C5', 'D5', 'E5', 'F5', 'G5', 'H5', 'I5', 'J5'], ]; const hot = new Handsontable(container, { licenseKey: 'non-commercial-and-evaluation', data, width: 'auto', height: 'auto', rowHeaders: true, colHeaders: true, readOnly: false, columns: (index: number) => { return { type: index > 0 ? 'numeric' : 'text', readOnly: index === 2 || index === 8, }; }, autoWrapRow: true, autoWrapCol: true, }); // checks a cell's options // returns `false` hot.getCellMeta(0, 0).readOnly; // returns `true` hot.getCellMeta(0, 2).readOnly; ``` -------------------------------- ### Handsontable Initialization with minSpareRows and trimRows Source: https://handsontable.com/docs/javascript-data-grid/migration-from-7.4-to-8.0 Example demonstrating Handsontable initialization with `minSpareRows` and `trimRows` options. This configuration highlights how `trimRows` previously affected `minSpareRows`. ```javascript const hotInstance = new Handsontable(container, { data: [ ['A1', 'B1', 'C1', 'D1', 'E1'], ['A2', 'B2', 'C2', 'D2', 'E2'], ['A3', 'B3', 'C3', 'D3', 'E3'], ['A4', 'B4', 'C4', 'D4', 'E4'], ['A5', 'B5', 'C5', 'D5', 'E5'], ], minSpareRows: 2, trimRows: [1, 2, 3, 4] }); ``` -------------------------------- ### Initialize Handsontable with Multi-Sheet Formulas (TypeScript) Source: https://handsontable.com/docs/javascript-data-grid/formula-calculation This TypeScript code demonstrates the same multi-sheet Handsontable setup as the JavaScript example, including type annotations for data arrays and DOM element selection. It ensures type safety while leveraging HyperFormula for calculations. ```typescript import Handsontable from 'handsontable/base'; import { registerAllModules } from 'handsontable/registry'; import { HyperFormula } from 'hyperformula'; // Register all Handsontable's modules. registerAllModules(); const data1: [string, null, string, string][] = [ ['10.26', null, 'Sum', '=SUM(A:A)'], ['20.12', null, 'Average', '=AVERAGE(A:A)'], ['30.01', null, 'Median', '=MEDIAN(A:A)'], ['40.29', null, 'MAX', '=MAX(A:A)'], ['50.18', null, 'MIN', '=MIN(A1:A5)'], ]; const data2: [string, string][] = [ ['Is A1 in Sheet1 > 10?', '=IF(Sheet1!A1>10,"TRUE","FALSE")'], ['Is A:A in Sheet > 150?', '=IF(SUM(Sheet1!A:A)>150,"TRUE","FALSE")'], ['How many blank cells are in the Sheet1?', '=COUNTBLANK(Sheet1!A1:D5)'], ['Generate a random number', '=RAND()'], ['Number of sheets in this workbook', '=SHEETS()'], ]; // create an external HyperFormula instance const hyperformulaInstance = HyperFormula.buildEmpty({ // to use an external HyperFormula instance, // initialize it with the `'internal-use-in-handsontable'` license key licenseKey: 'internal-use-in-handsontable', }); const container1 = document.querySelector('#example-basic-multi-sheet-1')!; new Handsontable(container1, { data: data1, colHeaders: true, rowHeaders: true, height: 'auto', formulas: { engine: hyperformulaInstance, sheetName: 'Sheet1', }, autoWrapRow: true, autoWrapCol: true, licenseKey: 'non-commercial-and-evaluation', }); const container2 = document.querySelector('#example-basic-multi-sheet-2')!; new Handsontable(container2, { data: data2, colHeaders: true, rowHeaders: true, height: 'auto', formulas: { engine: hyperformulaInstance, sheetName: 'Sheet2', }, autoWrapRow: true, autoWrapCol: true, licenseKey: 'non-commercial-and-evaluation', }); ``` -------------------------------- ### Initialize Handsontable with Dialog Plugin Source: https://handsontable.com/docs/javascript-data-grid/dialog This snippet shows the basic setup for Handsontable, including registering all modules and initializing the grid with the dialog option enabled. It also demonstrates how to retrieve the dialog plugin instance and display a simple dialog after initialization. ```javascript import Handsontable from 'handsontable/base'; import { registerAllModules } from 'handsontable/registry'; // register Handsontable's modules registerAllModules(); const data = [ { model: 'Trail Helmet', price: 1298.14, sellDate: '2025-08-31', sellTime: '14:12', inStock: true }, { model: 'Windbreaker Jacket', price: 178.9, sellDate: '2025-05-10', sellTime: '22:26', inStock: false }, { model: 'Cycling Cap', price: 288.1, sellDate: '2025-09-15', sellTime: '09:37', inStock: true }, { model: 'HL Mountain Frame', price: 94.49, sellDate: '2025-01-17', sellTime: '14:19', inStock: false }, { model: 'Racing Socks', price: 430.38, sellDate: '2025-05-10', sellTime: '13:42', inStock: true }, { model: 'Racing Socks', price: 138.85, sellDate: '2025-09-20', sellTime: '14:48', inStock: true }, { model: 'HL Mountain Frame', price: 1909.63, sellDate: '2025-09-05', sellTime: '09:35', inStock: false }, { model: 'Carbon Handlebar', price: 1080.7, sellDate: '2025-10-24', sellTime: '22:58', inStock: false }, { model: 'Aero Bottle', price: 1571.13, sellDate: '2025-05-24', sellTime: '00:24', inStock: true }, { model: 'Windbreaker Jacket', price: 919.09, sellDate: '2025-07-16', sellTime: '19:11', inStock: true }, { model: 'HL Road Tire', price: 886.22, sellDate: '2025-09-09', sellTime: '00:42', inStock: false }, { model: 'Speed Gloves', price: 635.13, sellDate: '2025-11-17', sellTime: '12:45', inStock: true }, { model: 'Trail Helmet', price: 1440.64, sellDate: '2025-01-03', sellTime: '20:16', inStock: false }, { model: 'Aero Bottle', price: 944.63, sellDate: '2025-11-15', sellTime: '16:14', inStock: false }, { model: 'Windbreaker Jacket', price: 1161.43, sellDate: '2025-06-24', sellTime: '13:19', inStock: false }, { model: 'LED Bike Light', price: 1012.5, sellDate: '2025-05-01', sellTime: '17:30', inStock: false }, { model: 'Windbreaker Jacket', price: 635.37, sellDate: '2025-05-14', sellTime: '09:05', inStock: true }, { model: 'Road Tire Tube', price: 1421.27, sellDate: '2025-01-31', sellTime: '13:33', inStock: true }, { model: 'Action Camera', price: 1019.05, sellDate: '2025-12-07', sellTime: '01:26', inStock: false }, { model: 'Carbon Handlebar', price: 603.96, sellDate: '2025-09-13', sellTime: '04:10', inStock: false }, ]; const container = document.getElementById('example1')!; const hot = new Handsontable(container, { data, colHeaders: true, rowHeaders: true, columns: [ { title: 'Model', type: 'text', data: 'model', width: 150, headerClassName: 'htLeft', }, { title: 'Price', type: 'numeric', data: 'price', width: 80, locale: 'en-US', numericFormat: { style: 'currency', currency: 'USD', minimumFractionDigits: 2, }, className: 'htRight', headerClassName: 'htRight', }, { title: 'Date', type: 'intl-date', data: 'sellDate', width: 131, locale: 'en-US', dateFormat: { month: 'short', day: 'numeric', year: 'numeric' }, className: 'htRight', headerClassName: 'htRight', }, { title: 'Time', type: 'intl-time', data: 'sellTime', width: 90, locale: 'en-US', timeFormat: { hour: '2-digit', minute: '2-digit', hour12: true }, className: 'htRight', headerClassName: 'htRight', }, { title: 'In stock', type: 'checkbox', data: 'inStock', className: 'htCenter', headerClassName: 'htCenter', }, ], width: '100%', height: 300, stretchH: 'all', dialog: true, licenseKey: 'non-commercial-and-evaluation', }); // Show dialog after initialization const dialogPlugin = hot.getPlugin('dialog'); dialogPlugin.show({ content: 'This is a basic dialog with default configuration.', closable: true, }); ``` -------------------------------- ### Autocomplete with Ajax Data Source (TypeScript) Source: https://handsontable.com/docs/javascript-data-grid/autocomplete-cell-type This TypeScript example configures the 'autocomplete' cell type to fetch suggestions from an Ajax endpoint. It uses `fetch` to get data and the `process` callback to supply suggestions. Strict mode is enabled for data validation. ```typescript import Handsontable from 'handsontable/base'; import { registerAllModules } from 'handsontable/registry'; // Register all Handsontable's modules. registerAllModules(); const container = document.querySelector('#example3')!; new Handsontable(container, { height: 'auto', licenseKey: 'non-commercial-and-evaluation', data: [ ['BMW', 2017, 'black', 'black'], ['Nissan', 2018, 'blue', 'blue'], ['Chrysler', 2019, 'yellow', 'black'], ['Volvo', 2020, 'white', 'gray'], ], colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'], columns: [ { type: 'autocomplete', source(_query, process) { fetch('/docs/scripts/json/autocomplete.json') .then((response) => response.json()) .then((response) => process(response.data)); }, strict: true, }, {}, // Year is a default text column {}, // Chassis color is a default text column {}, // Bumper color is a default text column ], autoWrapRow: true, autoWrapCol: true, }); ``` -------------------------------- ### Configure Custom Cell Borders with Styles Source: https://handsontable.com/docs/javascript-data-grid/formatting-cells Apply custom borders with different styles (dotted, dashed, solid) to a range of cells and individual cells. This example demonstrates setting top, bottom, start, and end borders with specific widths and colors. ```javascript import Handsontable from 'handsontable/base'; import { registerAllModules } from 'handsontable/registry'; // Register all Handsontable's modules. registerAllModules(); const container = document.querySelector('#example3'); new Handsontable(container, { data: [ ['A1', 'B1', 'C1', 'D1', 'E1', 'F1'], ['A2', 'B2', 'C2', 'D2', 'E2', 'F2'], ['A3', 'B3', 'C3', 'D3', 'E3', 'F3'], ['A4', 'B4', 'C4', 'D4', 'E4', 'F4'], ['A5', 'B5', 'C5', 'D5', 'E5', 'F5'], ], rowHeaders: true, colHeaders: true, autoWrapRow: true, autoWrapCol: true, stretchH: 'all', height: 'auto', licenseKey: 'non-commercial-and-evaluation', customBorders: [ { range: { from: { row: 1, col: 1, }, to: { row: 3, col: 4, }, }, top: { width: 2, color: '#5292F7', style: 'dotted', }, bottom: { width: 2, color: 'red', }, start: { width: 2, color: 'orange', style: 'dashed', }, end: { width: 2, color: 'magenta', }, }, { row: 2, col: 2, start: { width: 2, color: 'red', }, end: { width: 1, color: 'green', }, }, ], }); ``` ```javascript import Handsontable from 'handsontable/base'; import { registerAllModules } from 'handsontable/registry'; // Register all Handsontable's modules. registerAllModules(); const container = document.querySelector('#example3')!; new Handsontable(container, { data: [ ['A1', 'B1', 'C1', 'D1', 'E1', 'F1'], ['A2', 'B2', 'C2', 'D2', 'E2', 'F2'], ['A3', 'B3', 'C3', 'D3', 'E3', 'F3'], ['A4', 'B4', 'C4', 'D4', 'E4', 'F4'], ['A5', 'B5', 'C5', 'D5', 'E5', 'F5'], ], rowHeaders: true, colHeaders: true, autoWrapRow: true, autoWrapCol: true, stretchH: 'all', height: 'auto', licenseKey: 'non-commercial-and-evaluation', customBorders: [ { range: { from: { row: 1, col: 1, }, to: { row: 3, col: 4, }, }, top: { width: 2, color: '#5292F7', style: 'dotted', }, bottom: { width: 2, color: 'red', }, start: { width: 2, color: 'orange', style: 'dashed', }, end: { width: 2, color: 'magenta', }, }, { row: 2, col: 2, start: { width: 2, color: 'red', }, end: { width: 1, color: 'green', }, }, ], }); ``` -------------------------------- ### Initializing Pagination Source: https://handsontable.com/docs/javascript-data-grid/api/pagination Example of how to initialize the Handsontable with the Pagination plugin enabled and configured. ```APIDOC ## Initializing Pagination ### Description This example demonstrates how to enable and configure the Pagination plugin when initializing a Handsontable instance. ### Configuration ```javascript const hot = new Handsontable(document.getElementById('example'), { data: getData(), pagination: { pageSize: 10, pageSizeList: ['auto', 5, 10, 20, 50, 100], initialPage: 1, showPageSize: true, showCounter: true, showNavigation: true, }, }); ``` ``` -------------------------------- ### Example Data for Pagination Source: https://handsontable.com/docs/javascript-data-grid/rows-pagination This is a sample dataset used to demonstrate pagination functionality. It includes various product details. ```javascript const data = [ { model: 'Trail Helmet', price: 1311.09, sellDate: '2025-12-27', sellTime: '14:45', inStock: false }, { model: 'Windbreaker Jacket', price: 1573.57, sellDate: '2025-09-20', sellTime: '20:31', inStock: false }, { model: 'Speed Gloves', price: 338.01, sellDate: '2025-10-22', sellTime: '18:56', inStock: false }, { model: 'Carbon Handlebar', price: 309.18, sellDate: '2025-11-10', sellTime: '15:20', inStock: true }, { model: 'LED Bike Light', price: 1289.0, sellDate: '2025-08-22', sellTime: '15:34', inStock: true }, { model: 'Action Camera', price: 1655.66, sellDate: '2025-06-12', sellTime: '15:38', inStock: false }, { model: 'Hydration Pack', price: 1126.33, sellDate: '2025-09-15', sellTime: '06:29', inStock: false }, { model: 'Racing Socks', price: 157.45, sellDate: '2025-01-26', sellTime: '19:25', inStock: true }, { model: 'Aero Bottle', price: 1707.67, sellDate: '2025-02-02', sellTime: '17:34', inStock: true }, { model: 'Road Tire Tube', price: 601.95, sellDate: '2025-04-14', sellTime: '08:02', inStock: true }, { model: 'HL Road Tire', price: 118.42, sellDate: '2025-02-08', sellTime: '06:08', inStock: false }, { model: 'Racing Socks', price: 1721.99, sellDate: '2025-10-13', sellTime: '09:01', inStock: true }, { model: 'Action Camera', price: 1620.39, sellDate: '2025-07-18', sellTime: '05:53', inStock: false }, { model: 'Trail Helmet', price: 1051.16, sellDate: '2025-01-21', sellTime: '09:44', inStock: true }, { model: 'Fitness Watch', price: 1534.64, sellDate: '2025-02-27', sellTime: '09:19', inStock: true }, { model: 'Comfort Saddle', price: 984.12, sellDate: '2025-03-16', sellTime: '07:24', inStock: false }, { model: 'Comfort Saddle', price: 1316.13, sellDate: '2025-02-11', sellTime: '11:01', inStock: true }, { model: 'Carbon Handlebar', price: 774.69, sellDate: '2025-10-17', sellTime: '11:38', inStock: false }, { model: 'Road Tire Tube', price: 1887.19, sellDate: '2025-10-19', sellTime: '06:02', inStock: true }, { model: 'Cycling Cap', price: 519.44, sellDate: '2025-10-21', sellTime: '03:54', inStock: true }, { model: 'Trail Helmet', price: 1149.2, sellDate: '2025-04-24', sellTime: '04:40', inStock: false }, { model: 'Carbon Handlebar', price: 915.24, sellDate: '2025-07-10', sellTime: '05:22', inStock: true }, { model: 'Comfort Saddle', price: 1625.63, sellDate: '2025-03-31', sellTime: '23:55', inStock: true }, { model: 'Racing Socks', price: 143.76, sellDate: '2025-12-02', sellTime: '07:25', inStock: true }, { model: 'Cycling Cap', price: 981.24, sellDate: '2025-08-09', sellTime: '19:52', inStock: false }, { model: 'Comfort Saddle', price: 779.4, sellDate: '2025-06-12', sellTime: '17:08', inStock: true }, { model: 'Carbon Handlebar', price: 1512.24, sellDate: '2025-07-27', sellTime: '07:02', inStock: true }, { model: 'Cycling Cap', price: 444.79, sellDate: '2025-09-11', sellTime: '10:05', inStock: false } ]; ``` -------------------------------- ### Get DOM Elements for Shortcut Log Source: https://handsontable.com/docs/javascript-data-grid/recipes/accessibility/keyboard-shortcuts This code snippet shows how to acquire references to specific DOM elements used for logging shortcut actions and submission details. These elements are typically located within a parent container related to the Handsontable example preview. ```javascript const preview = container.closest('.hot-example-preview') ?? container.parentElement; const lastShortcutEl = preview.querySelector('.last-shortcut'); const lastSubmissionEl = preview.querySelector('.last-submission'); ```