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 astriggerTemplate. - Branch per trigger: check
obj.triggerinside 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.triggerto vary the layout. - The item data is yours: fields like
label,name, andimagecome from the objects you put indata, 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
- triggerTemplate config: Custom suggestion rendering for each trigger
- triggers config: Trigger data and suggestion item fields
- API overview: Full list of methods, properties, and events
Related examples
- Mentions and tags: triggers fed from an array, a function, or an API
- Emoji autocomplete: an emoji list filtered as you type
- Slash commands: a command menu opened by typing a slash