Skip to main content

DHTMLX RichText. Find and highlight mentions example

Live example

Mentions inserted from a trigger can be found and stepped through one by one. This demo types @ to mention people, then walks the mentions of a chosen person, highlighting the current one and scrolling it into view. Next and previous move through them in order.

const widget = new richtext.Richtext("#richtext", {
    value,
    triggers: [{ trigger: "@", data: people }]
});

let currentUser = people[0].id;
let currentMentionElement;

function getMentionSelector(){
    return `a[data-token="@"][data-token-id="${currentUser}"]`;
}

function changeUser(user){
    clearMentionElementCss();
    currentUser = user;
}

function clearMentionElementCss() {
    if (currentMentionElement)
        currentMentionElement.classList.remove("mention-highlight");
}

function navigate(delta) {
    clearMentionElementCss();

    const all = widget.container.querySelectorAll(getMentionSelector());
    if (all.length === 0) return;

    let index = [...all].indexOf(currentMentionElement);
    if (index === -1) index = delta > 0 ? -1 : all.length;

    const newIndex = (index + delta + all.length) % all.length;
    currentMentionElement = all[newIndex];

    currentMentionElement.classList.add("mention-highlight");
    currentMentionElement.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "start" });
}
<!-- auxiliary controls for interacting with the sample -->
<link rel="stylesheet" href="https://snippet.dhtmlx.com/codebase/assets/css/auxiliary_controls.css">
<section class="dhx_sample-controls">
	<label for="user" class="dhx_sample-label">User:</label>
	<select name="user" class="dhx_select dhx_sample-input" id="user" onchange="changeUser(this.value)">
		<option value="alice" selected>alice_nova</option>
		<option value="bob">b0b_c4t</option>
		<option value="charlie">charlie_x</option>
		<option value="diana">diana.92</option>
	</select>
	<button class="dhx_sample-btn dhx_sample-btn--flat" onclick="navigate(-1)">Prev Mention</button>
	<button class="dhx_sample-btn dhx_sample-btn--flat" onclick="navigate(1)">Next Mention</button>
</section>

<!-- component container -->
<div id="richtext" style="width: 100%; height: calc(100% - 60px);"></div>

<!-- custom styles -->

<style>
.mention-highlight {
      background: #fb8500 !important;
      color: #fff !important;
	}
</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 mentionLinks = people.map(
	    person =>
	        `<a href="${person.url}" data-token="@" data-token-id="${person.id}">@${person.label}</a>`
	);
	const value = `<h2>Project Discussion</h2>
	<p>Hi team, I've been reviewing the latest requirements and I think we need some help with the following areas:</p>
	<ul>
	<li>Frontend implementation - maybe ${mentionLinks[0]} can take the lead?</li>
	<li>Backend API design - ${mentionLinks[1]} has the most experience here</li>
	<li>Database optimization - we should ask ${mentionLinks[2]} for advice</li>
	<li>Testing strategy - ${mentionLinks[3]} just finished a similar project</li>
	</ul>
	<p>Also, could someone help me understand the deployment process? ${mentionLinks[0]} and ${mentionLinks[1]} can you share your thoughts?</p>
	<p>${mentionLinks[0]} ${mentionLinks[1]} ${mentionLinks[2]} ${mentionLinks[3]} Looking forward to your feedback!</p>`;
</script>

Use case

Use it when a document is long and you want to jump between references, like reviewing every mention of one teammate or checking each place a tag appears. Each mention is a link carrying the person's id, so you can collect them all and move a cursor through the list. The demo highlights the active mention and scrolls it into view as you step. To make it yours, query the mention links for the current person and add or remove a highlight class as you navigate.

How to do this in your app

  • Insert mentions with a trigger: { trigger: "@", data: people } inserts each pick as a link that carries the person's id.
  • Collect the matches: query the editor for the current person's mention links, like a[data-token-id="<id>"].
  • Highlight the current one: add a CSS class to the active mention and remove it from the previous.
  • Scroll it into view: call scrollIntoView({ behavior: "smooth", block: "nearest" }) on the active mention.

Good to know

  • Navigation wraps around: stepping past the last mention returns to the first, so next and previous loop.
  • Each mention carries its id: that id is what your query matches to gather one person's mentions.
  • Highlighting is a class you own: the demo toggles its own class, so the look is defined in your CSS.

API reference

Additional resources