---
title: Integrate a Third-Party Rich Content Editor
product: Survey Creator
description: Learn how to transform text entry fields within the Property Grid into powerful rich text editors for easy and precise text formatting. View this free demo to explore the capabilities of a WYSIWYG visual editor and access a code example for JavaScript to discover how to seamlessly integrate Quill into your SurveyJS form-building tool.
framework: jQuery
source: https://surveyjs.io/survey-creator/examples/form-builder-with-integrated-rich-text-editor/jquery
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Integrate a Third-Party Rich Content Editor (jQuery)

In addition to multiple configuration options available by default, SurveyJS Creator supports various customizations. For instance, you can replace text entry fields within the Property Grid (the input fields you use to enter a title or form description) with dedicated rich text editors. A rich text editor is a WYSIWYG visual editor that provides an input area for editing your form's content and a toolbar equipped with all the necessary formatting tools. Survey creators can apply bold, italic, or underline font style to text, add bullet points or numbered lists, insert hyperlinks, adjust text alignment, and more. This demo illustrates how to integrate a third-party <a href="https://quilljs.com/" target="_blank">Quill</a> text editor into Survey Creator.

For a step-by step Quill integration tutorial, refer to the following documentation articles. Although they describe integration of a color picker, the same instructions apply to any other third-party component, including Quill. 

- [Integrate Third-Party React Components](https://surveyjs.io/form-library/documentation/customize-question-types/third-party-component-integration-react)
- [Integrate Third-Party Angular Components](https://surveyjs.io/form-library/documentation/customize-question-types/third-party-component-integration-angular)
- [Integrate Third-Party Vue 3 Components](/form-library/documentation/customize-question-types/third-party-component-integration-vue)

## Files

### `public/index.html`

```html
<!-- Uncomment the following lines to enable Ace Editor in the JSON Editor tab -->
<!-- 
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ace.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ext-searchbox.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/theme-clouds_midnight.js"></script>
-->

<div id="surveyCreatorContainer" style="position: absolute; height: 100%; width: 100%"></div>
```

### `src/index.css`

```css
.ql-toolbar.ql-snow {
    white-space: normal;
}
.sv-string-editor--html {
    white-space: normal !important;
}
.quill .ql-container {
    max-height: calc(100% - 42px);
}
```

### `src/quill.js`

```js
import { CustomWidgetCollection, Serializer, ElementFactory } from "survey-core";
import { PropertyGridEditorCollection } from "survey-creator-core";
import Quill from "quill";
import "quill/dist/quill.snow.css";

const componentName = "quill";

function initQuill() {
    const iconId = "icon-editor";
    var widget = {
        name: componentName,
        title: "Quill",
        iconName: iconId,
        widgetIsLoaded: function () {
            return Quill !== undefined;
        },
        isFit: function (question) {
            return question.getType() === componentName;
        },
        activatedByChanged: function (activatedBy) {
            Serializer.addClass(componentName, [], null, "empty");
            let registerQuestion = ElementFactory.Instance.registerCustomQuestion;
            if (!!registerQuestion) registerQuestion(componentName);
            Serializer.addProperty(componentName, {
                name: "height",
                default: "200px",
                category: "layout"
            });
        },
        htmlTemplate: "<div></div>",
        afterRender: function (question, el) {
            el.style.height = question.height;
            var editor = new Quill(el, {
                theme: "snow"
            });
            editor.enable(!question.isReadOnly);
            var isValueChanging = false;
            editor.on("text-change", function (eventName, ...args) {
                isValueChanging = true;
                question.value = editor.root.innerHTML;
                isValueChanging = false;
            });
            var updateValueHandler = function () {
                if (isValueChanging) return;
                const text = question.value || "";
                editor.root.innerHTML = text;
            };
            question.valueChangedCallback = updateValueHandler;
            question.readOnlyChangedCallback = function () {
                editor.enable(!question.isReadOnly);
            };
            updateValueHandler();
        },
        willUnmount: function (question, el) {
            el.previousSibling && el.previousSibling.remove();
            el.innerHTML = "";
        }
    };

    CustomWidgetCollection.Instance.addCustomWidget(widget, "customtype");
}

if (!Serializer.findClass(componentName)) {
    initQuill();
}

// Register `quill` as an editor for properties of the `text` and `html` types in the Survey Creator's Property Grid
PropertyGridEditorCollection.register({
    fit: function (prop) {
        return prop.type == "text" || prop.type == "html";
    },
    getJSON: function () {
        return { type: "quill" };
    }
});
```

### `src/index.js`

```js
import { SurveyCreator } from "survey-creator-js";
import "survey-core/survey.i18n";
import "survey-creator-core/survey-creator-core.i18n";
export * from "./quill";
import { getLocaleStrings } from "survey-creator-core";
import "survey-core/survey-core.css";
import "survey-creator-core/survey-creator-core.css";
import "./index.css";

import SurveyTheme from "survey-core/themes";
import { registerCreatorTheme } from "survey-creator-core";

registerCreatorTheme(SurveyTheme); // Add predefined Survey Creator UI themes

function applyHtml(_, options) {
    let str = options.text;
    if (str.indexOf("<p>") === 0) {
        // Remove root paragraphs <p></p>
        str = str.substring(3);
        str = str.substring(0, str.length - 4);
    }
    // Set HTML markup to render
    options.html = str;
}

// Specify a title for the toolbox category that will contain the Quill question type  
const translations = getLocaleStrings("en");
translations.toolboxCategories["custom"] = "Custom Questions";
const creator = new SurveyCreator();
// Move the Quill question type to the first position in the Toolbox
const toolboxItems = creator.toolbox.items;
const quillIndex = toolboxItems.findIndex((item) => item.name === "quill");
const quillItem = toolboxItems.splice(quillIndex, 1)[0];
quillItem.title = "Rich Text Editor";
quillItem.iconName = "icon-comment";
toolboxItems.unshift(quillItem);
creator.toolbox.changeCategory("quill", "custom");

// Apply HTML markup to survey contents
creator.survey.onTextMarkdown.add(applyHtml);
creator.onSurveyInstanceSetupHandlers.add((_, options) => {    
    options.survey.onTextMarkdown.add(applyHtml);    
});

creator.JSON = {
    "title": "Quill Integration with SurveyJS",
    "description": "<ul><li><strong>Bold</strong></li><li><em>Italics</em></li><li><s>Strikethrough</s></li></ul>",
    "pages": [{
        "name": "page1",
        "elements": [{
            "type": "quill",
            "name": "rich-text-editor",
            "title": "Rich Text Editor",
            "defaultValue": "Hello world!"
        }]
    }]
}

creator.render("surveyCreatorContainer");
```

### `package.json`

```json
{
  "dependencies": {
    "jquery": "latest",
    "quill": "^1.3.7",
    
    "survey-core": "latest",
    "survey-js-ui": "latest",
    "survey-creator-core": "latest",
    "survey-creator-js": "latest"
  },
  "devDependencies": {
    "react-scripts": "latest"
  }
}
```

## Other Frameworks

- [Angular](https://surveyjs.io/survey-creator/examples/form-builder-with-integrated-rich-text-editor/angular.md)
- [React](https://surveyjs.io/survey-creator/examples/form-builder-with-integrated-rich-text-editor/reactjs.md)
- [Vue 3](https://surveyjs.io/survey-creator/examples/form-builder-with-integrated-rich-text-editor/vue3js.md)
