Was doing some proof of concept with RTE plugin like CKEditor or TinyMCE, and ended up with an interest to incorporate a text hints or intellisense for the editor.
At first I was trying to use the jQuery Autocomplete, but it tie to a input box, and RTE does not use input box, they use contenteditable DOM element like <body> inside an iframe. And I came across the amazing code editor CodeMirror that came with the amazing autocomplete feature that I was looking for, it pops up nicely where it meant to be, and performance was terrific, but I don’t want dependencies from any of CodeMirror’s code base, and reverse engineering isn’t my strength.
So I decided to write one just for the sake to know how it could be done. Usually I would start writing the code in a simple JavaScript class, but this time I thought I could write a jQuery plugin for that, since I’m going to use jQuery anyway.
The jQuery plugin can be start with this structure:
( function ( $ ) {
$.editablehints = function ( options ) {
};
})( jQuery );
Simple codes define the plugin name, and configuration options that can be send in. With options sent in, we then can do this to set our default value if config option is not set, or use the config if it exists.
//default settings
var settings = $.extend({
'editor': null,
'hints': [],
'className': 'editablehints',
'trigger': '@',
'hintsBoxOffsetX': 0,
'hintsBoxOffsetY': 0
}, options);
Then to define some function inside the plugin,
//remove suggestion
this.stopHints = function() {
hintsBox.empty();
hintsBox.hide();
isHinting = false;
triggerPos = -1;
};
Most important part for this plugin is listen to keystroke and search for suggested text,
// bind the event
editor.keyup( function( e ) {
var keycode = e.keyCode || e.which;
if ( keycode !== 38 && keycode !== 40 && keycode !== 13 && keycode !== 27 && keycode !== 39 && keycode !== 37 ) {
setTimeout( me.doSearch, 1 );
}
});
I need to set timeout inorder to get the very lastest keystroke captured, or I guess I should just need to bind to keydown or keypress event, lots of refactoring needed for this first draft.
The flow of the plugin is to listen for key stroke, if the trigger character is detected, it will then search for the array of text we predefined, filter it and show on a absolute position popup, at the cursor position.
The challenges lies at capturing the position correct position of the caret, the challenge even tougher when I initially aim to allow the plugin to incorporate with iframe’s RTE plugin, but that is just too much of works at the moment, zooming browser, scrolling the content, all of this causing problem.
The plugin can be found at jQuery Plugin and GitHub, this is a very rough version, it does not work properly on IE, and it have bugs here and there, not to mention noticeable performance issue when the popup is filtering.