Bootstrap 5 Rich Text Editor
Bootstrap 5 rich text editor in AdminKit PRO: Quill 2 with the snow and bubble themes, a toolbar you write in HTML, and styles for light and dark mode.
This plugin is only available in AdminKit PRO. Learn more.
Use a rich text editor when a plain textarea is not enough: for a reply, an article or a product description with bold text, lists and links. People format the text with a toolbar, the way they would in a word processor.
AdminKit PRO comes with Quill 2 and both of its themes. Snow puts a toolbar above the editor. Bubble shows the toolbar in a tooltip when you select text. The template styles both for light and dark mode.
Snow theme
You write the toolbar yourself, as HTML. It holds ql-formats groups of buttons and selects, and the ql-* class of each control names the format it applies. Quill fills in the icons and the options of the selects.
<div id="quill-toolbar">
<span class="ql-formats">
<button type="button" class="ql-bold" aria-label="Bold"></button>
<button type="button" class="ql-italic" aria-label="Italic"></button>
<button type="button" class="ql-underline" aria-label="Underline"></button>
<button type="button" class="ql-strike" aria-label="Strikethrough"></button>
</span>
<span class="ql-formats">
<select class="ql-color"></select>
<select class="ql-background"></select>
</span>
<span class="ql-formats">
<button type="button" class="ql-header" value="1" aria-label="Heading 1"></button>
<button type="button" class="ql-header" value="2" aria-label="Heading 2"></button>
<button type="button" class="ql-blockquote" aria-label="Quote"></button>
</span>
<span class="ql-formats">
<button type="button" class="ql-list" value="ordered" aria-label="Numbered list"></button>
<button type="button" class="ql-list" value="bullet" aria-label="Bulleted list"></button>
</span>
<span class="ql-formats">
<button type="button" class="ql-link" aria-label="Link"></button>
<button type="button" class="ql-clean" aria-label="Clear formatting"></button>
</span>
</div>
<div id="quill-editor"></div>
<script>
document.addEventListener("DOMContentLoaded", function() {
var editor = new Quill("#quill-editor", {
modules: {
toolbar: "#quill-toolbar"
},
placeholder: "Type something",
theme: "snow"
});
// Quill builds its dropdowns from the toolbar selects without a name; name them
var pickerNames = { color: "Text color", background: "Highlight color" };
document.querySelectorAll(".ql-picker").forEach(function(picker) {
var format = Object.keys(pickerNames).find(function(name) {
return picker.classList.contains("ql-" + name);
});
picker.querySelector(".ql-picker-label").setAttribute("aria-label", pickerNames[format]);
});
});
</script>The editors demo has a larger toolbar, with a font and size select, subscript and superscript, a code block, indents, text direction, alignment, images and video.
Bubble theme
For a lighter look, such as editing text in place, use the bubble theme. It has no toolbar above the editor. Instead, the toolbar appears in a tooltip when you select text. Select a word below to try it.
<div id="quill-bubble-toolbar">
<span class="ql-formats">
<button type="button" class="ql-bold" aria-label="Bold"></button>
<button type="button" class="ql-italic" aria-label="Italic"></button>
<button type="button" class="ql-underline" aria-label="Underline"></button>
</span>
<span class="ql-formats">
<button type="button" class="ql-header" value="1" aria-label="Heading 1"></button>
<button type="button" class="ql-header" value="2" aria-label="Heading 2"></button>
</span>
<span class="ql-formats">
<button type="button" class="ql-link" aria-label="Link"></button>
<button type="button" class="ql-clean" aria-label="Clear formatting"></button>
</span>
</div>
<div id="quill-bubble-editor"><p>Select this text to format it.</p></div>
<script>
document.addEventListener("DOMContentLoaded", function() {
var bubbleEditor = new Quill("#quill-bubble-editor", {
placeholder: "Compose an epic...",
modules: {
toolbar: "#quill-bubble-toolbar"
},
theme: "bubble"
});
});
</script>The editor starts with the HTML inside its element. Leave the element empty to show the placeholder instead.
Use it in your page
js/app.js includes Quill and makes it available as window.Quill. The styles of both themes are part of css/app.css. So a page needs no script of its own besides app.js.
app.js is a module script, and the browser runs module scripts once the page has been parsed. Wrap your code in a DOMContentLoaded listener, so it runs after app.js. The editors demo does the same:
<div id="quill-toolbar">...</div>
<div id="quill-editor"></div>
<script type="module" src="js/app.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
var editor = new Quill("#quill-editor", {
modules: {
toolbar: "#quill-toolbar"
},
placeholder: "Type something",
theme: "snow"
});
});
</script>Options
These are the options the editors demo uses. See Quill's configuration for the full list.
| Option | What it does |
|---|---|
theme | "snow" for a toolbar above the editor, "bubble" for a toolbar in a tooltip |
modules.toolbar | A selector for your toolbar markup, such as "#quill-toolbar" |
placeholder | Text shown while the editor is empty |
These are the toolbar controls of the demo, with the class that makes each one:
| Control | Markup |
|---|---|
| Bold, italic, underline, strikethrough | <button class="ql-bold">, ql-italic, ql-underline, ql-strike |
| Font and size | <select class="ql-font">, <select class="ql-size"> |
| Text and highlight color | <select class="ql-color">, <select class="ql-background"> |
| Subscript and superscript | <button class="ql-script" value="sub">, value="super" |
| Headings | <button class="ql-header" value="1">, value="2" |
| Quote and code block | <button class="ql-blockquote">, ql-code-block |
| Lists | <button class="ql-list" value="ordered">, value="bullet" |
| Indent | <button class="ql-indent" value="-1">, value="+1" |
| Text direction and alignment | <button class="ql-direction" value="rtl">, <select class="ql-align"> |
| Link, image and video | <button class="ql-link">, ql-image, ql-video |
| Clear formatting | <button class="ql-clean"> |
Leave the <select> elements empty. Quill adds the options and turns each select into a dropdown of its own, called a picker.
In a form
The editor is not a form field, so its content is not sent with the form by itself. Copy it into a hidden input when the form is submitted. getSemanticHTML() returns the content as HTML:
<form id="article-form">
<div id="quill-toolbar">...</div>
<div id="quill-editor"></div>
<input type="hidden" name="body" id="article-body">
<button type="submit" class="btn btn-primary mt-3">Save</button>
</form>
<script>
document.addEventListener("DOMContentLoaded", function() {
var editor = new Quill("#quill-editor", {
modules: {
toolbar: "#quill-toolbar"
},
theme: "snow"
});
document.getElementById("article-form").addEventListener("submit", function() {
document.getElementById("article-body").value = editor.getSemanticHTML();
});
});
</script>Sanitize the HTML on the server before you show it to other people.
Styling
AdminKit restyles both themes in src/scss/5-vendor/_quill.scss. The toolbar and editor use the font of the template. With the snow theme, active and hovered toolbar buttons get the primary color. The editor area is at least 15rem high and has the background of a card. With the bubble theme, the editor has no padding. The other colors come from the gray scale of the template, so both themes follow the color mode.
Accessibility
-
Quill's toolbar buttons have no text. Give each one an
aria-label, as in the examples. -
Quill builds its pickers from the
<select>s without a name. The editors demo names them after Quill has started:// Quill builds its dropdowns from the toolbar selects without a name; name them var pickerNames = { font: "Font", size: "Size", color: "Text color", background: "Highlight color", align: "Alignment" }; document.querySelectorAll(".ql-picker").forEach(function(picker) { var format = Object.keys(pickerNames).find(function(name) { return picker.classList.contains("ql-" + name); }); picker.querySelector(".ql-picker-label").setAttribute("aria-label", pickerNames[format]); });Add a name to
pickerNamesfor every other select you use. -
The editor area is an editable element that Quill manages. Put a visible label or heading next to it, since the placeholder disappears once someone types.
Related
- React Quill Editor: the same editor in AdminKit for React
- Next.js Quill Editor: the same editor in AdminKit for Next.js
- Form control: Bootstrap's text inputs and textareas
- Validation: validating the rest of the form
- Editors demo
Last updated on
CalendarPro
Bootstrap 5 FullCalendar in AdminKit PRO: FullCalendar 7 with month, week and day views, drag and drop events and color-coded event categories.
Vector map
Bootstrap 5 vector map with jsVectorMap in AdminKit: a world map with markers in theme colors that follows dark mode, plus a US map in AdminKit PRO.