jquery.coolautosuggest.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /**
  2. * jQuery Plugin for creating AJAX auto-suggest textfield
  3. * @version 2.1
  4. * @requires jQuery 1.4 or later
  5. *
  6. * Copyright (c) 2011 Lucky
  7. * Licensed under the GPL license:
  8. * http://www.gnu.org/licenses/gpl.html
  9. */
  10. (function($) {
  11. function autosuggest(callBackUrl, textField){
  12. this.divId="suggestions_holder";
  13. this.hovered=false;
  14. this.arrData=null;
  15. this.textField=textField;
  16. this.callBackUrl=callBackUrl;
  17. var width=this.textField.width() + 3;
  18. var minChars=1;
  19. var currRow=0;
  20. var suggestRow="suggest_row";
  21. var suggestItem="suggest_item";
  22. this.idField=null;
  23. this.submitOnSelect=false;
  24. this.thumbnail=false;
  25. this.description=false;
  26. this.textField.after('<div class="suggestions" id="' + this.divId + '"></div>');
  27. this.textField.attr("autocomplete", "off");
  28. this.holder=this.textField.next("#" + this.divId);
  29. this.holder.hide();
  30. this.onSelected=null;
  31. var me=this;
  32. this.textField.keyup(
  33. function(e){
  34. if(e.keyCode!=37 && e.keyCode!=38 && e.keyCode!=39 && e.keyCode!=40 && e.keyCode!=13){
  35. if($(this).val().length>=minChars){
  36. $.ajax({
  37. url:me.callBackUrl + encodeURI($(this).val()),
  38. success:function(data){
  39. try{
  40. me.arrData=$.parseJSON(data);
  41. var arr=me.arrData;
  42. var html="";
  43. currRow=0;
  44. if(arr==null){
  45. me.hide();
  46. }
  47. else{
  48. if(arr.length>0){
  49. for(i=0;i<arr.length;i++){
  50. cssClass=suggestItem;
  51. if(i==0){
  52. cssClass+=" first";
  53. }
  54. if(i==(arr.length-1)){
  55. cssClass+=" last";
  56. }
  57. var id_field='';
  58. if(me.idField!=null){
  59. id_field=' id_field="' + arr[i].id + '"';
  60. }
  61. var thumb="";
  62. if(me.thumbnail==true){
  63. var style="";
  64. if(arr[i].thumbnail!=undefined){
  65. style=' style="background-image:url(' + arr[i].thumbnail + ');"';
  66. }
  67. thumb='<div class="thumbnail"' + style + '></div>';
  68. }
  69. var desc="";
  70. if(me.description==true){
  71. if(arr[i].description!=undefined){
  72. desc='<div class="description">' + arr[i].description + '</div>';
  73. }
  74. }
  75. html+='<div id="' + suggestRow + (i+1) + '" class="' + cssClass + '"' + id_field + ' seq_id="' + i + '" >' + thumb + '<div class="suggestion_title">' + arr[i].data.replace(new RegExp('(' + me.textField.val() + ')', 'gi'), "<b>$1</b>") + '</div>' + desc + '</div>';
  76. }
  77. me.holder.html(html);
  78. for(i=1;i<=arr.length;i++){
  79. var target=me.holder.find("#" + suggestRow + i);
  80. target.mouseover(function(e){
  81. me.hovered=true;
  82. me.unSelectAll(this);
  83. $(this).addClass("selected");
  84. });
  85. target.mouseout(function(e){
  86. me.hovered=false;
  87. $(this).removeClass("selected");
  88. });
  89. target.click(function(e){
  90. me.textField.val($(this).find(".suggestion_title").text());
  91. if(me.idField!=null){
  92. me.idField.val($(this).attr("id_field"));
  93. }
  94. // Callback function
  95. if(me.onSelected!=null){
  96. me.onSelected.call(this, me.arrData[$(this).attr("seq_id")]);
  97. }
  98. if(me.submitOnSelect==true){
  99. $("form").has(me.textField).submit();
  100. }
  101. me.hide();
  102. });
  103. }
  104. me.show(me.holder.find("." + suggestItem).height() * arr.length);
  105. }
  106. else{
  107. me.hide();
  108. }
  109. }
  110. }
  111. catch(e){
  112. console.log('Sorry, an error has occured!');
  113. }
  114. },
  115. error: function(xhr, status, ex){
  116. console.log('Sorry, an error has occured!');
  117. }
  118. });
  119. }
  120. else{
  121. me.hide();
  122. }
  123. }
  124. else{
  125. if(me.holder.css("display")!="none"){
  126. checkKey(e);
  127. }
  128. else{
  129. // Callback function
  130. if(me.onSelected!=null){
  131. me.onSelected.call(this, null);
  132. }
  133. }
  134. }
  135. }
  136. );
  137. this.textField.bind(
  138. "blur",
  139. function(e){
  140. if(me.idField!=null){
  141. if(me.checkSelected(me.textField.val())==false){
  142. me.textField.val("");
  143. me.idField.val("");
  144. }
  145. }
  146. if(me.hovered==false){
  147. me.hide();
  148. }
  149. else{
  150. me.hovered=false;
  151. }
  152. }
  153. );
  154. this.show=function(height){
  155. this.holder.css({
  156. "position":"absolute",
  157. "left":this.textField.position().left + "px",
  158. "top":this.textField.position().top + this.textField.height() + 5 + "px",
  159. "z-index":1000,
  160. "height":height + "px"
  161. });
  162. this.holder.css({
  163. "width":width + "px"
  164. });
  165. this.holder.find("." + suggestItem).css({
  166. "width":width + "px",
  167. "overflow":"hidden"
  168. });
  169. this.holder.show();
  170. }
  171. this.hide=function(){
  172. this.holder.hide();
  173. }
  174. this.unSelectAll=function(div){
  175. var id=$(div).attr("id");
  176. var rows=this.holder.find("." + suggestItem).get().length;
  177. for(i=1;i<=rows;i++){
  178. this.holder.find("#" + suggestRow + i).removeClass("selected");
  179. }
  180. currRow=parseInt(id.replace(suggestRow, ""));
  181. var rgx=/^[0-9]+$/;
  182. if(!rgx.test(currRow)){
  183. currRow=0;
  184. }
  185. }
  186. this.setWidth=function(w){
  187. width=w;
  188. }
  189. this.setMinChars=function(c){
  190. minChars=c;
  191. }
  192. this.preventEnter=function(){
  193. this.textField.keypress(
  194. function(e){
  195. if(e.keyCode==13){
  196. return false;
  197. }
  198. return true;
  199. }
  200. );
  201. }
  202. this.checkSelected=function(data){
  203. if(this.arrData!=null){
  204. for(var i=0;i<this.arrData.length;i++){
  205. if(this.arrData[i].data==data){
  206. return true;
  207. }
  208. }
  209. }
  210. return false;
  211. }
  212. function checkKey(e){
  213. if(me.holder.css("display")!="none"){
  214. var rows=me.holder.find("." + suggestItem).get().length;
  215. if(e.keyCode==40){
  216. currRow++;
  217. if(currRow<=rows){
  218. if(currRow>0){
  219. me.holder.find("#" + suggestRow + (currRow-1)).removeClass("selected");
  220. }
  221. var target=me.holder.find("#" + suggestRow + currRow);
  222. target.addClass("selected");
  223. me.textField.val(target.find(".suggestion_title").text());
  224. if(me.idField!=null){
  225. me.idField.val(target.attr("id_field"));
  226. }
  227. }
  228. else{
  229. currRow=rows;
  230. }
  231. }
  232. else if(e.keyCode==38){
  233. currRow--;
  234. if(currRow>0){
  235. if(currRow<rows){
  236. me.holder.find("#" + suggestRow + (currRow+1)).removeClass("selected");
  237. }
  238. var target=me.holder.find("#" + suggestRow + currRow);
  239. target.addClass("selected");
  240. me.textField.val(target.find(".suggestion_title").text());
  241. if(me.idField!=null){
  242. me.idField.val(target.attr("id_field"));
  243. }
  244. }
  245. else{
  246. currRow=1;
  247. }
  248. }
  249. else if(e.keyCode==13){
  250. if(me.idField!=null){
  251. if(me.checkSelected(me.textField.val())==false){
  252. me.textField.val("");
  253. me.idField.val("");
  254. }
  255. }
  256. // Callback function
  257. if(me.onSelected!=null){
  258. if(currRow>0){
  259. me.onSelected.call(this, me.arrData[currRow-1]);
  260. }
  261. else{
  262. me.onSelected.call(this, null);
  263. }
  264. }
  265. me.hide();
  266. }
  267. }
  268. else{
  269. // Callback function
  270. if(me.onSelected!=null){
  271. me.onSelected.call(this, null);
  272. }
  273. }
  274. return true;
  275. }
  276. }
  277. $.fn.coolautosuggest = function(options) {
  278. var settings = {
  279. width: null,
  280. minChars: null,
  281. idField: null,
  282. submitOnSelect: false,
  283. showThumbnail : false,
  284. showDescription : false,
  285. onSelected : null
  286. };
  287. $.extend(settings, options);
  288. return this.each(function() {
  289. var obj = new autosuggest(settings.url, $(this));
  290. if(settings.width!=null){
  291. obj.setWidth(settings.width);
  292. }
  293. if(settings.minChars!=null){
  294. obj.setMinChars(settings.minChars);
  295. }
  296. if(settings.idField!=null){
  297. obj.idField=settings.idField;
  298. obj.preventEnter();
  299. }
  300. if(settings.submitOnSelect==true){
  301. obj.submitOnSelect=true;
  302. }
  303. else{
  304. obj.preventEnter();
  305. }
  306. if(settings.showThumbnail==true){
  307. obj.thumbnail=settings.showThumbnail;
  308. }
  309. if(settings.showDescription==true){
  310. obj.description=settings.showDescription;
  311. }
  312. /*if(obj.idField!=null){
  313. if(obj.checkSelected(obj.textField.val())==false){
  314. obj.textField.val("");
  315. obj.idField.val("");
  316. }
  317. }*/
  318. if($.isFunction(settings.onSelected)==true){
  319. obj.onSelected=settings.onSelected;
  320. }
  321. });
  322. }
  323. })(jQuery);