Toolbar in Vue Rich text editor component
14 Oct 202424 minutes to read
The Rich Text Editor toolbar contains a collection of tools such as bold, italic, and text alignment buttons that are used to format the content. However, in most integrations, you can customize the toolbar configurations easily to suit your needs.
To create Rich Text Editor with Markdown editing feature, inject the Toolbar
module to the Rich Text Editor using the RichTextEditor.Inject(Toolbar)
method.
The Rich Text Editor allows you to configure different types of toolbar using toolbarSettings.type
property. The types of toolbar are:
- Expand
- MultiRow
Expand Toolbar
The default mode of toolbarSettings.type
is Expand, it will hide the overflowing items in the next row. By clicking the expand arrow, view the overflowing toolbar items.
<template>
<div>
<div class="control-section">
<div class="sample-container">
<div class="default-section">
<ejs-richtexteditor ref="rteObj" :height="340" :toolbarSettings="toolbarSettings"><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>
</ul></ejs-richtexteditor>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { provide } from 'vue';
import { RichTextEditorComponent as EjsRichtexteditor, Toolbar, HtmlEditor } from "@syncfusion/ej2-vue-richtexteditor";
const toolbarSettings = {
type: 'Expand',
items: ['Bold', 'Italic', 'Underline', 'StrikeThrough',
'FontName', 'FontSize', 'FontColor', 'BackgroundColor',
'LowerCase', 'UpperCase', '|',
'Formats', 'Alignments', 'OrderedList', 'UnorderedList',
'Outdent', 'Indent', '|',
'CreateLink', 'Image', '|', 'ClearFormat', 'Print',
'SourceCode', 'FullScreen', '|', 'Undo', 'Redo'
]
};
provide('richtexteditor', [Toolbar, HtmlEditor]);
</script>
<style>
@import "https://ej2.syncfusion.com/vue/documentation/../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-vue-richtexteditor/styles/material.css";
</style>
<template>
<div>
<div class="control-section">
<div class="sample-container">
<div class="default-section">
<ejs-richtexteditor ref="rteObj" :height="340" :toolbarSettings="toolbarSettings">
<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>
</ul>
</ejs-richtexteditor>
</div>
</div>
</div>
</div>
</template>
<script>
import { RichTextEditorComponent, Toolbar, HtmlEditor } from "@syncfusion/ej2-vue-richtexteditor";
export default {
name: "App",
components: {
"ejs-richtexteditor": RichTextEditorComponent
},
data: function () {
return {
toolbarSettings: {
type: 'Expand',
items: ['Bold', 'Italic', 'Underline', 'StrikeThrough',
'FontName', 'FontSize', 'FontColor', 'BackgroundColor',
'LowerCase', 'UpperCase', '|',
'Formats', 'Alignments', 'OrderedList', 'UnorderedList',
'Outdent', 'Indent', '|',
'CreateLink', 'Image', '|', 'ClearFormat', 'Print',
'SourceCode', 'FullScreen', '|', 'Undo', 'Redo'
]
},
};
},
provide: {
richtexteditor: [Toolbar, HtmlEditor]
}
}
</script>
<style>@import "https://ej2.syncfusion.com/vue/documentation/../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-vue-richtexteditor/styles/material.css";</style>
Multi-row Toolbar
Set the type as MultiRow in toolbarSettings to hide the overflowing items in the next row. All toolbar items are visible.
<template>
<div>
<div class="control-section">
<div class="sample-container">
<div class="default-section">
<ejs-richtexteditor ref="rteObj" :height="340" :toolbarSettings="toolbarSettings"><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>
</ul></ejs-richtexteditor>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { provide } from 'vue';
import { RichTextEditorComponent as EjsRichtexteditor, Toolbar, HtmlEditor } from "@syncfusion/ej2-vue-richtexteditor";
const toolbarSettings = {
type: 'Expand',
items: ['Bold', 'Italic', 'Underline', 'StrikeThrough',
'FontName', 'FontSize', 'FontColor', 'BackgroundColor',
'LowerCase', 'UpperCase', '|',
'Formats', 'Alignments', 'OrderedList', 'UnorderedList',
'Outdent', 'Indent', '|',
'CreateLink', 'Image', '|', 'ClearFormat', 'Print',
'SourceCode', 'FullScreen', '|', 'Undo', 'Redo'
]
};
provide('richtexteditor', [Toolbar, HtmlEditor]);
</script>
<style>
@import "https://ej2.syncfusion.com/vue/documentation/../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-vue-richtexteditor/styles/material.css";
</style>
<template>
<div>
<div class="control-section">
<div class="sample-container">
<div class="default-section">
<ejs-richtexteditor ref="rteObj" :height="340" :toolbarSettings="toolbarSettings"><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>
</ul></ejs-richtexteditor>
</div>
</div>
</div>
</div>
</template>
<script>
import { RichTextEditorComponent, Toolbar, HtmlEditor } from "@syncfusion/ej2-vue-richtexteditor";
export default {
name: "App",
components: {
"ejs-richtexteditor":RichTextEditorComponent
},
data: function() {
return {
toolbarSettings: {
type: 'MultiRow',
items: ['Bold', 'Italic', 'Underline', 'StrikeThrough',
'FontName', 'FontSize', 'FontColor', 'BackgroundColor',
'LowerCase', 'UpperCase', '|',
'Formats', 'Alignments', 'OrderedList', 'UnorderedList',
'Outdent', 'Indent', '|',
'CreateLink', 'Image', '|', 'ClearFormat', 'Print',
'SourceCode', 'FullScreen', '|', 'Undo', 'Redo'
]
},
};
},
provide:{
richtexteditor:[Toolbar, HtmlEditor]
}
}
</script>
<style>
@import "https://ej2.syncfusion.com/vue/documentation/../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-vue-richtexteditor/styles/material.css";
</style>
Floating Toolbar
By default, toolbar is float at the top of the Rich Text Editor on scrolling. It can be customized by specifying the offset of the floating toolbar from documents top position using floatingToolbarOffset
.
Enable or disable the floating toolbar using enableFloating
of thetoolbarSettings
property.
<template>
<div>
<div class="col-lg-4 property-section">
<div title="Properties" id="property">
<table title="Properties" id="property">
<tbody>
<tr>
<td>
<div>
<ejs-checkbox label='Enable Floating' ref="checkInstance" :change="onFloatChange"
id="float" :checked="false"></ejs-checkbox>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="control-section">
<div class="sample-container">
<div class="default-section">
<ejs-richtexteditor ref="rteInstance" :height="340" :toolbarSettings="toolbarSettings">
<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>
</ul>
</ejs-richtexteditor>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { provide, ref } from 'vue';
import { RichTextEditorComponent as EjsRichtexteditor, Toolbar, HtmlEditor } from "@syncfusion/ej2-vue-richtexteditor";
import { CheckBoxComponent as EjsCheckbox } from "@syncfusion/ej2-vue-buttons";
const rteObj = ref(null);
const toolbarSettings = {
enableFloating: false
}
const onFloatChange = (args) => {
rteInstance.value.ej2Instances.toolbarSettings.enableFloating = args.checked;
rteInstance.value.rteInstance.dataBind();
}
provide('richtexteditor', [Toolbar, HtmlEditor]);
</script>
<style>@import "../../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-vue-richtexteditor/styles/material.css";</style>
<template>
<div>
<div class="col-lg-4 property-section">
<div title="Properties" id="property">
<table title="Properties" id="property">
<tbody>
<tr>
<td>
<div>
<ejs-checkbox label='Enable Floating' ref="checkInstance" :change="onFloatChange" id="float" :checked="false"></ejs-checkbox>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="control-section">
<div class="sample-container">
<div class="default-section">
<ejs-richtexteditor ref="rteInstance" :height="340" :toolbarSettings="toolbarSettings"><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>
</ul>
</ejs-richtexteditor>
</div>
</div>
</div>
</div>
</template>
<script>
import { RichTextEditorComponent, Toolbar, HtmlEditor } from "@syncfusion/ej2-vue-richtexteditor";
import { CheckBoxComponent } from "@syncfusion/ej2-vue-buttons";
export default {
name: "App",
components: {
"ejs-checkbox":CheckBoxComponent,
"ejs-richtexteditor":RichTextEditorComponent
},
data: function() {
return {
toolbarSettings: {
enableFloating: false
},
};
},
methods: {
onFloatChange: function(args) {
this.$refs.rteInstance.ej2Instances.toolbarSettings.enableFloating = args.checked;
this.$refs.rteInstance.dataBind();
}
},
provide:{
richtexteditor:[Toolbar, HtmlEditor]
}
}
</script>
<style>
@import "../../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-vue-richtexteditor/styles/material.css";
</style>
Toolbar items
The following table lists the tools available in the toolbar.
Name | Summary | Initialization |
---|---|---|
Undo | Allows to undo the actions. | toolbarSettings: { items: [‘Undo’] } |
Redo | Allows to redo the actions. | toolbarSettings: { items: [‘Redo’] } |
Alignment | Align the content with left, center, and right margin. | toolbarSettings: { items: [‘Alignments’] } |
OrderedList | Create a new list item (numbered). | toolbarSettings: { items: [‘OrderedList’] } |
UnorderedList | Create a new list item (bulleted). | toolbarSettings: { items: [‘UnorderedList’] } |
Indent | Allows to increase the indent level of the content. | toolbarSettings: { items: [‘Indent’] } |
Outdent | Allows to decrease the indent level of the content. | toolbarSettings: { items: [‘Outdent’] } |
Hyperlink | Creates a hyperlink to a text or image to a specific location in the content. | toolbarSettings: { items: [‘CreateLink’] } |
Images | Inserts an image from an online source or local computer. | toolbarSettings: { items: [‘Image’] } |
LowerCase | Change the case of selected text to lower in the content. | toolbarSettings: { items: [‘LowerCase’] } |
UpperCase | Change the case of selected text to upper in the content. | toolbarSettings: { items: [‘UpperCase’] } |
SubScript | Makes the selected text as subscript (lower). | toolbarSettings: { items: [‘SubScript’] } |
SuperScript | Makes the selected text as superscript (higher). | toolbarSettings: { items: [‘SuperScript’] } |
Allows to print the editor content. | toolbarSettings: { items: [‘Print’] } |
|
FontName | Defines the fonts that appear under the Font Family DropDownList from the Rich Text Editor’s toolbar. | toolbarSettings: { items: [‘FontName’] } |
FontSize | Defines the font sizes that appear under the Font Size DropDownList from the Rich Text Editor’s toolbar. | toolbarSettings: { items: [‘FontSize’] } |
FontColor | Specifies an array of colors can be used in the colors pop-up for font color. | toolbarSettings: { items: [‘FontColor’] } |
BackgroundColor | Specifies an array of colors can be used in the colors pop-up for background color. | toolbarSettings: { items: [‘BackgroundColor’] } |
Format | An object with the options that will appear in the paragraph format drop-down from the toolbar. | toolbarSettings: { items: [‘Formats’] } |
Blockquote | Blockquotes visually highlight important text within an editor, emphasizing key information or quotations. | toobarSettings: { items: [‘Blockquote’] } |
StrikeThrough | Apply double line strike through formatting for the selected text. | toolbarSettings: { items: [‘StrikeThrough’] } |
InlineCode | Adds code-specific styling to selected text by highlighting it with a background color and using a monospace font for easy readability. | toolbarSettings: { items: [‘InlineCode’] } |
ClearFormat | The clear format tool is used to remove all formatting styles (such as bold, italic, underline, color, superscript, subscript, and more) from currently selected text. As a result, all the formatting text will be cleared and return to its default formatting styles. | toolbarSettings: { items: [‘ClearFormat’] } |
FullScreen | Stretches the editor to the maximum width and height of the browser window. | toolbarSettings: { items: [‘FullScreen’] } |
SourceCode | The RichTextBox includes the ability for users to directly edit the HTML code via Source View. If you made any modification in source view directly, synchronize with design view. | toolbarSettings: { items: [‘SourceCode’] } |
NumberFormatList | Allows to create list items with various list style types(numbered) | toolbarSettings: { items: [‘NumberFormatList’] } |
BulletFormatList | Allows to create list items with various list style types(bulleted) | toolbarSettings: { items: [‘BulletFormatList’] } |
By default, tools will be arranged in following order.
items: [‘Bold’, ‘Italic’, ‘Underline’, ‘ ’, ‘Formats’, ‘Alignments’, ‘Blockquote’, ‘OrderedList’, ‘UnorderedList’, ‘ ’, ‘CreateLink’, ‘Image’, ‘ ’, ‘SourceCode’, ‘Undo’, ‘Redo’]
The tools order can be customized as our application requirement. If you are not specifying any tools order, the editor will create the toolbar with default items.
Custom tool
The Rich Text Editor allows you to configure your own commands to its toolbar using the toolbarSettings
property. The command can be plain text, icon, or HTML template. The order and the group can also be defined where the command should be included. Bind the action to the command by getting its instance.
This sample shows how to add your own commands to the toolbar of the Rich Text Editor. The Ω command is added to insert special characters in the editor. By clicking the Ω command, it will show the special characters list, and then choose the character to be inserted in the editor.
The following code snippet illustrates custom tool with tooltip text which will be included in items
field of the toolbarSettings
property.
In the following sample, once Rich Text Editor control is created, the concern event will be created
the Dialog component can be rendered and target as Rich Text Editor content.
{
tooltipText: 'Insert Symbol',
undo: true,
click: this.onClick.bind(this),
template: '<button class="e-tbar-btn e-btn" tabindex="-1" id="custom_tbar" style="width:100%"><div class="e-tbar-btn-text" style="font-weight: 500;"> Ω</div></button>'
}
Click the Ω command to show the special characters list, and then choose the character to be inserted in the editor.
<template>
<div>
<div class="control-section">
<div class="sample-container">
<div class="default-section" id="rteSection" style="min-height: 360px;">
<ejs-richtexteditor ref="customObj" :toolbarSettings="toolbarSettings" :created="onCreate">
<p style="margin-right:10px">The custom command "insert special character" is configured as the last
item of the toolbar. Click on the command and choose the special character you want to include
from the popup.</p>
</ejs-richtexteditor>
<ejs-dialog id='rteDialog' :buttons='dlgButtons' :width='width' :height="height" :header='header'
ref="dialogObj" :overlayClick='dialogOverlay' :visible='visible' :showCloseIcon='showCloseIcon'
:isModal='modal' :cssClass="cssClass" target='#rteSection' :created="dialogCreate">
</ejs-dialog>
<div id="customTbarDialog" style="display: none">
<div id="rteSpecial_char">
<div class="char_block" title="^">^</div>
<div class="char_block" title="_">_</div>
<div class="char_block" title="`">`</div>
<div class="char_block" title="{">{</div>
<div class="char_block" title="|">|</div>
<div class="char_block" title="}">}</div>
<div class="char_block" title="~">~</div>
<div class="char_block" title=" "> </div>
<div class="char_block" title="¡">¡</div>
<div class="char_block" title="¢">¢</div>
<div class="char_block" title="£">£</div>
<div class="char_block" title="¤">¤</div>
<div class="char_block" title="¥">¥</div>
<div class="char_block" title="₹">₹</div>
<div class="char_block" title="¦">¦</div>
<div class="char_block" title="§">§</div>
<div class="char_block" title="¨">¨</div>
<div class="char_block" title="©">©</div>
<div class="char_block" title="ª">ª</div>
<div class="char_block" title="«">«</div>
<div class="char_block" title="¬">¬</div>
<div class="char_block" title="­">­</div>
<div class="char_block" title="®">®</div>
<div class="char_block" title="¯">¯</div>
<div class="char_block" title="°">°</div>
<div class="char_block" title="±">±</div>
<div class="char_block" title="²">²</div>
<div class="char_block" title="³">³</div>
<div class="char_block" title="´">´</div>
<div class="char_block" title="µ">µ</div>
<div class="char_block" title="¶">¶</div>
<div class="char_block" title="·">·</div>
<div class="char_block" title="¸">¸</div>
<div class="char_block" title="¹">¹</div>
<div class="char_block" title="º">º</div>
<div class="char_block" title="»">»</div>
<div class="char_block" title="¼">¼</div>
<div class="char_block" title="½">½</div>
<div class="char_block" title="¾">¾</div>
<div class="char_block" title="¿">¿</div>
<div class="char_block" title="À">À</div>
<div class="char_block" title="Á">Á</div>
<div class="char_block" title="Â">Â</div>
<div class="char_block" title="Ã">Ã</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style>
#rteSpecial_char .char_block {
display: inline-block;
}
#custom_tbar,
#custom_tbar div {
cursor: pointer;
font-size: 16px;
}
#rteSpecial_char {
padding: 15px 0 15px 0;
}
#rteSpecial_char .char_block.e-active {
outline: 1px solid #e3165b;
border-color: #e3165b;
}
#rteSpecial_char .char_block {
width: 30px;
height: 30px;
line-height: 30px;
margin: 0 5px 5px 0;
text-align: center;
vertical-align: middle;
border: 1px solid #DDDDDD;
font-size: 20px;
cursor: pointer;
user-select: none;
}
</style>
<script setup>
import { provide, ref } from 'vue';
import { Browser, addClass, removeClass } from "@syncfusion/ej2-base";
import { RichTextEditorComponent as EjsRichtexteditor, Toolbar, Link, NodeSelection, Image, QuickToolbar, HtmlEditor } from "@syncfusion/ej2-vue-richtexteditor";
import { DialogComponent as EjsDialog } from '@syncfusion/ej2-vue-popups';
const customObj = ref(null);
const dialogObj = ref(null);
const selection = new NodeSelection();
let ranges = null;
const header = 'Special Characters';
const visible = false;
const modal = true;
const showCloseIcon = false;
const width = '520px';
const height = '310px';
const dlgButtons = [{ click: onInsert, buttonModel: { isPrimary: 'true', content: 'Insert' } }, { buttonModel: { content: 'Cancel' }, click: dialogOverlay }];
const toolbarSettings = {
items: ['Bold', 'Italic', 'Underline', '|', 'Formats', 'Alignments', 'OrderedList',
'UnorderedList', '|', 'CreateLink', 'Image', '|', 'SourceCode',
{
tooltipText: 'Insert Symbol',
undo: true,
click: onClick,
template: '<button class="e-tbar-btn e-btn" tabindex="-1" id="custom_tbar" style="width:100%"><div class="e-tbar-btn-text" style="font-weight: 500;"> Ω</div></button>'
}, '|', 'Undo', 'Redo']
};
const cssClass = "customClass e-rte-elements";
const onClick = function () {
customObj.value.ej2Instances.focusIn();
ranges = selection.getRange(document);
dialogObj.value.ej2Instances.width = customObj.value.ej2Instances.element.offsetWidth * 0.5;
dialogObj.value.ej2Instances.content = document.getElementById('rteSpecial_char');
dialogObj.value.ej2Instances.dataBind();
dialogObj.value.ej2Instances.show();
}
const dialogCreate = function () {
var dialogCtn = document.getElementById('rteSpecial_char');
dialogCtn.onclick = function (e) {
var target = e.target;
var activeEle = dialogObj.value.ej2Instances.element.querySelector('.char_block.e-active');
if (target.classList.contains('char_block')) {
target.classList.add('e-active');
if (activeEle) {
activeEle.classList.remove('e-active');
}
}
};
}
const onInsert = function () {
var activeEle = dialogObj.value.ej2Instances.element.querySelector('.char_block.e-active');
if (activeEle) {
customObj.value.ej2Instances.executeCommand('insertText', activeEle.textContent, { undo: true });
}
dialogOverlay();
}
const dialogOverlay = function () {
var activeEle = dialogObj.value.ej2Instances.element.querySelector('.char_block.e-active');
if (activeEle) {
activeEle.classList.remove('e-active');
}
dialogObj.value.ej2Instances.hide();
}
const onCreate = function (e) {
var customBtn = document.getElementById('custom_tbar');
dialogObj.value.ej2Instances.target = document.getElementById('rteSection');
}
provide('richtexteditor', [Toolbar, Link, Image, QuickToolbar, HtmlEditor]);
</script >
<style>
@import "https://ej2.syncfusion.com/vue/documentation/../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-vue-richtexteditor/styles/material.css";
</style>
<template>
<div>
<div class="control-section">
<div class="sample-container">
<div class="default-section" id="rteSection" style="min-height: 360px;">
<ejs-richtexteditor ref="customObj" :toolbarSettings="toolbarSettings" :created="onCreate"><p style="margin-right:10px">The custom command "insert special character" is configured as the last item of the toolbar. Click on the command and choose the special character you want to include from the popup.</p></ejs-richtexteditor>
<ejs-dialog id='rteDialog' :buttons='dlgButtons' :width='width' :height="height" :header='header' ref="dialogObj" :overlayClick='dialogOverlay' :visible='visible' :showCloseIcon='showCloseIcon' :isModal='modal' :cssClass="cssClass" target='#rteSection' :created="dialogCreate">
</ejs-dialog>
<div id="customTbarDialog" style="display: none">
<div id="rteSpecial_char">
<div class="char_block" title="^">^</div>
<div class="char_block" title="_">_</div>
<div class="char_block" title="`">`</div>
<div class="char_block" title="{">{</div>
<div class="char_block" title="|">|</div>
<div class="char_block" title="}">}</div>
<div class="char_block" title="~">~</div>
<div class="char_block" title=" "> </div>
<div class="char_block" title="¡">¡</div>
<div class="char_block" title="¢">¢</div>
<div class="char_block" title="£">£</div>
<div class="char_block" title="¤">¤</div>
<div class="char_block" title="¥">¥</div>
<div class="char_block" title="₹">₹</div>
<div class="char_block" title="¦">¦</div>
<div class="char_block" title="§">§</div>
<div class="char_block" title="¨">¨</div>
<div class="char_block" title="©">©</div>
<div class="char_block" title="ª">ª</div>
<div class="char_block" title="«">«</div>
<div class="char_block" title="¬">¬</div>
<div class="char_block" title="­">­</div>
<div class="char_block" title="®">®</div>
<div class="char_block" title="¯">¯</div>
<div class="char_block" title="°">°</div>
<div class="char_block" title="±">±</div>
<div class="char_block" title="²">²</div>
<div class="char_block" title="³">³</div>
<div class="char_block" title="´">´</div>
<div class="char_block" title="µ">µ</div>
<div class="char_block" title="¶">¶</div>
<div class="char_block" title="·">·</div>
<div class="char_block" title="¸">¸</div>
<div class="char_block" title="¹">¹</div>
<div class="char_block" title="º">º</div>
<div class="char_block" title="»">»</div>
<div class="char_block" title="¼">¼</div>
<div class="char_block" title="½">½</div>
<div class="char_block" title="¾">¾</div>
<div class="char_block" title="¿">¿</div>
<div class="char_block" title="À">À</div>
<div class="char_block" title="Á">Á</div>
<div class="char_block" title="Â">Â</div>
<div class="char_block" title="Ã">Ã</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style>
#rteSpecial_char .char_block {
display: inline-block;
}
#custom_tbar,
#custom_tbar div{
cursor: pointer;
font-size: 16px;
}
#rteSpecial_char {
padding: 15px 0 15px 0;
}
#rteSpecial_char .char_block.e-active {
outline: 1px solid #e3165b;
border-color: #e3165b;
}
#rteSpecial_char .char_block {
width: 30px;
height: 30px;
line-height: 30px;
margin: 0 5px 5px 0;
text-align: center;
vertical-align: middle;
border: 1px solid #DDDDDD;
font-size: 20px;
cursor: pointer;
user-select: none;
}
</style>
<script>
import { Browser, addClass, removeClass } from "@syncfusion/ej2-base";
import { RichTextEditorComponent, Toolbar, Link, NodeSelection, Image, QuickToolbar, HtmlEditor } from "@syncfusion/ej2-vue-richtexteditor";
import { DialogComponent } from '@syncfusion/ej2-vue-popups';
let proxy = undefined;
export default {
name: "App",
components: {
"ejs-richtexteditor":RichTextEditorComponent,
"ejs-dialog":DialogComponent
},
data: function() {
return {
selection: new NodeSelection(),
ranges: null,
header: 'Special Characters',
visible: false,
modal: true,
showCloseIcon: false,
width: '520px',
height: '310px',
dlgButtons: [{ click: this.onInsert.bind(this), buttonModel: { isPrimary:'true', content: 'Insert' } }, { buttonModel: { content: 'Cancel' }, click: this.dialogOverlay.bind(this) }],
toolbarSettings: {
items: ['Bold', 'Italic', 'Underline', '|', 'Formats', 'Alignments', 'OrderedList',
'UnorderedList', '|', 'CreateLink', 'Image', '|', 'SourceCode',
{
tooltipText: 'Insert Symbol',
undo: true,
click: this.onClick.bind(this),
template: '<button class="e-tbar-btn e-btn" tabindex="-1" id="custom_tbar" style="width:100%"><div class="e-tbar-btn-text" style="font-weight: 500;"> Ω</div></button>'
}, '|', 'Undo', 'Redo']
},
cssClass: "customClass e-rte-elements",
};
},
methods: {
onCreate: function(e) {
var customBtn = document.getElementById('custom_tbar');
this.$refs.dialogObj.ej2Instances.target = document.getElementById('rteSection');
proxy = this;
},
onClick: function() {
proxy.$refs.customObj.ej2Instances.focusIn();
proxy.ranges = proxy.selection.getRange(document);
proxy.$refs.dialogObj.ej2Instances.width = proxy.$refs.customObj.ej2Instances.element.offsetWidth * 0.5;
proxy.$refs.dialogObj.ej2Instances.content = document.getElementById('rteSpecial_char');
proxy.$refs.dialogObj.ej2Instances.dataBind();
proxy.$refs.dialogObj.ej2Instances.show();
},
dialogCreate: function() {
var dialogCtn = document.getElementById('rteSpecial_char');
proxy = this;
dialogCtn.onclick = function (e) {
var target = e.target;
var activeEle = proxy.$refs.dialogObj.ej2Instances.element.querySelector('.char_block.e-active');
if (target.classList.contains('char_block')) {
target.classList.add('e-active');
if (activeEle) {
activeEle.classList.remove('e-active');
}
}
};
},
onInsert: function() {
var activeEle = this.$refs.dialogObj.ej2Instances.element.querySelector('.char_block.e-active');
if (activeEle) {
proxy.$refs.customObj.ej2Instances.executeCommand('insertText', activeEle.textContent , {undo: true});
}
this.dialogOverlay();
},
dialogOverlay: function() {
var activeEle = this.$refs.dialogObj.ej2Instances.element.querySelector('.char_block.e-active');
if (activeEle) {
activeEle.classList.remove('e-active');
}
this.$refs.dialogObj.ej2Instances.hide();
}
},
provide:{
richtexteditor:[Toolbar, Link, Image, QuickToolbar, HtmlEditor]
}
}
</script>
<style>
@import "https://ej2.syncfusion.com/vue/documentation/../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-vue-richtexteditor/styles/material.css";
</style>
The focus will be lost while rendering the required component for the custom toolbar, causing it to render outside the Rich Text Editor and triggering a blur event. During that time, proper functionality will not be achievable. Therefore, it is recommended to set the cssClass property or class as
e-rte-elements
in the dependency component.
Quick inline toolbar
Quick commands are opened as context-menu on clicking the corresponding element. The commands must be passed as string collection to image, text, link and table attributes of the quickToolbarSettings
property.
Target Element | Default Quick Toolbar items |
---|---|
image | ‘Replace’, ‘Align’, ‘Caption’, ‘Remove’, ‘InsertLink’, ‘Display’, ‘AltText’,’Dimension’. |
link | ‘Open’, ‘Edit’, ‘UnLink’. |
text | null (Any toolbar items in the Rich Text Editor can be configured here). |
table | ‘TableHeader’, ‘TableRows’, ‘TableColumns’, ‘BackgroundColor’, ‘TableRemove’, ‘Alignments’, ‘TableCellVerticalAlign’, ‘Styles’. |
Custom tool can be added to the corresponding quick toolbar, using quickToolbarSettings
property.
The following sample demonstrates the option to insert the image to the Rich Text Editor content as well as option to rotate the image through the quick toolbar. The image rotation functionalities have been achieved through the toolbarClick
event.
<template>
<div>
<div class="control-section">
<div class="sample-container">
<div class="default-section" id="rteSection">
<ejs-richtexteditor ref="rteObj" :quickToolbarSettings="quickToolbarSettings" :toolbarClick="onToolbarClick">
<p>Rich Text Editor allows to insert images from online source as well as local
computer where you want to insert the image in your content.</p>
<p><b>Get started Quick Toolbar to click on the image</b></p>
<p>It is possible to add custom style on the selected image inside the Rich Text Editor through quick toolbar.</p>
<img id="rteImageID" style="width:300px; height:300px;transform: rotate(0deg);" alt="Logo" src="https://ej2.syncfusion.com/demos/src/rich-text-editor/images/RTEImage-Feather.png"></ejs-richtexteditor>
</div>
</div>
</div>
</div>
</template>
<style>
.e-rte-quick-popup .e-rte-quick-toolbar .e-rotate-left::before {
content: "\e341";
}
.e-rte-quick-popup .e-rte-quick-toolbar .e-rotate-right::before {
content: "\e354";
}
</style>
<script setup>
import { provide, ref } from 'vue';
import { RichTextEditorComponent as EjsRichtexteditor, Toolbar, Image, Link, HtmlEditor, QuickToolbar, NodeSelection } from "@syncfusion/ej2-vue-richtexteditor";
const rteObj = ref(null);
const quickToolbarSettings = {
image: [
'Replace', 'Align', 'Caption', 'Remove', 'InsertLink', 'OpenImageLink', '-',
'EditImageLink', 'RemoveImageLink', 'Display', 'AltText', 'Dimension',
{
tooltipText: 'Rotate Left',
template: '<button class="e-tbar-btn e-btn" id="roatateLeft"><span class="e-btn-icon e-icons e-rotate-left"></span>'
},
{
tooltipText: 'Rotate Right',
template: '<button class="e-tbar-btn e-btn" id="roatateRight"><span class="e-btn-icon e-icons e-rotate-right"></span>'
}
]
};
const onToolbarClick = function(e) {
var nodeObj = new NodeSelection();
var range = nodeObj.getRange(rteObj.value.ej2Instances.contentModule.getDocument());
var imgEle = nodeObj.getNodeCollection(range)[0];
if (e.item.tooltipText === 'Rotate Right') {
var transform = (imgEle.style.transform === '') ? 0 :
parseInt(imgEle.style.transform.split('(')[1].split(')')[0], 10);
imgEle.style.transform = 'rotate(' + (transform + 90) + 'deg)';
}
else if (e.item.tooltipText === 'Rotate Left') {
var transform = (imgEle.style.transform === '') ? 0 :
Math.abs(parseInt(imgEle.style.transform.split('(')[1].split(')')[0], 10));
imgEle.style.transform = 'rotate(-' + (transform + 90) + 'deg)';
}
}
provide('richtexteditor', [Toolbar, Image, Link, HtmlEditor, QuickToolbar]);
</script>
<style>
@import "../../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-vue-richtexteditor/styles/material.css";
</style>
<template>
<div>
<div class="control-section">
<div class="sample-container">
<div class="default-section" id="rteSection">
<ejs-richtexteditor ref="rteObj" :quickToolbarSettings="quickToolbarSettings" :toolbarClick="onToolbarClick">
<p>Rich Text Editor allows to insert images from online source as well as local
computer where you want to insert the image in your content.</p>
<p><b>Get started Quick Toolbar to click on the image</b></p>
<p>It is possible to add custom style on the selected image inside the Rich Text Editor through quick toolbar.</p>
<img id="rteImageID" style="width:300px; height:300px;transform: rotate(0deg);" alt="Logo" src="https://ej2.syncfusion.com/demos/src/rich-text-editor/images/RTEImage-Feather.png"></ejs-richtexteditor>
</div>
</div>
</div>
</div>
</template>
<style>
.e-rte-quick-popup .e-rte-quick-toolbar .e-rotate-left::before {
content: "\e341";
}
.e-rte-quick-popup .e-rte-quick-toolbar .e-rotate-right::before {
content: "\e354";
}
</style>
<script>
import { RichTextEditorComponent, Toolbar, Image, Link, HtmlEditor, QuickToolbar, NodeSelection } from "@syncfusion/ej2-vue-richtexteditor";
export default {
name: "App",
components: {
"ejs-richtexteditor":RichTextEditorComponent
},
data: function() {
return {
quickToolbarSettings: {
image: [
'Replace', 'Align', 'Caption', 'Remove', 'InsertLink', 'OpenImageLink', '-',
'EditImageLink', 'RemoveImageLink', 'Display', 'AltText', 'Dimension',
{
tooltipText: 'Rotate Left',
template: '<button class="e-tbar-btn e-btn" id="roatateLeft"><span class="e-btn-icon e-icons e-rotate-left"></span>'
},
{
tooltipText: 'Rotate Right',
template: '<button class="e-tbar-btn e-btn" id="roatateRight"><span class="e-btn-icon e-icons e-rotate-right"></span>'
}
]
}
};
},
methods: {
onToolbarClick: function(e) {
var nodeObj = new NodeSelection();
var range = nodeObj.getRange(this.$refs.rteObj.ej2Instances.contentModule.getDocument());
var imgEle = nodeObj.getNodeCollection(range)[0];
if (e.item.tooltipText === 'Rotate Right') {
var transform = (imgEle.style.transform === '') ? 0 :
parseInt(imgEle.style.transform.split('(')[1].split(')')[0], 10);
imgEle.style.transform = 'rotate(' + (transform + 90) + 'deg)';
}
else if (e.item.tooltipText === 'Rotate Left') {
var transform = (imgEle.style.transform === '') ? 0 :
Math.abs(parseInt(imgEle.style.transform.split('(')[1].split(')')[0], 10));
imgEle.style.transform = 'rotate(-' + (transform + 90) + 'deg)';
}
}
},
provide:{
richtexteditor:[Toolbar, Image, Link, HtmlEditor, QuickToolbar]
}
}
</script>
<style>
@import "../../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../../node_modules/@syncfusion/ej2-vue-richtexteditor/styles/material.css";
</style>
Rich Text Editor features are segregated into individual feature-wise modules. To use quick toolbar, inject the quick toolbar module using the
RichTextEditor.Inject(image, link)
.