---
title: Implement a Descriptive Text Element
product: Survey Creator
description: Descriptive Text is an element that enables you to create engaging introductions, disclaimers, and add descriptive textual content anywhere within your survey. View our free demo for JavaScript to learn more.
framework: Vanilla JS
source: https://surveyjs.io/survey-creator/examples/custom-descriptive-text-element/vanillajs
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Implement a Descriptive Text Element (Vanilla JS)

A Descriptive Text survey element displays a long piece of text. You can use this element to add introductions, disclaimers, or other explanatory texts to your survey. This demo shows how to implement a custom Descriptive Text question type for Survey Creator in Angular and React applications.

A Descriptive Text question type contains the following two custom properties. All other properties are inherited from the `QuestionNonValue` class.

- `caption`: `String`\
A message displayed by the question type.

- `textSize`: `"small"` | `"medium"` | `"large"`\
The size of the text. Text sizes correspond to HTML heading levels as follows:

    | Text size  | Heading |
    | ---------- | ------- |
    | `"large"`  | `<h2>`  |
    | `"medium"` | `<h3>`  |
    | `"small"`  | `<h4>`  |

This demo uses comments in code to guide you through the implementation. If you need more detailed explanations, please refer to help topics about third-party component integration listed below. They cover the same steps because the integration process is very similar to the process of custom question type implementation.

- [Integrate Third-Party Angular Components](/form-library/documentation/customize-question-types/third-party-component-integration-angular)
- [Integrate Third-Party React Components](/form-library/documentation/customize-question-types/third-party-component-integration-react)
- [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
.descriptiveText.small {
    font-size: 0.875rem;
    font-weight: normal;
}

.descriptiveText.medium {
    font-size: 1rem;
    font-weight: bold;
}

.descriptiveText.large {
    font-size: 1.25rem;
    font-weight: bold;
}
```

### `src/survey_json.js`

```js
export const surveyJSON = {
  "title": "Customer Feedback Survey",
  "pages": [
    {
      "name": "page1",
      "elements": [
        {
          "type": "descriptivetext",
          "name": "heading",
          "textSize": "large",
          "caption": "This survey is designed to gather feedback from our users. Your responses will help us improve our products and services. Thank you for participating!"
        },
        {
          "type": "radiogroup",
          "name": "satisfaction-level",
          "title": "How satisfied are you with our products?",
          "choices": [
            "Very satisfied",
            "Satisfied",
            "Neutral",
            "Dissatisfied",
            "Very dissatisfied"
          ]
        }
      ]
    }
  ]
}
```

### `src/index.js`

```js
import { SurveyCreator } from "survey-creator-js";
import "survey-core/survey.i18n";
import "survey-creator-core/survey-creator-core.i18n";
import { ReactQuestionFactory, createElement, SurveyQuestionElementBase, SurveyElementBase } from "survey-js-ui";
import { Serializer, QuestionNonValue, ElementFactory, settings, surveyLocalization } from "survey-core";
import { getLocaleStrings } from "survey-creator-core";
import { surveyJSON } from "./survey_json";
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

window.React = { createElement: createElement };

const CUSTOM_QUESTION_TYPE = "descriptivetext";

class DescriptiveTextModel extends QuestionNonValue {
    constructor() {
        super();
        // Create a `LocalizableString` object for the `caption` property
        this.createLocString({
            name: "caption",
            supportsMarkdown: true,
            translationKey: "descriptiveTextCaption"
        });
    }
    getType() {
        return CUSTOM_QUESTION_TYPE;
    }
    get textSize() {
        return this.getPropertyValue("textSize");
    }
    set textSize(val) {
        this.setPropertyValue("textSize", val);
    }
    get caption() {
        return this.getLocalizableStringText("caption");
    }
    set caption(val) {
        this.setLocalizableStringText("caption", val);
    }
    get locCaption() {
        return this.getLocalizableString("caption");
    }
}

ElementFactory.Instance.registerElement(CUSTOM_QUESTION_TYPE, (name) => {
    return new DescriptiveTextModel(name);
});

Serializer.addClass(
    CUSTOM_QUESTION_TYPE,
    [
        {
            name: "caption:text",
            category: "general",
            visibleIndex: 2,
            serializationProperty: "locCaption",
        },
        {
            name: "textSize",
            category: "general",
            visibleIndex: 3,
            default: "medium",
            choices: [
                { value: "small", text: "Small" },
                { value: "medium", text: "Medium" },
                { value: "large", text: "Large" },
            ],
        },
    ],
    function () {
        return new DescriptiveTextModel("");
    },
    "question"
);

Serializer.getProperty(CUSTOM_QUESTION_TYPE, "hideNumber").defaultValue = true;
Serializer.getProperty(CUSTOM_QUESTION_TYPE, "titleLocation").defaultValue =
    "hidden";

class SurveyQuestionDescriptiveText extends SurveyQuestionElementBase {
    get question() {
        return this.questionBase;
    }
    renderElement() {
        const textSize = this.question.textSize || "medium";
        const locStr = SurveyElementBase.renderLocString(this.question.locCaption);
        return React.createElement(
            "span",
            {
                className: `descriptiveText ${textSize}`,
                tabIndex: 0,
                style: { overflow: "hidden", display: "block" }
            },
            locStr
        );
    }
}

ReactQuestionFactory.Instance.registerQuestion(
    CUSTOM_QUESTION_TYPE,
    (props) => {
        return React.createElement(SurveyQuestionDescriptiveText, props);
    }
);

const locale = getLocaleStrings("en");
locale.qt[CUSTOM_QUESTION_TYPE] = "Descriptive Text";
locale.pe.caption = "Caption text";
locale.pe.textSize = "Text size";

settings.customIcons["icon-descriptivetext"] = "icon-text";

// Specify the default value for the Descriptive Text caption
const enStrings = surveyLocalization.getLocaleStrings("en");
enStrings["descriptiveTextCaption"] = "Default Header Text";
const creator = new SurveyCreator();

const propertyStopList = [
    "title",
    "description",
    "isRequired",
    "readOnly",
    "requiredErrorText",
    "validators",
    "useDisplayValuesInDynamicTexts",
    "valueName",
    "clearIfInvisible",
    "defaultValue",
    "correctAnswer",
    "enableIf",
    "defaultValueExpression",
    "requiredIf",
    "descriptionLocation",
    "width",
    "minWidth",
    "maxWidth"
];
// Hide inherited properties that do not apply to the Descriptive Text element
creator.onPropertyShowing.add((_, options) => {
    if (options.element.getType() === "descriptivetext") {
        options.show = propertyStopList.indexOf(options.property.name) === -1;
    }
});
creator.JSON = surveyJSON;

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

### `package.json`

```json
{
  "dependencies": {
    "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/custom-descriptive-text-element/angular.md)
- [React](https://surveyjs.io/survey-creator/examples/custom-descriptive-text-element/reactjs.md)
- [Vue 3](https://surveyjs.io/survey-creator/examples/custom-descriptive-text-element/vue3js.md)
- [jQuery](https://surveyjs.io/survey-creator/examples/custom-descriptive-text-element/jquery.md)
