jquery.quicksearch.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. (function($, window, document, undefined) {
  2. $.fn.quicksearch = function (target, opt) {
  3. var timeout, cache, rowcache, jq_results, val = '', e = this, options = $.extend({
  4. delay: 100,
  5. selector: null,
  6. stripeRows: null,
  7. loader: null,
  8. noResults: '',
  9. matchedResultsCount: 0,
  10. bind: 'keyup',
  11. onBefore: function () {
  12. return;
  13. },
  14. onAfter: function () {
  15. return;
  16. },
  17. show: function () {
  18. this.style.display = "";
  19. },
  20. hide: function () {
  21. this.style.display = "none";
  22. },
  23. prepareQuery: function (val) {
  24. return val.toLowerCase().split(' ');
  25. },
  26. testQuery: function (query, txt, _row) {
  27. for (var i = 0; i < query.length; i += 1) {
  28. if (txt.indexOf(query[i]) === -1) {
  29. return false;
  30. }
  31. }
  32. return true;
  33. }
  34. }, opt);
  35. this.go = function () {
  36. var i = 0,
  37. numMatchedRows = 0,
  38. noresults = true,
  39. query = options.prepareQuery(val),
  40. val_empty = (val.replace(' ', '').length === 0);
  41. for (var i = 0, len = rowcache.length; i < len; i++) {
  42. if (val_empty || options.testQuery(query, cache[i], rowcache[i])) {
  43. options.show.apply(rowcache[i]);
  44. noresults = false;
  45. numMatchedRows++;
  46. } else {
  47. options.hide.apply(rowcache[i]);
  48. }
  49. }
  50. if (noresults) {
  51. this.results(false);
  52. } else {
  53. this.results(true);
  54. this.stripe();
  55. }
  56. this.matchedResultsCount = numMatchedRows;
  57. this.loader(false);
  58. options.onAfter();
  59. return this;
  60. };
  61. /*
  62. * External API so that users can perform search programatically.
  63. * */
  64. this.search = function (submittedVal) {
  65. val = submittedVal;
  66. e.trigger();
  67. };
  68. /*
  69. * External API to get the number of matched results as seen in
  70. * https://github.com/ruiz107/quicksearch/commit/f78dc440b42d95ce9caed1d087174dd4359982d6
  71. * */
  72. this.currentMatchedResults = function() {
  73. return this.matchedResultsCount;
  74. };
  75. this.stripe = function () {
  76. if (typeof options.stripeRows === "object" && options.stripeRows !== null)
  77. {
  78. var joined = options.stripeRows.join(' ');
  79. var stripeRows_length = options.stripeRows.length;
  80. jq_results.not(':hidden').each(function (i) {
  81. $(this).removeClass(joined).addClass(options.stripeRows[i % stripeRows_length]);
  82. });
  83. }
  84. return this;
  85. };
  86. this.strip_html = function (input) {
  87. var output = input.replace(new RegExp('<[^<]+\>', 'g'), "");
  88. output = $.trim(output.toLowerCase());
  89. return output;
  90. };
  91. this.results = function (bool) {
  92. if (typeof options.noResults === "string" && options.noResults !== "") {
  93. if (bool) {
  94. $(options.noResults).hide();
  95. } else {
  96. $(options.noResults).show();
  97. }
  98. }
  99. return this;
  100. };
  101. this.loader = function (bool) {
  102. if (typeof options.loader === "string" && options.loader !== "") {
  103. (bool) ? $(options.loader).show() : $(options.loader).hide();
  104. }
  105. return this;
  106. };
  107. this.cache = function () {
  108. jq_results = $(target);
  109. if (typeof options.noResults === "string" && options.noResults !== "") {
  110. jq_results = jq_results.not(options.noResults);
  111. }
  112. var t = (typeof options.selector === "string") ? jq_results.find(options.selector) : $(target).not(options.noResults);
  113. cache = t.map(function () {
  114. return e.strip_html(this.innerHTML);
  115. });
  116. rowcache = jq_results.map(function () {
  117. return this;
  118. });
  119. /*
  120. * Modified fix for sync-ing "val".
  121. * Original fix https://github.com/michaellwest/quicksearch/commit/4ace4008d079298a01f97f885ba8fa956a9703d1
  122. * */
  123. val = val || this.val() || "";
  124. return this.go();
  125. };
  126. this.trigger = function () {
  127. this.loader(true);
  128. options.onBefore();
  129. window.clearTimeout(timeout);
  130. timeout = window.setTimeout(function () {
  131. e.go();
  132. }, options.delay);
  133. return this;
  134. };
  135. this.cache();
  136. this.results(true);
  137. this.stripe();
  138. this.loader(false);
  139. return this.each(function () {
  140. /*
  141. * Changed from .bind to .on.
  142. * */
  143. $(this).on(options.bind, function () {
  144. val = $(this).val();
  145. e.trigger();
  146. });
  147. });
  148. };
  149. }(jQuery, this, document));