Selection in EJ2 Angular Rich Text Editor Component
6 Nov 202514 minutes to read
Text selection
The Rich Text Editor supports character range-based text selection using the Syncfusion Slider component. This feature allows users to select a specific range of characters (e.g., 33–45) within the editor content, which is then automatically highlighted.
This functionality is useful for scenarios where precise text selection is needed for operations such as copying, formatting, or analysis.
import { Component, ViewChild } from '@angular/core';
import { SliderComponent, ChangeEventArgs, SliderModule } from '@syncfusion/ej2-angular-inputs';
import { RichTextEditorComponent, RichTextEditorModule, ToolbarService, LinkService, ImageService, HtmlEditorService, QuickToolbarService, TableService, VideoService, AudioService, PasteCleanupService } from '@syncfusion/ej2-angular-richtexteditor';
@Component({
selector: 'app-root',
standalone: true,
imports: [RichTextEditorModule, SliderModule],
template: `
<div id="container">
<div class="sliderwrap">
<label class="labeltext userselect">Range Slider</label>
<ejs-slider
#rangeSlider
[type]="'Range'"
[value]="sliderValue"
[min]="0"
[max]="maxLength"
(change)="onChange($event)"
></ejs-slider>
</div>
<ejs-richtexteditor
#rte
[value]="rteContent"
(created)="onEditorCreated()"
></ejs-richtexteditor>
</div>
`,
providers: [
ToolbarService,
LinkService,
ImageService,
HtmlEditorService,
QuickToolbarService,
TableService,
VideoService,
AudioService,
PasteCleanupService,
],
})
export class AppComponent {
@ViewChild('rangeSlider') rangeSlider!: SliderComponent;
@ViewChild('rte') rte!: RichTextEditorComponent;
sliderValue: number[] = [0, 50];
maxLength: number = 400;
rteContent: string = `<p>The Syncfusion Rich Text Editor, a WYSIWYG (what you see is what you get) editor, is a user interface that allows you to create, edit, and format rich text content. You can try out a demo of this editor here. Key features: Provides IFRAME and DIV modes. Bulleted and numbered lists. Handles images, hyperlinks, videos, hyperlinks, uploads, etc. Contains undo/redo manager.</p>`;
onEditorCreated(): void {
setTimeout(() => {
const panel = this.rte.contentModule.getEditPanel() as HTMLElement;
const realLength = panel.textContent?.length ?? 0;
this.maxLength = realLength;
this.rangeSlider.max = realLength;
this.rangeSlider.dataBind();
panel.focus();
this.onChange({ value: this.rangeSlider.value } as ChangeEventArgs);
}, 100);
}
getTextNodeAtOffset(root: Node, offset: number): { node: Text; offset: number } | null {
let currentOffset = 0;
const walker: TreeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null);
while (walker.nextNode()) {
const node = walker.currentNode as Text;
const nodeLength = node.textContent?.length ?? 0;
if (currentOffset + nodeLength >= offset) {
return {
node,
offset: offset - currentOffset,
};
}
currentOffset += nodeLength;
}
return null;
}
onChange(args: ChangeEventArgs): void {
const [start, end] = args.value as any;
const panel = this.rte.contentModule.getEditPanel() as HTMLElement;
const maxLength = panel.textContent?.length ?? 0;
const safeStart = Math.min(start, maxLength);
const safeEnd = Math.min(end, maxLength);
const startInfo = this.getTextNodeAtOffset(panel, safeStart);
const endInfo = this.getTextNodeAtOffset(panel, safeEnd);
if (startInfo && endInfo) {
const range = document.createRange();
range.setStart(startInfo.node, startInfo.offset);
range.setEnd(endInfo.node, endInfo.offset);
const selection = window.getSelection();
if (selection) {
selection.removeAllRanges();
selection.addRange(range);
}
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Node selection
Node selection allows users to programmatically select entire HTML elements (nodes) such as paragraphs, images, or tables within the Rich Text Editor. This is useful when you want to highlight or manipulate specific content blocks without relying on manual user selection.
The following example demonstrates how to select a paragraph node programmatically using the browser’s native Range and Selection APIs.
import { Component, ViewChild } from '@angular/core';
import { RichTextEditorModule, RichTextEditorComponent, ToolbarService, LinkService, ImageService, HtmlEditorService, QuickToolbarService, TableService, PasteCleanupService } from '@syncfusion/ej2-angular-richtexteditor';
@Component({
imports: [
RichTextEditorModule
],
standalone: true,
selector: 'app-root',
template: `<button id="btn" style="margin:0 0 20px 0" class="e-btn" (click)="selectParagraph()">Select Paragraph</button>
<ejs-richtexteditor #rte id="editor" [value]="value"></ejs-richtexteditor>`,
providers: [ToolbarService, LinkService, ImageService, HtmlEditorService, QuickToolbarService, TableService, PasteCleanupService]
})
export class AppComponent {
@ViewChild('rte') editor!: RichTextEditorComponent;
public value: string = `<p>This is paragraph one.</p><p>This is paragraph two.</p>`;
selectParagraph(): void {
const panel = (this.editor as any).contentModule.getEditPanel();
const paragraphs = panel.querySelectorAll('p');
if (paragraphs.length > 1) {
const range = document.createRange();
range.selectNode(paragraphs[1]); // Select the second paragraph
const selection = window.getSelection();
if (selection) {
selection.removeAllRanges();
selection.addRange(range);
}
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Cell selection
Cell selection allows users to programmatically select specific table cells within the Rich Text Editor. This is useful for highlighting or manipulating content inside tables without requiring manual user interaction.
The following example demonstrates how to select a table cell programmatically using the browser’s native Range and Selection APIs.
import { Component, ViewChild } from '@angular/core';
import { RichTextEditorModule, RichTextEditorComponent, ToolbarService, LinkService, ImageService, HtmlEditorService, QuickToolbarService, TableService, PasteCleanupService } from '@syncfusion/ej2-angular-richtexteditor';
@Component({
imports: [
RichTextEditorModule
],
standalone: true,
selector: 'app-root',
template: `<button id="btn" class="e-btn" style="margin-bottom: 20px;" (click)="selectCell()">Select Cell</button>
<ejs-richtexteditor #rte [height]="300" [value]="value"></ejs-richtexteditor>`,
providers: [ToolbarService, LinkService, ImageService, HtmlEditorService, QuickToolbarService, TableService, PasteCleanupService]
})
export class AppComponent {
@ViewChild('rte') rte!: RichTextEditorComponent;
public value: string = `
<table style="width:100%; border-collapse: collapse;" border="1">
<thead>
<tr>
<th style="font-weight:bold; padding:8px;">Product</th>
<th style="font-weight:bold; padding:8px;">Price</th>
<th style="font-weight:bold; padding:8px;">Stock</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding:8px;">Product A</td>
<td style="padding:8px;">$25</td>
<td style="padding:8px;">Available</td>
</tr>
<tr>
<td style="padding:8px;">Product B</td>
<td style="padding:8px;">$40</td>
<td style="padding:8px;">Out of Stock</td>
</tr>
</tbody>
</table>
`;
selectCell(): void {
const panel = (this.rte as any).contentModule.getEditPanel();
const cells = panel.querySelectorAll('td');
if (cells.length > 2) {
const cell = cells[2]; // Third cell
const range = document.createRange();
range.selectNode(cell);
const selection = window.getSelection();
if (selection) {
selection.removeAllRanges();
selection.addRange(range);
}
cell.style.backgroundColor = '#cce5ff';
cell.classList.add('e-cell-select');
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Select all content
To select all content within the Rich Text Editor, use the selectAll method. This method highlights all the text and elements inside the editor, allowing users to perform actions such as formatting or deleting the entire content.
import { Component, ViewChild } from '@angular/core';
import { RichTextEditorModule, RichTextEditorComponent, ToolbarService, LinkService, ImageService, HtmlEditorService, QuickToolbarService, TableService, PasteCleanupService } from '@syncfusion/ej2-angular-richtexteditor';
@Component({
imports: [
RichTextEditorModule
],
standalone: true,
selector: 'app-root',
template: `<button id="btn" style="margin:0 0 20px 0" class="e-btn" (click)="selectAllContent()">Select All</button><ejs-richtexteditor #rte id='editor' [value]='value'></ejs-richtexteditor>`,
providers: [ToolbarService, LinkService, ImageService, HtmlEditorService, QuickToolbarService, TableService, PasteCleanupService]
})
export class AppComponent {
@ViewChild('rte') editor!: RichTextEditorComponent;
public value: string =
'<p>The Rich Text Editor component is WYSIWYG ("what you see is what you get") editor that provides the best user experience to create and update the content. Users can format their content using standard toolbar commands.</p><p><b>Key features:</b></p><ul><li><p>Provides <IFRAME> and <DIV> modes</p></li><li><p>Capable of handling markdown editing.</p></li><li><p>Contains a modular library to load the necessary functionality on demand.</p></li><li><p>Provides a fully customizable toolbar.</p></li><li><p>Provides HTML view to edit the source directly for developers.</p></li><li><p>Supports third-party library integration.</p></li><li><p>Allows preview of modified content before saving it.</p></li><li><p>Handles images, hyperlinks, video, hyperlinks, uploads, etc.</p></li><li><p>Contains undo/redo manager.</p></li><li><p>Creates bulleted and numbered lists.</p></li></ul>';
selectAllContent(): void {
this.editor.selectAll();
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));