After transitioning from tinymce 4 to tinymce 5, I am struggling to create a dropdown menu button and change its text dynamically based on the current selection.
Essentially, I want something similar to the default Font or title button.
This is how I currently create a dropdown button that wraps selected text with <span lang='xx'
tag.
addLanguageBtn()
{
let lngBtn = editor.ui.registry.addMenuButton('languageBtn', {
text: 'Language',
fetch: (callback) => {
let items: any = [
{text: 'French', value: 'fr', type: 'menuitem'},
{text: 'German', value: 'de', type: 'menuitem'},
{text: 'Spanish', value: 'es', type: 'menuitem'},
];
items.forEach(item => {
item.onAction = () => {
let currentNode = editor.selection.getNode();
if (currentNode.tagName.toLocaleLowerCase() !== 'body')
{
currentNode.setAttribute('lang', item.value);
}
else
{
let textToWrap = editor.selection.getContent();
let wrappedContent = `<span lang='${item.value}'>${textToWrap}</span>`;
editor.selection.setContent(wrappedContent);
}
}
});
callback(items);
},
In the main setup
method of tinymce, my goal is to update the button text to display the selected language whenever the cursor is positioned on a word within a <span lang='xx'
tag.
setup(ed)
{
let lngButton = this.addLanguageBtn(ed);
ed.on('NodeChange', function (ev) {
if (!lngButton)//No button
{
return;
}
let lang = ev.element.getAttribute('lang');
lngButton.text = lang; // <==== This does not work, value is modified but UI is not updated
Note
For a codepen example, check out this link
Edit: Upon inspecting tinymce's source code, it appears they use Alloy components for their font family and font weight buttons. I'm aiming for a more straightforward solution.