I need to add a functionality to my CKEditor to give suggestions to user when he types '#' in document, the suggestions can change on the fly depending on some other fields on the page. please help

- 10,578
- 12
- 62
- 104

- 61
- 1
- 2
-
1What is the current one you're using in that GIF? – Brian Chavez Dec 13 '15 at 03:10
-
1@BrianChavez it comes from this page: https://www.liferay.com/fr/web/jose.balsas/blog/-/blogs/new-feature-for-liferay-7-autocomplete-lists-in-ckeditor And the code is there: https://github.com/liferay/liferay-portal/tree/00f84a16ac1740dc7c2f5fd8efa2fa3c5b4a8b55/modules/frontend/frontend-editor/frontend-editor-ckeditor-web/src/main/resources/META-INF/resources/_diffs/plugins/autocomplete – Julien Dec 28 '15 at 11:29
-
@Demo link: https://sdk.ckeditor.com/samples/mentions.html – Ajeet Kumar Jul 11 '18 at 07:23
1 Answers
In order to make a suggestion box, you will have to make your custom plugin to use context menu as suggestion box, please check out the link for the basic knowledge of making ckeditor plugin from here a link
Add this to your config.js, where autocomplete is name of the plugin
config.extraPlugins = 'autocomplete';
Then create a following directory structure/file in the ckeditor folder
ckeditor->plugins->autocomplete->plugin.js
Put the following content in your plugin.js file
CKEDITOR.plugins.add('autocomplete',
{
init : function(editor) {
var autocompleteCommand = editor.addCommand('autocomplete', {
exec : function(editor) {
We will need to create a dummy span in the document to calculate the current position of the menu to be shown
var dummyElement = editor.document
.createElement('span');
editor.insertElement(dummyElement);
var x = 0;
var y = 0;
var obj = dummyElement.$;
while (obj.offsetParent) {
x += obj.offsetLeft;
y += obj.offsetTop;
obj = obj.offsetParent;
}
x += obj.offsetLeft;
y += obj.offsetTop;
dummyElement.remove();
After calculation the position, we remove the element and call the method to show the suggestions (placed in the context menu, which are configured in next function)
editor.contextMenu.show(editor.document
.getBody(), null, x, y);
}
});
},
Here is the listener bind on editor to check whether the current key is a # or not, CKEDITOR.SHIFT + 51 is the key combination for #
afterInit : function(editor) {
editor.on('key', function(evt) {
if (evt.data.keyCode == CKEDITOR.SHIFT + 51) {
editor.execCommand('autocomplete');
}
});
reloadSuggetionBox command will be called from your external jquery to generate the menu just after the ckeditor is ready
var firstExecution = true;
var dataElement = {};
editor.addCommand('reloadSuggetionBox', {
exec : function(editor) {
if (editor.contextMenu) {
dataElement = {};
editor.addMenuGroup('suggestionBoxGroup');
$.each(Suggestions,function(i, suggestion)
{
var suggestionBoxItem = "suggestionBoxItem"+ i;
dataElement[suggestionBoxItem] = CKEDITOR.TRISTATE_OFF;
editor.addMenuItem(suggestionBoxItem,
{
id : suggestion.id,
label : suggestion.label,
group : 'suggestionBoxGroup',
icon : null,
onClick : function() {
var data = editor.getData();
var selection = editor.getSelection();
var element = selection.getStartElement();
var ranges = selection.getRanges();
ranges[0].setStart(element.getFirst(), 0);
ranges[0].setEnd(element.getFirst(),0);
editor.insertHtml(this.id + ' ');
},
});
});
if(firstExecution == true)
{
editor.contextMenu.addListener(function(element) {
return dataElement;
});
firstExecution = false;
}
}
}
});
delete editor._.menuItems.paste;
},
});
Here "Suggestions" is the variable present somewhere on your page with holds a list of object having a 'id' and 'label' to be shown in suggestion.
Now in order to configure these suggestions, please perform the following jquery code, after this, whenever '#' is pressed, suggestions will be shown
$('textarea').ckeditor();
CKEDITOR.on( 'instanceReady', function( evt ) {
CKEDITOR.instances.contractData.execCommand('reloadSuggetionBox');
});
This will load the ckeditor(contractData is name of my ckeditor instance) and configure the plugin to show suggestions currently present int the "Suggestions" variable, anytime you need to refresh/change the suggestions you just need to call this function after reloading "Suggestions" variable
CKEDITOR.instances.contractData.execCommand('reloadSuggetionBox');
Let me know if you get any problem on getting this working.
Find the downloadable plugin at my repo at
http://navalgandhi1989.github.io/ckeditor-autocomplete-suggestions-plugin/

- 936
- 6
- 15
-
1Well it does work, I tried your code +1 for that. To be precise it triggers the custom context-menu to open when anyone types '#' (or anything else according to the Key-code used in 'Key' event listener) in it. The only shortcoming of this solution is while using long list of suggestions. Need to customize this more so as to filter out the results as he types more characters after the '#' key. It would be great to know if anyone including you did this customization already. – Suraj Jadhav Apr 10 '15 at 07:15
-
Hi Suraj, Sorry but I didn't developed the plugin further, but we can surely work together to see it possibility. – Naval Kishore Jun 25 '15 at 11:57
-
-
I am geting the follwing error , how to resolve this ? **Uncaught TypeError: Cannot read property 'execCommand' of undefined** – KTM Sep 14 '15 at 10:29
-
Hi, The sample suggestion json file is present in the github repo at https://github.com/navalgandhi1989/ckeditor-autocomplete-suggestions-plugin/blob/master/data/suggestions1.json – Naval Kishore Sep 18 '15 at 13:12
-
-
`Uncaught TypeError: $(...).ckeditor is not a function` shows this error inside the object `initCkEditor` – FerdousTheWebCoder Jan 28 '19 at 07:20