Create Custom Cell Templates

3 Jul 202610 minutes to read

The React Spreadsheet Editor component lets you display custom templates inside cells.You can insert icons, labels, buttons, or any custom templates. This is useful when you need custom functionality inside cells. You can add templates to cells by dynamically assigning a custom template property directly to individual cells. When a cell has this custom template property, you can use the beforeCellRender event to append the desired template element to the cell.

The following sample demonstrates how to insert a Syncfusion Dropdown component into Spreadsheet cells using this custom template property. Additionally, a custom ribbon item named “DropDown List” is included under a new “Template” ribbon tab. When this ribbon item is selected, the Spreadsheet dynamically inserts a dropdown into the currently active cell.

The following code sample shows how to create custom cell templates.

import * as React from 'react';
import { createRoot } from 'react-dom/client';
import { SpreadsheetComponent, getCellIndexes, getCell, setCell } from '@syncfusion/ej2-react-spreadsheet';
import { DropDownList } from '@syncfusion/ej2-dropdowns';

function App() {
  let spreadsheet = null;
  const spreadsheetRef = React.useRef(null);

  const dropDownOptions = [10, 20, 30, 40, 50, 60];

  const onCreated = () => {
    spreadsheet = spreadsheetRef.current;
    if (!spreadsheet) return;

    // Custom template tab to add dropdown to cell.
    spreadsheet.addRibbonTabs([{ header: { text: 'Template' }, content: [{
      text: 'DropDown List', click: () => {
        if (!spreadsheet) return;
        const sheet = spreadsheet.getActiveSheet();
        const [rowIdx, colIdx] = getCellIndexes(sheet.activeCell);
        const cellModel = getCell(rowIdx, colIdx, sheet);
        const cellEle = spreadsheet.getCell(rowIdx, colIdx);
        if (cellModel && cellModel.template === 'dropdown-list') return;
        addDropDownlist(cellEle, dropDownOptions);
      }
    }] }]);

    spreadsheet.setRowsHeight(35, ['1:100']);
    // Rendering dropdown list for a specific range initially.
    const activeSheet = spreadsheet.getActiveSheet();
    for (let colIdx = 0; colIdx <= 3; colIdx++) {
        setCell(0, colIdx, activeSheet, { template: 'dropdown-list' }, true);
    }
    spreadsheet.resize();
  };

  // Triggers before the cell is appended to the DOM.
  const beforeCellRender = (args) => {
    if (args.rowIndex !== undefined && args.colIndex !== undefined) {
      // To render dropdown if template property 'dropdown-list' is set.
      if (args.cell && args.cell.template === 'dropdown-list') {
        addDropDownlist(args.element, dropDownOptions);
      }
    }
  };

  // To render the dropdown list.
  const addDropDownlist = (element, legendOptions) => {
    element.innerHTML = '';
    const inputEle = document.createElement("input");
    element.appendChild(inputEle);
    new DropDownList({
      placeholder: 'Select a value',
      dataSource: legendOptions,
      cssClass: 'e-dropdown-list',
      change: (event)=>{
        spreadsheetRef.current.updateCell({value: event.value.toString()}, ( spreadsheet.getActiveSheet()).activeCell);
      }
    }, inputEle);
  };

  return (
    <SpreadsheetComponent
      ref={spreadsheetRef}
      created={onCreated}
      beforeCellRender={beforeCellRender}
    />
  );
}

export default App;

const root = createRoot(document.getElementById('root'));
root.render(<App />);
import * as React from 'react';
import { createRoot } from 'react-dom/client';
import { SpreadsheetComponent, getCellIndexes, getCell, setCell } from '@syncfusion/ej2-react-spreadsheet';
import { DropDownList } from '@syncfusion/ej2-dropdowns';

function App(): React.ReactElement {
  let spreadsheet: SpreadsheetComponent = null;
  const spreadsheetRef = React.useRef<SpreadsheetComponent>(null);

  const dropDownOptions: number[] = [10, 20, 30, 40, 50, 60];

  const onCreated = (): void => {
    spreadsheet = spreadsheetRef.current;
    if (!spreadsheet) return;

    // Custom template tab to add dropdown to cell.
    spreadsheet.addRibbonTabs([{ header: { text: 'Template' }, content: [{
      text: 'DropDown List', click: () => {
        if (!spreadsheet) return;
        const sheet: any = spreadsheet.getActiveSheet();
        const [rowIdx, colIdx]: number[] = getCellIndexes((sheet as any).activeCell);
        const cellModel: any = getCell(rowIdx, colIdx, sheet as any);
        const cellEle: HTMLElement = spreadsheet.getCell(rowIdx, colIdx) as HTMLElement;
        if (cellModel && (cellModel as any).template === 'dropdown-list') return;
        addDropDownlist(cellEle as any, dropDownOptions);
      }
    }] }]);

    spreadsheet.setRowsHeight(35, ['1:100']);
    // Rendering dropdown list for a specific range initially.
    const activeSheet: any = spreadsheet.getActiveSheet();
    for (let colIdx = 0; colIdx <= 3; colIdx++) {
        setCell(0, colIdx, activeSheet as any, { template: 'dropdown-list' } as any, true);
    }
    spreadsheet.resize();
  };

  // Triggers before the cell is appended to the DOM.
  const beforeCellRender = (args: any): void => {
    if (args.rowIndex !== undefined && args.colIndex !== undefined) {
      // To render dropdown if template property 'dropdown-list' is set.
      if (args.cell && args.cell.template === 'dropdown-list') {
        addDropDownlist(args.element as HTMLElement, dropDownOptions);
      }
    }
  };

  // To render the dropdown list.
  const addDropDownlist = (element: HTMLElement, legendOptions: number[]): void => {
    element.innerHTML = '';
    const inputEle: HTMLInputElement = document.createElement("input");
    element.appendChild(inputEle);
    new DropDownList({
      placeholder: 'Select a value',
      dataSource: legendOptions,
      cssClass: 'e-dropdown-list',
      change: (event: any)=>{
        spreadsheetRef.current.updateCell({value: event.value.toString()}, ( spreadsheet.getActiveSheet() as any).activeCell);
      }
    }, inputEle);
  };

  return (
    <SpreadsheetComponent
      ref={spreadsheetRef}
      created={onCreated}
      beforeCellRender={beforeCellRender}
    />
  );
}

export default App;

const root = createRoot(document.getElementById('root')!);
root.render(<App />);