jquery.autocompletejson.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /**
  2. * Json key/value autocomplete for jQuery
  3. * Provides a transparent way to have key/value autocomplete
  4. * Copyright (C) 2008 Ziadin Givan www.CodeAssembly.com
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program. If not, see http://www.gnu.org/licenses/
  18. *
  19. * Examples
  20. * $("input#example").autocomplete("autocomplete.php");//using default parameters
  21. * $("input#example").autocomplete("autocomplete.php",{minChars:3,timeout:3000,validSelection:false,parameters:{'myparam':'myvalue'},before : function(input,text) {},after : function(input,text) {}});
  22. * minChars = Minimum characters the input must have for the ajax request to be made
  23. * timeOut = Number of miliseconds passed after user entered text to make the ajax request
  24. * validSelection = If set to true then will invalidate (set to empty) the value field if the text is not selected (or modified) from the list of items.
  25. * parameters = Custom parameters to be passed
  26. * after, before = a function that will be caled before/after the ajax request
  27. */
  28. jQuery.fn.autocomplete = function(url, settings )
  29. {
  30. return this.each( function()//do it for each matched element
  31. {
  32. //this is the original input
  33. var textInput = $(this);
  34. //create a new hidden input that will be used for holding the return value when posting the form, then swap names with the original input
  35. textInput.after('<input type=hidden name="' + textInput.attr("name") + '"/>').attr("name", textInput.attr("name") + "_text");
  36. var valueInput = $(this).next();
  37. //create the ul that will hold the text and values
  38. valueInput.after('<ul class="autocomplete"></ul>');
  39. var list = valueInput.next().css({top: textInput.offset().top + textInput.outerHeight(), left: textInput.offset().left, width: textInput.width()});
  40. var oldText = '';
  41. var typingTimeout;
  42. var size = 0;
  43. var selected = 0;
  44. settings = jQuery.extend(//provide default settings
  45. {
  46. minChars : 1,
  47. timeout: 1000,
  48. after : null,
  49. before : null,
  50. validSelection : true,
  51. parameters : {'inputName' : valueInput.attr('name'), 'inputId' : textInput.attr('id')}
  52. } , settings);
  53. function getData(text)
  54. {
  55. window.clearInterval(typingTimeout);
  56. if (text != oldText && (settings.minChars != null && text.length >= settings.minChars))
  57. {
  58. clear();
  59. if (settings.before == "function")
  60. {
  61. settings.before(textInput,text);
  62. }
  63. textInput.addClass('autocomplete-loading');
  64. settings.parameters.text = text;
  65. $.getJSON(url,settings.parameters,function(data)
  66. {
  67. var items = '';
  68. if (data)
  69. {
  70. size = data.length;
  71. for (i = 0; i < data.length; i++)//iterate over all options
  72. {
  73. for ( key in data[i] )//get key => value
  74. {
  75. items += '<li value="' + key + '">' + data[i][key].replace(new RegExp("(" + text + ")","i"),"<strong>$1</strong>") + '</li>';
  76. }
  77. list.html(items);
  78. //on mouse hover over elements set selected class and on click set the selected value and close list
  79. list.show().children().
  80. hover(function() { $(this).addClass("selected").siblings().removeClass("selected");}, function() { $(this).removeClass("selected") } ).
  81. click(function () { valueInput.val( $(this).attr('value') );textInput.val( $(this).text() ); clear(); });
  82. }
  83. if (settings.after == "function")
  84. {
  85. settings.after(textInput,text);
  86. }
  87. }
  88. textInput.removeClass('autocomplete-loading');
  89. });
  90. oldText = text;
  91. }
  92. }
  93. function clear()
  94. {
  95. list.hide();
  96. size = 0;
  97. selected = 0;
  98. }
  99. textInput.keydown(function(e)
  100. {
  101. window.clearInterval(typingTimeout);
  102. if(e.which == 27)//escape
  103. {
  104. clear();
  105. } else if (e.which == 46 || e.which == 8)//delete and backspace
  106. {
  107. clear();
  108. //invalidate previous selection
  109. if (settings.validSelection) valueInput.val('');
  110. }
  111. else if(e.which == 13)//enter
  112. {
  113. if ( list.css("display") == "none")//if the list is not visible then make a new request, otherwise hide the list
  114. {
  115. getData(textInput.val());
  116. } else
  117. {
  118. clear();
  119. }
  120. e.preventDefault();
  121. return false;
  122. }
  123. else if(e.which == 40 || e.which == 9 || e.which == 38)//move up, down
  124. {
  125. switch(e.which)
  126. {
  127. case 40:
  128. case 9:
  129. selected = selected >= size - 1 ? 0 : selected + 1; break;
  130. case 38:
  131. selected = selected <= 0 ? size - 1 : selected - 1; break;
  132. default: break;
  133. }
  134. //set selected item and input values
  135. textInput.val( list.children().removeClass('selected').eq(selected).addClass('selected').text() );
  136. valueInput.val( list.children().eq(selected).attr('value') );
  137. } else
  138. {
  139. //invalidate previous selection
  140. if (settings.validSelection) valueInput.val('');
  141. typingTimeout = window.setTimeout(function() { getData(textInput.val()) },settings.timeout);
  142. }
  143. });
  144. });
  145. };