Permalink
Browse files

Added support for extra field in options list by adding a options lis…

…t object to start params.

- Tested using Latest Chrome on Mac 10.6
- Packed editor_plugin.js with YUI comp. keeping semicolons.
- Updated readme file also with example of usage
  • Loading branch information...
1 parent 260d809 commit 4c741a06db6609203172d0de51a96fd7dcd3608e @santeriv santeriv committed Feb 22, 2012
Showing with 63 additions and 7 deletions.
  1. +31 −2 README.md
  2. +1 −1 src/autocomplete/editor_plugin.js
  3. +31 −4 src/autocomplete/editor_plugin_src.js
View
33 README.md
@@ -13,7 +13,15 @@ Autocomplete requires TinyMCE with the jQuery package, available for download he
There are four parameters that need to be specified in your tinyMCE config:
1. autocomplete_delimiters - A CSV list of delimiters (ASCII codes) on which to split text entered into tinyMCE. In most cases you will want to split text by spaces, in which case you would specify '160,32'. 32 is a normal space and 160 is   (which is commonly used by tinyMCE). Whichever delimiter you specify first will be inserted after you select an option. The default is '160,32' for spaces.
-2. autocomplete_options - A CSV list of autocomplete options. For example, 'john,jane,william'.
+2. autocomplete_options - A CSV list OR Javascript Object "options".
+ 1. A CSV List like "john,jane,william"
+ 2. JSON-like "options" array of objects havaing a key and a description ( both visible to user key and description, key is only used for autocomplete features )
+ "options": [
+ {
+ "key": "Attila",
+ "description": "- The <i>Great</i> Hun"
+ }
+ ]
3. autocomplete_trigger - You can specify a trigger character that must be type immediately before searching for options. The default trigger is '@'
4. autocomplete_end_option - Any text that you want to be added after the option. The caret will be placed between the option and this ending text. For example, you could specify 'end', in which case selecting an autocomplete option would insert: '@jane @end' with the caret placed in between (and including the trigger before the end option).
@@ -30,7 +38,28 @@ plugins : "autolink,lists,pagebreak,style,layer,advlink,emotions,advlist,autocom
Add the configuration options for the autocomplete plugin, e.g.:
```
-autocomplete_options: "john,jane,william", // Required
+// Required
+autocomplete_options: "john,jane,william",
+
+OR (if you prefer showing description along the keys)
+
+autocomplete_options: {
+ "options": [
+ {
+ "key": "Attila",
+ "description": "- The <i>Great</i> Hun <hr /> <iframe src=\"http://farm4.staticflickr.com/3451/3233621766_e4f6db7a22_m.jpg\"></iframe>"
+ },
+ {
+ "key": "Kattila",
+ "description": "/ The Great B<b>um</b>"
+ },
+ {
+ "key": "JustKey",
+ "description": "* Just a <a href=\"http://twitter.com/enersizetech">link</a>"
+ }
+ ]
+ },
+// Optional
autocomplete_delimiters: "160,32", // Optional and this is the default
autocomplete_trigger: "@", // Optional and this is the default
autocomplete_end_option: "end", // Optional and by default no ending text is inserted
View
2 src/autocomplete/editor_plugin.js
@@ -1 +1 @@
-(function(){var d={};var c=40;var e=38;var a=27;var b=13;tinymce.create("tinymce.plugins.AutoCompletePlugin",{init:function(k,j){d={list:n(),visible:false,cancelEnter:false,delimiter:k.getParam("autocomplete_delimiters","160,32").split(","),options:k.getParam("autocomplete_options","").split(","),trigger:k.getParam("autocomplete_trigger","@"),enclosing:k.getParam("autocomplete_end_option","")};function m(x,A){if((!d.visible&&A.keyCode!=a&&A.keyCode!=b)||(A.keyCode!=c&&A.keyCode!=e&&A.keyCode!=b&&A.keyCode!=a)){var y=w(x);var z=[];if(y.length>0){var B=y.replace(d.trigger,"");z=i(B);if(z.length>0){p(z,B,x);q()}}if(y.length==0||z.length==0){v()}}}function r(x,y){if(y.keyCode==b&&d.cancelEnter){d.cancelEnter=false;return tinymce.dom.Event.cancel(y)}}function l(x,y){if(d.visible){if(y.keyCode==c){q();return tinymce.dom.Event.cancel(y)}if(y.keyCode==e){g();return tinymce.dom.Event.cancel(y)}if(y.keyCode==b){u(x,w(x));d.cancelEnter=true;return}if(y.keyCode==a){v();return tinymce.dom.Event.cancel(y)}}}function h(x,y){v()}function p(D,G,F){var z="";var A=new RegExp("("+G+")");for(var C in D){z+="<li data-value='"+D[C]+"'>"+D[C].replace(A,"<mark>$1</mark>")+"</li>"}jQuery(d.list).html(z);var x=jQuery(F.getContainer()).position();var H=jQuery(F.getContainer()).find(".mceToolbar").first();var y=jQuery(F.selection.getNode()).position();var E=0;var B=0;if(F.selection.getRng().getClientRects().length>0){E=F.selection.getRng().getClientRects()[0].top+F.selection.getRng().getClientRects()[0].height;B=F.selection.getRng().getClientRects()[0].left}else{E=parseInt(jQuery(F.selection.getNode()).css("font-size"))*1.3+y.top;B=y.left}jQuery(d.list).css("margin-top",x.top+H.innerHeight()+E);jQuery(d.list).css("margin-left",x.left+B);jQuery(d.list).css("display","block");d.visible=true;t(F)}function t(x){jQuery(d.list).find("li").hover(function(){jQuery(d.list).find("[data-selected=true]").attr("data-selected","false");jQuery(this).attr("data-selected","true")});jQuery(d.list).find("li").click(function(){u(x,w(x))})}function n(){var x=document.createElement("ul");jQuery(x).addClass("auto-list");document.body.appendChild(x);return x}function v(){jQuery(d.list).css("display","none");d.visible=false}function q(){var x=jQuery(d.list).find("[data-selected=true]");if(x.size()==0||x.next().size()==0){jQuery(d.list).find("li:first-child").attr("data-selected","true")}else{x.next().attr("data-selected","true")}x.attr("data-selected","false")}function g(){var x=jQuery(d.list).find("[data-selected=true]");if(x.size()==0||x.prev().size()==0){jQuery(d.list).find("li:last-child").attr("data-selected","true")}else{x.prev().attr("data-selected","true")}x.attr("data-selected","false")}function u(y,z){var D=jQuery(d.list).find("[data-selected=true]").attr("data-value");if(D==null){D=jQuery(d.list).find("li:first-child").attr("data-value")}var B=s(y.selection.getSel().anchorNode,"");var A=y.selection.getSel().anchorNode.textContent;var x=y.selection.getRng();x.setStart(x.startContainer,x.startOffset-z.length);y.selection.setRng(x);var E="";if(d.delimiter.length>0){E=String.fromCharCode(d.delimiter[0])}y.selection.setContent(d.trigger+D+E);if(d.enclosing.length>0&&!f(B,A)){var C=y.selection.getBookmark();y.selection.setContent(E+d.trigger+d.enclosing);y.selection.moveToBookmark(C)}v()}function f(y,x){var A=d.trigger+d.enclosing;y=y.substr(x.length);var z=new RegExp(d.trigger+".{"+d.enclosing.length+"}","g").exec(y);if(z!=null&&z.length>0&&z[0]==A){return true}return false}function s(x,y){y+=x.textContent;if(x.nextSibling!=null){return s(x.nextSibling,y)}return y}function i(z){var x=d.options;var A=[];for(var y in x){if(z.length==0||o(z,x[y])){A.push(x[y])}}return A}function o(y,x){return(x.match("^"+y)==y)}function w(y){var B=y.selection.getSel().focusNode==null?"":y.selection.getSel().focusNode.nodeValue;var z=y.selection.getSel().focusOffset;if(B==null||B.length==0){return""}var x=0;for(var A=0;A<z;A++){if(d.delimiter.indexOf(B.charCodeAt(A).toString())!=-1){x=A+1}}var C=B.substr(x,z-x);if(C.length>0&&C.charAt(0).toString()==d.trigger){return C}return""}k.onKeyUp.addToTop(m);k.onKeyDown.addToTop(l);k.onKeyPress.addToTop(r);k.onClick.add(h)},getInfo:function(){return{longname:"AutoComplete",author:"Mijura Pty Ltd",authorurl:"http://mijura.com",infourl:"http://blog.mijura.com",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autocomplete",tinymce.plugins.AutoCompletePlugin)})();
+(function(){var e={};var d=40;var f=38;var a=27;var c=13;function b(g){return g.options==null?g.split(","):g.options;}tinymce.create("tinymce.plugins.AutoCompletePlugin",{setOptions:function(g){e.options=b(g);},getOptions:function(){return e.options;},init:function(l,k){e={list:o(),visible:false,cancelEnter:false,delimiter:l.getParam("autocomplete_delimiters","160,32").split(","),options:b(l.getParam("autocomplete_options","")),trigger:l.getParam("autocomplete_trigger","@"),enclosing:l.getParam("autocomplete_end_option","")};function n(y,B){if((!e.visible&&B.keyCode!=a&&B.keyCode!=c)||(B.keyCode!=d&&B.keyCode!=f&&B.keyCode!=c&&B.keyCode!=a)){var z=x(y);var A=[];if(z.length>0){var C=z.replace(e.trigger,"");A=j(C);if(A.length>0){q(A,C,y);r();}}if(z.length==0||A.length==0){w();}}}function s(y,z){if(z.keyCode==c&&e.cancelEnter){e.cancelEnter=false;return tinymce.dom.Event.cancel(z);}}function m(y,z){if(e.visible){if(z.keyCode==d){r();return tinymce.dom.Event.cancel(z);}if(z.keyCode==f){h();return tinymce.dom.Event.cancel(z);}if(z.keyCode==c){v(y,x(y));e.cancelEnter=true;return;}if(z.keyCode==a){w();return tinymce.dom.Event.cancel(z);}}}function i(y,z){w();}function q(E,H,G){var A="";var B=new RegExp("("+H+")");for(var D in E){if(E[D].key!=null){A+="<li data-value='"+E[D].key+"'>"+E[D].key.replace(B,"<mark>$1</mark>")+" "+E[D].description+"</li>";}else{A+="<li data-value='"+E[D]+"'>"+E[D].replace(B,"<mark>$1</mark>")+"</li>";}}jQuery(e.list).html(A);var y=jQuery(G.getContainer()).position();var I=jQuery(G.getContainer()).find(".mceToolbar").first();var z=jQuery(G.selection.getNode()).position();var F=0;var C=0;if(G.selection.getRng().getClientRects().length>0){F=G.selection.getRng().getClientRects()[0].top+G.selection.getRng().getClientRects()[0].height;C=G.selection.getRng().getClientRects()[0].left;}else{F=parseInt(jQuery(G.selection.getNode()).css("font-size"))*1.3+z.top;C=z.left;}jQuery(e.list).css("margin-top",y.top+I.innerHeight()+F);jQuery(e.list).css("margin-left",y.left+C);jQuery(e.list).css("display","block");e.visible=true;u(G);}function u(y){jQuery(e.list).find("li").hover(function(){jQuery(e.list).find("[data-selected=true]").attr("data-selected","false");jQuery(this).attr("data-selected","true");});jQuery(e.list).find("li").click(function(){v(y,x(y));});}function o(){var y=document.createElement("ul");jQuery(y).addClass("auto-list");document.body.appendChild(y);return y;}function w(){jQuery(e.list).css("display","none");e.visible=false;}function r(){var y=jQuery(e.list).find("[data-selected=true]");if(y.size()==0||y.next().size()==0){jQuery(e.list).find("li:first-child").attr("data-selected","true");}else{y.next().attr("data-selected","true");}y.attr("data-selected","false");}function h(){var y=jQuery(e.list).find("[data-selected=true]");if(y.size()==0||y.prev().size()==0){jQuery(e.list).find("li:last-child").attr("data-selected","true");}else{y.prev().attr("data-selected","true");}y.attr("data-selected","false");}function v(z,A){var E=jQuery(e.list).find("[data-selected=true]").attr("data-value");if(E==null){E=jQuery(e.list).find("li:first-child").attr("data-value");}var C=t(z.selection.getSel().anchorNode,"");var B=z.selection.getSel().anchorNode.textContent;var y=z.selection.getRng();y.setStart(y.startContainer,y.startOffset-A.length);z.selection.setRng(y);var F="";if(e.delimiter.length>0){F=String.fromCharCode(e.delimiter[0]);}z.selection.setContent(e.trigger+E+F);if(e.enclosing.length>0&&!g(C,B)){var D=z.selection.getBookmark();z.selection.setContent(F+e.trigger+e.enclosing);z.selection.moveToBookmark(D);}w();}function g(z,y){var B=e.trigger+e.enclosing;z=z.substr(y.length);var A=new RegExp(e.trigger+".{"+e.enclosing.length+"}","g").exec(z);if(A!=null&&A.length>0&&A[0]==B){return true;}return false;}function t(y,z){z+=y.textContent;if(y.nextSibling!=null){return t(y.nextSibling,z);}return z;}function j(A){var y=e.options;var B=[];for(var z in y){if(y[z].key==null&&(A.length==0||p(A,y[z]))){B.push(y[z]);}else{if(y[z].key!=null&&(A.length==0||p(A,y[z].key))){B.push(y[z]);}}}return B;}function p(z,y){return(y.match("^"+z)==z);}function x(z){var C=z.selection.getSel().focusNode==null?"":z.selection.getSel().focusNode.nodeValue;var A=z.selection.getSel().focusOffset;if(C==null||C.length==0){return"";}var y=0;for(var B=0;B<A;B++){if(e.delimiter.indexOf(C.charCodeAt(B).toString())!=-1){y=B+1;}}var D=C.substr(y,A-y);if(D.length>0&&D.charAt(0).toString()==e.trigger){return D;}return"";}l.onKeyUp.addToTop(n);l.onKeyDown.addToTop(m);l.onKeyPress.addToTop(s);l.onClick.add(i);},getInfo:function(){return{longname:"AutoComplete",author:"Mijura Pty Ltd",authorurl:"http://mijura.com",infourl:"http://blog.mijura.com",version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add("autocomplete",tinymce.plugins.AutoCompletePlugin);})();
View
35 src/autocomplete/editor_plugin_src.js
@@ -40,19 +40,36 @@
var ESC_KEY = 27;
var ENTER_KEY = 13;
+ function parseOptions( param )
+ {
+ return param.options == null ? param.split(",") : param.options;
+ }
+
tinymce.create('tinymce.plugins.AutoCompletePlugin', {
+
+ setOptions : function( param )
+ {
+ autocomplete_data.options = parseOptions( param );
+ },
+
+ getOptions : function()
+ {
+ return autocomplete_data.options;
+ },
+
init : function(ed, url) {
autocomplete_data = {
list: createOptionList(),
visible: false,
cancelEnter: false,
delimiter: ed.getParam('autocomplete_delimiters', '160,32').split(","),
- options: ed.getParam('autocomplete_options', '').split(","),
+ options: parseOptions( ed.getParam('autocomplete_options', '') ),
trigger: ed.getParam('autocomplete_trigger', '@'),
enclosing: ed.getParam('autocomplete_end_option', '')
};
+
/**
* Search for autocomplete options after text is entered and display the
* option list if any matches are found.
@@ -64,6 +81,7 @@
if (currentWord.length > 0) {
var wordLessTrigger = currentWord.replace(autocomplete_data.trigger,"");
matches = matchingOptions(wordLessTrigger);
+
if (matches.length > 0) {
displayOptionList(matches, wordLessTrigger, ed);
highlightNextOption();
@@ -126,8 +144,14 @@
var matchesList = "";
var highlightRegex = new RegExp("(" + matchedText + ")");
+
for (var i in matches) {
- matchesList += "<li data-value='" + matches[i] + "'>" + matches[i].replace(highlightRegex,"<mark>$1</mark>") + "</li>";
+ if( matches[i].key != null ) {
+ matchesList += "<li data-value='" + matches[i].key + "'>" + matches[i].key.replace(highlightRegex,"<mark>$1</mark>") +" " + matches[i].description + "</li>";
+ }
+ else {
+ matchesList += "<li data-value='" + matches[i] + "'>" + matches[i].replace(highlightRegex,"<mark>$1</mark>") + "</li>";
+ }
}
jQuery(autocomplete_data.list).html(matchesList);
@@ -266,7 +290,10 @@
var options = autocomplete_data.options;
var matches = [];
for (var i in options) {
- if (currentWord.length == 0 || beginningOfWordMatches(currentWord, options[i])) {
+ if ( options[i].key == null && (currentWord.length == 0 || beginningOfWordMatches(currentWord, options[i]))) {
+ matches.push(options[i]);
+ }
+ else if( options[i].key != null && (currentWord.length == 0 || beginningOfWordMatches(currentWord, options[i].key))) {
matches.push(options[i]);
}
}
@@ -319,4 +346,4 @@
tinymce.PluginManager.add('autocomplete',
tinymce.plugins.AutoCompletePlugin);
-})();
+})();

0 comments on commit 4c741a0

Please sign in to comment.