Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Document-Processing-toc.html
Original file line number Diff line number Diff line change
Expand Up @@ -5313,6 +5313,8 @@
<li><a href="/document-processing/excel/spreadsheet/react/how-to/create-a-object-structure">Create a object structure </a></li>
<li><a href="/document-processing/excel/spreadsheet/react/how-to/change-active-sheet">Changing the active sheet while importing a file</a></li>
<li><a href="/document-processing/excel/spreadsheet/react/how-to/identify-the-context-menu-opened">Identify the context menu opened</a></li>
<li><a href="/document-processing/excel/spreadsheet/react/how-to/dynamic-dropdown-cell-template">Find and replace the text within the selected range of cells</a></li>
<li><a href="/document-processing/excel/spreadsheet/react/how-to/find-and-replace-text-for-selected-range">Add dynamic cell templates in the spreadsheet</a></li>
</ul>
</li>
<li><a href="/document-processing/excel/spreadsheet/react/mobile-responsiveness">Mobile Responsiveness</a></li>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
layout: post
title: Dynamic cell templates in the React Spreadsheet component | Syncfusion
description: Learn here all about cell dropdown in Syncfusion React Spreadsheet component of Syncfusion Essential JS 2 and more.
control: Spreadsheet
platform: document-processing
documentation: ug
---

## Dynamic Cell Template — Dropdown to Input Behavior

A custom Ribbon tab ("Template" -> "DropDown List") is added via addRibbonTabs in created, enabling a dropdown to be injected into the active cell.

On click, the code resolves the active cell using getActiveSheet, getCellIndexes, retrieves the cell model/element via getCell, and marks it with template: 'dropdown-list';

During beforeCellRender, if cell.template === 'dropdown-list', the cell DOM is cleared and an input element is appended.

A Syncfusion DropDownList is instantiated on that input with dataSource, placeholder, cssClass, and initial value, and hooked to its change event.

When a non-"Other" option is chosen, the selection is written back into the sheet using updateCell({ value }) on sheet.activeCell.

When "Other" is chosen, the dropdown element is located with getComponent().

The dropdown is recreated automatically for any cell whose model retains template: 'dropdown-list', ensuring consistent behavior as users navigate.

Layout helpers like ColumnsDirective configure column widths, while SpreadsheetComponent, SheetsDirective, and SheetDirective provide the Spreadsheet structure.

The options list (dropdownData) includes "Other" to trigger the switch from templated dropdown to native text entry.

The following code example shows how to add dropdown from custom template

{% tabs %}
{% highlight js tabtitle="app.jsx" %}
{% include code-snippet/spreadsheet/react/dynamic-cell-template-cs1/app/app.jsx %}
{% endhighlight %}
{% highlight ts tabtitle="app.tsx" %}
{% include code-snippet/spreadsheet/react/dynamic-cell-template-cs1/app/app.tsx %}
{% endhighlight %}
{% endtabs %}

{% previewsample "/document-processing/code-snippet/spreadsheet/react/dynamic-cell-template-cs1" %}

## Initialize the dropdown for cells

This implementation initializes a SpreadsheetComponent and in the created handler sets row height, applies a 'dropdown-list' template to a range using setCell, and calls resize.

The beforeCellRender event checks each cell's template and injects an ej2-dropdowns DropDownList into the cell DOM when the template equals 'dropdown-list'.

On selection, dropDownChangeHandler updates the spreadsheet by calling updateCell on the spreadsheetRef, writing the chosen value into the active cell.
Clipboard operations are detected via actionBegin and actionComplete.

In beforeCellUpdate, pasted cells with the dropdown template are fixed up: if a dropdown component exists it’s updated via getComponent, otherwise addDropDownlist re-renders it.

The pattern uses a template flag on cells and lazy-mounts the interactive dropdown only when the cell is rendered or updated, keeping the sheet performant and editable.

The following code example shows how to initialize the dropdown for cells

{% tabs %}
{% highlight js tabtitle="app.jsx" %}
{% include code-snippet/spreadsheet/react/initialize-cell-dropdown-cs1/app/app.jsx %}
{% endhighlight %}
{% highlight ts tabtitle="app.tsx" %}
{% include code-snippet/spreadsheet/react/initialize-cell-dropdown-cs1/app/app.tsx %}
{% endhighlight %}
{% endtabs %}

{% previewsample "/document-processing/code-snippet/spreadsheet/react/initialize-cell-dropdown-cs1" %}

## Dynamic Cell Template — In-Cell Dropdown via Data Validation

The sample adds a dropdown into cells by applying list validation with addDataValidation (using inCellDropDown) inside the onCreated handler.

It formats headers and columns via cellFormat and numberFormat to prepare the spreadsheet UI.
The cellSave event inspects the edited cell using getCellIndexes, getSheet, getSheetIndex, getCell, and getColumn.

Validation is detected with the cell's validation property or checkColumnValidation, ensuring list-type rules are honored.

When the user selects Other, the code removes validation with removeDataValidation, clears the cell using clear, and calls startEdit to allow free-text input.
The spreadsheet instance is accessed via the component ref on SpreadsheetComponent (also configured with openUrl/saveUrl).

As an alternative to the toolbar demo, you can update the custom cell using updateCell and embed a dropdown directly with addDropDownToCell during any event, avoiding extra UI controls.

Together these methods implement a dynamic cell template that presents an in-cell dropdown, detects special selections, and swaps to editable mode when needed.

The following code example shows how the dropdown applied via data validation.

{% tabs %}
{% highlight js tabtitle="app.jsx" %}
{% include code-snippet/spreadsheet/react/data-validation-dropdown-cs1/app/app.jsx %}
{% endhighlight %}
{% highlight ts tabtitle="app.tsx" %}
{% include code-snippet/spreadsheet/react/data-validation-dropdown-cs1/app/app.tsx %}
{% endhighlight %}
{% endtabs %}

{% previewsample "/document-processing/code-snippet/spreadsheet/react/data-validation-dropdown-cs1" %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
layout: post
title: Find and replace the text within the selected range of cells in the React Spreadsheet component | Syncfusion
description: Learn here all about changing the active sheet index while importing a file in Syncfusion React Spreadsheet component of Syncfusion Essential JS 2 and more.
control: Spreadsheet
platform: document-processing
documentation: ug
---

## Find and replace the text within the selected range of cells

What it does: Limits “Replace All” so replacements occur only inside the currently selected cells.

Select a cell range, open Find and Replace, enter Find/Replace values, then choose Replace All.

How it works: Intercepts the beforeReplaceAll action via [actionBegin](https://ej2.syncfusion.com/react/documentation/api/spreadsheet/index-default#actionbegin), reads getActiveSheet().selectedRange, expands it to cell addresses, and filters eventArgs.addressCollection to match only the selection.

Key APIs: actionBegin, getActiveSheet().selectedRange, eventArgs.addressCollection, and optional programmatic replace({ value, replaceValue, mode: 'Sheet', isCSen, isEMatch }).

Only cells in your selection are processed; all others are excluded before the replace runs.

The following code example shows how to find and replace the text within the selected range of cells

{% tabs %}
{% highlight js tabtitle="app.jsx" %}
{% include code-snippet/spreadsheet/react/find-and-replace-cs1/app/app.jsx %}
{% endhighlight %}
{% highlight ts tabtitle="app.tsx" %}
{% include code-snippet/spreadsheet/react/find-and-replace-cs1/app/app.tsx %}
{% endhighlight %}
{% endtabs %}

{% previewsample "/document-processing/code-snippet/spreadsheet/react/find-and-replace-cs1" %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { createRoot } from 'react-dom/client';
import './index.css';
import * as React from 'react';
import { SheetsDirective, SheetDirective, ColumnsDirective, RangesDirective, RangeDirective, getColumn, getCellIndexes, getCell, getSheet, getSheetIndex, checkColumnValidation } from '@syncfusion/ej2-react-spreadsheet';
import { ColumnDirective } from '@syncfusion/ej2-react-spreadsheet';
import { SpreadsheetComponent } from '@syncfusion/ej2-react-spreadsheet';
import { defaultData } from './datasource';


function App() {
let spreadsheet;
const onCreated = () => {
// Apply styles to the specified range in the active sheet.
spreadsheet.cellFormat({ fontWeight: 'bold', textAlign: 'center', verticalAlign: 'middle' }, 'A1:F1');
// Apply format to the specified range in the active sheet.
spreadsheet.numberFormat('$#,##0.00', 'F2:F31');
// The default format code for the date format is 'm/d/yyyy'.
spreadsheet.numberFormat('m/d/yyyy', 'E2:E30');
spreadsheet.addDataValidation({ type: 'List', inCellDropDown: true, value1: 'Option 1,Option 2,Option 3,Other' }, 'A1:A25')
spreadsheet.addDataValidation({ type: 'List', inCellDropDown: true, ignoreBlank: true, value1: 'Option 1,Option 2,Option 3,Other' }, 'B:B');
};

const cellSave = (args) => {
let addressArr = args.address.split('!');
let indexes = getCellIndexes(addressArr[1]);
let sheet = getSheet(spreadsheet, getSheetIndex(spreadsheet,addressArr[0]));
console.log(sheet)
let cell = getCell(indexes[0], indexes[1], sheet);
let column = getColumn(sheet, indexes[1]);
let validation = (cell && cell.validation && cell.validation.type == 'List') || checkColumnValidation(column, indexes[0], indexes[1]);
if (validation && args.value === 'Other') {
// Removing data validation if Other option is selected.
spreadsheet.removeDataValidation(addressArr[1]);
// To clear the cell content.
spreadsheet.clear({ type: 'Clear Contents', range: addressArr[1] });
// To start editing when other option is selected.
spreadsheet.startEdit();
}
}

return (<div className='control-pane'>
<div className='control-section spreadsheet-control'>
<SpreadsheetComponent openUrl='https://services.syncfusion.com/react/production/api/spreadsheet/open' saveUrl='https://services.syncfusion.com/react/production/api/spreadsheet/save' ref={(ssObj) => { spreadsheet = ssObj; }} created={onCreated.bind(this)} cellSave={cellSave}>
<SheetsDirective>
<SheetDirective name="Car Sales Report">
<RangesDirective>
<RangeDirective dataSource={defaultData}></RangeDirective>
</RangesDirective>
<ColumnsDirective>
<ColumnDirective width={180}></ColumnDirective>
<ColumnDirective width={130}></ColumnDirective>
<ColumnDirective width={130}></ColumnDirective>
<ColumnDirective width={180}></ColumnDirective>
<ColumnDirective width={130}></ColumnDirective>
<ColumnDirective width={120}></ColumnDirective>
</ColumnsDirective>
</SheetDirective>
</SheetsDirective>
</SpreadsheetComponent>
</div>
</div>);
}
export default App;

const root = createRoot(document.getElementById('root'));
root.render(<App />);
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { createRoot } from 'react-dom/client';
import './index.css';
import * as React from 'react';
import { SheetsDirective, SheetDirective, ColumnsDirective, RangesDirective, RangeDirective, getColumn, getCellIndexes, getCell, getSheet, getSheetIndex, checkColumnValidation } from '@syncfusion/ej2-react-spreadsheet';
import { ColumnDirective } from '@syncfusion/ej2-react-spreadsheet';
import { SpreadsheetComponent } from '@syncfusion/ej2-react-spreadsheet';
import { defaultData } from './datasource';


function App(): React.ReactElement {
let spreadsheet: any;
const onCreated = (): void => {
// Apply styles to the specified range in the active sheet.
spreadsheet.cellFormat({ fontWeight: 'bold', textAlign: 'center', verticalAlign: 'middle' }, 'A1:F1');
// Apply format to the specified range in the active sheet.
spreadsheet.numberFormat('$#,##0.00', 'F2:F31');
// The default format code for the date format is 'm/d/yyyy'.
spreadsheet.numberFormat('m/d/yyyy', 'E2:E30');
spreadsheet.addDataValidation({ type: 'List', inCellDropDown: true, value1: 'Option 1,Option 2,Option 3,Other' }, 'A1:A25')
spreadsheet.addDataValidation({ type: 'List', inCellDropDown: true, ignoreBlank: true, value1: 'Option 1,Option 2,Option 3,Other' }, 'B:B');
};

const cellSave = (args: any): void => {
let addressArr = args.address.split('!');
let indexes = getCellIndexes(addressArr[1]);
let sheet = getSheet(spreadsheet, getSheetIndex(spreadsheet,addressArr[0]));
console.log(sheet)
let cell = getCell(indexes[0], indexes[1], sheet);
let column = getColumn(sheet, indexes[1]);
let validation = (cell && cell.validation && cell.validation.type == 'List') || checkColumnValidation(column, indexes[0], indexes[1]);
if (validation && args.value === 'Other') {
// Removing data validation if Other option is selected.
spreadsheet.removeDataValidation(addressArr[1]);
// To clear the cell content.
spreadsheet.clear({ type: 'Clear Contents', range: addressArr[1] });
// To start editing when other option is selected.
spreadsheet.startEdit();
}
}

return (<div className='control-pane'>
<div className='control-section spreadsheet-control'>
<SpreadsheetComponent openUrl='https://services.syncfusion.com/react/production/api/spreadsheet/open' saveUrl='https://services.syncfusion.com/react/production/api/spreadsheet/save' ref={(ssObj: any) => { spreadsheet = ssObj; }} created={onCreated.bind(undefined as any)} cellSave={cellSave}>
<SheetsDirective>
<SheetDirective name="Car Sales Report">
<RangesDirective>
<RangeDirective dataSource={defaultData}></RangeDirective>
</RangesDirective>
<ColumnsDirective>
<ColumnDirective width={180}></ColumnDirective>
<ColumnDirective width={130}></ColumnDirective>
<ColumnDirective width={130}></ColumnDirective>
<ColumnDirective width={180}></ColumnDirective>
<ColumnDirective width={130}></ColumnDirective>
<ColumnDirective width={120}></ColumnDirective>
</ColumnsDirective>
</SheetDirective>
</SheetsDirective>
</SpreadsheetComponent>
</div>
</div>);
}
export default App;

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