Skip to main content

DHTMLX RichText. Custom dropdown template per trigger example

Live example

A trigger's suggestion dropdown can use your own markup, and it can differ per trigger. This demo has two: typing @ opens a rich user card with an avatar, nickname, and name, while typing # shows a plain tag label. One template function decides the layout based on which trigger fired.

const { template } = richtext;

const widget = new richtext.Richtext("#richtext", {
    value,
    triggers: [
        { trigger: "@", data: people },
        { trigger: "#", data: tags },
    ],
    triggerTemplate: template(obj => { 
        if(obj.trigger === "@"){
            return `<div class="user">
                <img class="user-avatar" src="${obj.data.image}">
                <div class="user-nickname">${obj.data.label}</div>
                <div class="user-name">${obj.data.name}</div>
            </div>`;
        }
        else return obj.data.label;
    })
});
<!-- component container -->
<div id="richtext" style="width: 100%; height: 100%;"></div>

<!-- styles for custom trigger template -->

<style>
.wx-editor .wx-suggest-anchor {
        width: 230px;
    }
	.user {
		display: flex;
		align-items: center;
		gap: 6px;
        white-space: nowrap;
	}
	.user-name {
		color: #9a9a9a;
        width: 100px;
	}
	.user-avatar {
        width: 24px;
		height: 24px;
		border-radius: 50%;
		object-fit: cover;
	}
</style>

<script>
const people = [
        {
            id: "alice",
            label: "alice_nova",
            name: "Alice Johnson",
            image: "https://snippet.dhtmlx.com/codebase/data/common/img/02/avatar_05.jpg",
            url: "mailto:alice@example.com",
        },
        {
            id: "bob",
            label: "b0b_c4t",
            name: "Robert Smith",
            image: "https://snippet.dhtmlx.com/codebase/data/common/img/02/avatar_02.jpg",
            url: "mailto:bob@example.com",
        },
        {
            id: "charlie",
            label: "charlie_x",
            name: "Charles Brown",
            image: "https://snippet.dhtmlx.com/codebase/data/common/img/02/avatar_03.jpg",
            url: "mailto:charlie@example.com",
        },
        {
            id: "diana",
            label: "diana.92",
            name: "Diana Williams",
            image: "https://snippet.dhtmlx.com/codebase/data/common/img/02/avatar_09.jpg",
            url: "mailto:diana@example.com",
        },
    ];
    const tags = [
        {
            id: "css",
            label: "CSS",
            url: "https://developer.mozilla.org/en-US/docs/Web/CSS",
        },
        {
            id: "html",
            label: "HTML",
            url: "https://developer.mozilla.org/en-US/docs/Web/HTML",
        },
        {
            id: "javascript",
            label: "JavaScript",
            url: "https://developer.mozilla.org/en-US/docs/Web/JavaScript",
        },
        { id: "nodejs", label: "Node.js", url: "https://nodejs.org" },
        { id: "svelte", label: "Svelte", url: "https://svelte.dev" },
        {
            id: "typescript",
            label: "TypeScript",
            url: "https://www.typescriptlang.org",
        },
    ];
    const value = `
        <h2>Custom Trigger Template</h2>
        <p>This example demonstrates how to customize the dropdown appearance for different triggers using <code>triggerTemplate</code>.</p>
        <p>Try it yourself:</p>
        <ul>
            <li>Type <b>@</b> to mention a person. The dropdown shows an avatar, username, and full name</li>
            <li>Type <b>#</b> to add a tag. The dropdown shows a plain text label</li>
        </ul>
        <p>The <code>triggerTemplate</code> receives both the trigger character and the data item, allowing you to render each trigger's dropdown differently in a single template function.</p>
    `;
</script>

Use case

Use it when the suggestion list needs more than plain text, like a mentions box that shows avatars and full names, or a tag picker that stays simple. You define the trigger characters and their data, then one template function renders each item however you want. Because the template receives the trigger, you can give @ and # different looks in the same editor. To make it yours, set your triggers and write a triggerTemplate that returns markup per item, branching on obj.trigger.

How to do this in your app

  • Define the triggers: list each with its character and data, like { trigger: "@", data: people } and { trigger: "#", data: tags }.
  • Render items with a template: wrap your rendering function with richtext.template() and pass the result as triggerTemplate.
  • Branch per trigger: check obj.trigger inside the template to show a rich card for @ and a plain label for #.
  • Style the markup: the template's classes (like .user, .user-avatar) are styled with your own CSS.

Good to know

  • One template covers all triggers: the function runs for every suggestion, so branch on obj.trigger to vary the layout.
  • The item data is yours: fields like label, name, and image come from the objects you put in data, so the template can use any of them.
  • Return a string of markup: the template returns HTML, so you control the whole item, not just its text.

API reference

Additional resources