Reputation: 1208
I've added an autocompleter to tinyMCE that creates a span with specific classes and attributs. We use that to create link to other elements in our tool. Those are not "a" tag since it is not a direct url, it is handled internaly. This works fine. The only issue I have is when we edit those value and the span is the last entry in the editor, when user starts to type in, the text continues in that same span instead of starting a new one.
How can I prevent that? I tried to add a space at the end when setting content but it had no effect (the space seems to be removed). This little trick does work when I insert the span though to help user writing in "normal" format.
So for example the content of tinyMCE would be set to something like that "I'm afraid of <span class='animal' data-animalId='animal2'>crocodile</span>"
When adding text, the span 'animal' gets the content. I'd prefer it to be outside of that (but still on the same line)
I'd be happy if the span is never append to also.
You can view a working example on this CodePen https://codepen.io/MissChocoe/pen/OJbaWXd
Here's the full JS code:
var autoCompletionValues = [
{id: "animal1", name: "alligator"},
{id: "animal2", name: "crocodile"},
{id: "animal3", name: "cat"},
{id: "animal4", name: "dog"},
{id: "animal5", name: "horse"},
{id: "animal6", name: "cow"}
];
var initialValue = "I'm afraid of <span class='animal' data-animalId='animal2'>crocodile</span>";
tinymce.init({
selector: "#myTinyMCE",
forced_root_block: false,
content_style: ".animal { color: blue; text-decoration: underline}",
setup: function (editor) {
editor.ui.registry.addAutocompleter('myAutoComplete', {
ch: "_",
minChars: 1,
onAction: function (autocompleteApi, rng, value, meta) {
editor.selection.setRng(rng);
editor.insertContent('<span class="animal" data-animalId="' + meta.id + '">' + value + '</span>' + " ");
autocompleteApi.hide();
},
fetch: function (pattern) {
return new tinymce.util.Promise(function (resolve) {
var results = autoCompletionValues.filter(function(c) {
return c.name.indexOf(pattern.toLowerCase()) === 0;
}).map(function(c) {
return {
type: 'autocompleteitem',
value: c.name,
text: c.name,
meta: c
};
});
resolve(results);
});
}
});
editor.on('init', function(ev) {
editor.setContent(initialValue);
});
},
});
Upvotes: 0
Views: 835
Reputation: 798
For tinyMCE 6, there is an option to allow navigating inline tags with arrow keys:
tinymce.init({
selector: 'textarea',
inline_boundaries_selector: 'a[href],code,b,i,strong,em'
});
Just add "span" to the inline_boundaries_selector option above.
https://www.tiny.cloud/docs/tinymce/6/content-behavior-options/#inline_boundaries_selector
Other workaround is to set contenteditable="false" to the span (tested in tinyMCE 6). To edit the text, just reuse the dialog used to create it.
"I'm afraid of <span class='animal' data-animalId='animal2' contenteditable='false'>crocodile</span>"
Upvotes: 2
Reputation: 1208
This might not be the best solution, but using
editor.setContent(initialValue + " ", {format: 'raw'});
Did the trick. The space was removed by tinyMCE clean up methods, this prevents running those.
If user deletes that space, he'll still get 'stuck' in the span so I'd still like to find a way to make this span 'final' but for now it will do the trick.
Upvotes: 2