DHTMLX RichText. Working with different formats example
Live example
RichText reads and writes its content through format encoders. This demo converts between HTML, plain text, and Markdown, with tabs for each format and buttons to load or read it. The encoders go to setValue and getValue.
let areaValue;
// html encoders
const { fromHTML, toHTML } = richtext.html;
// text encoders
const { fromText, toText } = richtext.text;
// markdown encoders
const { fromMarkdown, toMarkdown } = richtext.markdown;
const setters = { html: fromHTML, text: fromText, markdown: fromMarkdown };
const getters = { html: toHTML, text: toText, markdown: toMarkdown };
function trimOuterTags(value) {
value = value.trim();
const firstTagEnd = value.indexOf('>');
const lastTagStart = value.lastIndexOf('<');
if (firstTagEnd !== -1 && lastTagStart > firstTagEnd) {
return value.substring(firstTagEnd + 1, lastTagStart);
}
return value;
}
function fromEditor() {
const active = tabbar.getActive();
const activeCell = tabbar.getCell(active);
if (areaValue) areaValue = null;
activeCell.attachHTML(`<textarea id=${active}>${widget.getValue(getters[active])}</textarea>`);
}
function toEditor() {
const active = tabbar.getActive();
const activeCell = tabbar.getCell(active);
const value = areaValue ? areaValue : trimOuterTags(activeCell.config.html);
if (areaValue) areaValue = null;
widget.setValue(value, setters[active]);
}
const widget = new richtext.Richtext("#richtext", { value, imageUploadUrl });
const tabbar = new dhx.Tabbar("tabbar", {
mode: "top",
css: "dhx_widget--bordered modes",
views: [
{ id: "html", tab: "HTML", html: `<textarea id="html">${html}</textarea>` },
{ id: "text", tab: "Text", html: `<textarea id="text">${text}</textarea>` },
{ id: "markdown", tab: "Markdown", html: `<textarea id="markdown">${markdown}</textarea>` },
]
});
tabbar.events.on("change", () => (areaValue = null));
document.addEventListener("input", ev => {
const target = ev.target;
if (target && (target.id === "html" || target.id === "text" || target.id === "markdown")) {
areaValue = target.value;
}
});<!-- auxiliary controls for interacting with the sample -->
<link rel="stylesheet" href="https://snippet.dhtmlx.com/codebase/assets/css/auxiliary_controls.css">
<section class="dhx_sample-controls">
<button class="dhx_sample-btn dhx_sample-btn--flat" onclick="fromEditor()">From editor</button>
<button class="dhx_sample-btn dhx_sample-btn--flat" onclick="toEditor()">To editor</button>
</section>
<div id="richtext" style="width: 100%; height: calc(100% - 360px);"></div>
<div id="tabbar" style="height:300px;"></div>
<style>
.modes textarea {
display: block;
width: 100%;
height: 100%;
border: none;
resize: none;
}
</style>
<script>
const value = "<p>Select mode and try to load data <b>into the editor</b> and <b>back</b></p>";
const baseURL = "https://docs.dhtmlx.com/richtext-backend";
const imageUploadUrl = `${baseURL}/images`;
const html = `
<h2>Rich Text Format</h2>
<p>
The Rich Text Format (often abbreviated RTF) is a proprietary document file format
with published specification developed by Microsoft Corporation from 1987 until 2008
for cross-platform document interchange with Microsoft products. Prior to 2008,
Microsoft published updated specifications for RTF with major revisions of Microsoft Word
and Office versions.
</p>`;
const text = `
Plain text
In computing, plain text is a loose term for data (e.g. file contents) that represent only characters of readable material but not its graphical representation nor other objects (floating-point numbers, images, etc.). It may also include a limited number of "whitespace" characters that affect simple arrangement of text, such as spaces, line breaks, or tabulation characters (although tab characters can "mean" many different things, so are hardly "plain"). Plain text is different from formatted text, where style information is included; from structured text, where structural parts of the document such as paragraphs, sections, and the like are identified; and from binary files in which some portions must be interpreted as binary objects (encoded integers, real numbers, images, etc.).
`;
const markdown = `
# Markdown
Markdown is a lightweight markup language with plain-text-formatting syntax. Its design allows it to be converted to many output formats, but the original tool by the same name only supports HTML. Markdown is often used to format readme files, for writing messages in online discussion forums, and to create rich text using a plain text editor.
Heading
=======
Sub-heading
-----------
Alternative heading
===
Paragraphs are separated
by a blank line.
Two spaces at the end of a line
produce a line break.
Text attributes _italic_, **bold**
Bulleted list:
- item 1
- item 2
Numbered list:
1. item 1
1. item 2
Horizontal rule:
---
> Markdown uses email-style
characters for blockquoting.
Link: [some link](https://docs.dhtmlx.com/richtext-backend/images/3490994099/i.png)
Image:

`;
</script>Use case
Use it when content arrives or leaves in more than one format, like importing a Markdown file, saving plain text to a database, or exporting HTML for an email. RichText reads and writes its content through encoders, so you choose the format at the moment you load or save. The demo wires the conversion to tabs and buttons, but you can call the same methods from your own save flow or import step. To make it yours, pick the encoder for your format and pass it to getValue() when reading or setValue() when writing.
How to do this in your app
- Read the content: call
widget.getValue(encoder). With no encoder it returns HTML; passrichtext.text.toTextfor plain text. - Write the content: call
widget.setValue(value, encoder). Passrichtext.text.fromTextto load plain text, or omit the encoder to load HTML. - Grab the encoders: use
richtext.html.toHTML/richtext.html.fromHTMLfor HTML,richtext.text.toText/richtext.text.fromTextfor plain text, andrichtext.markdown.toMarkdown/richtext.markdown.fromMarkdownfor Markdown. - Map format to encoder: the demo keeps
gettersandsettersobjects that point each tab (html,text,markdown) at its encoder, then looks up the active tab and passes the result togetValue()orsetValue().
Good to know
- HTML is the default format: without an encoder,
getValue()returns HTML andsetValue()treats the provided content as HTML. - Encoders come in pairs: use a
to*encoder to read the content out, and afrom*encoder to load content in. - Conversions can be lossy: plain text removes formatting, while Markdown supports a limited syntax and drops formatting such as fonts, sizes, colors, alignment, and line height. Nested inline structures and nested lists are also limited.
- The tabs and buttons are just triggers: the surrounding UI only calls
getValue()andsetValue(). You can drive the same conversion from code with no extra UI.
API reference
- getValue method: Serializes the content, HTML by default or via an encoder
- setValue method: Loads content, HTML by default or via an encoder
- API overview: Full list of methods, properties, and events
Related examples
- Insert text at cursor: content dropped in at the caret from your own buttons
- Editor inside Gantt: the editor inside a Gantt task form
- Initialization: the base setup with content and image uploads