projectsearch.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * GitPHP javascript project search
  3. *
  4. * Live search of project list
  5. *
  6. * @author Christopher Han <xiphux@gmail.com>
  7. * @copyright Copyright (c) 2010 Christopher Han
  8. * @package GitPHP
  9. * @subpackage Javascript
  10. */
  11. define(["jquery", 'modules/resources', 'modules/hassearchreset'],
  12. function($, resources, hassearchreset) {
  13. var table = null;
  14. var searchPanel = null;
  15. var msgContainer = null;
  16. var currentSearch = '';
  17. var searchTimer = null;
  18. var self = null;
  19. var clearSearch = function() {
  20. searchPanel.find('img searchSpinner').show();
  21. searchPanel.find('input.projectSearchBox').val('');
  22. currentSearch = '';
  23. search('');
  24. searchPanel.find('img.searchSpinner').hide();
  25. return false;
  26. };
  27. var doSearch = function() {
  28. var newSearch = searchPanel.find('input.projectSearchBox').val().toLowerCase();
  29. if (newSearch != currentSearch) {
  30. searchPanel.find('img.searchSpinner').show();
  31. if (searchTimer != null) {
  32. clearTimeout(searchTimer);
  33. }
  34. currentSearch = newSearch;
  35. searchTimer = setTimeout(function() {
  36. self.search(newSearch);
  37. searchPanel.find('img.searchSpinner').hide();
  38. }, 500);
  39. }
  40. };
  41. function bindEvents() {
  42. searchPanel.find('form').keypress(function(e) {
  43. if (e.which == 13) {
  44. return false;
  45. }
  46. });
  47. if (table.find('tr.projectRow').size() > 0) {
  48. if (!hassearchreset()) {
  49. searchPanel.find('a.clearSearch').click(clearSearch);
  50. }
  51. searchPanel.find('input.projectSearchBox').keyup(doSearch).bind('input paste', doSearch);
  52. }
  53. }
  54. function searchRow(row, searchString) {
  55. var projectName = row.find('td.projectName span').text();
  56. if ((projectName.length > 0) && (projectName.toLowerCase().indexOf(searchString) != -1)) {
  57. return true;
  58. }
  59. var projectDesc = row.find('td.projectDescription span').text();
  60. if ((projectDesc.length > 0) && (projectDesc.toLowerCase().indexOf(searchString) != -1)) {
  61. return true;
  62. }
  63. var projectOwner = row.find('td.projectOwner em').text();
  64. if ((projectOwner.length > 0) && (projectOwner.toLowerCase().indexOf(searchString) != -1)) {
  65. return true;
  66. }
  67. return false;
  68. }
  69. function noMatchesMessage(show, searchString) {
  70. if (show) {
  71. if (!msgContainer) {
  72. msgContainer = jQuery(document.createElement('div'));
  73. msgContainer.addClass('message');
  74. msgContainer.appendTo(table);
  75. }
  76. var msg = resources.NoMatchesFound.replace(new RegExp('%1'), searchString);
  77. msgContainer.text(msg);
  78. msgContainer.show();
  79. } else {
  80. if (msgContainer) {
  81. msgContainer.hide();
  82. }
  83. }
  84. }
  85. var search = function(searchString) {
  86. clearTimeout(searchTimer);
  87. searchTimer = null;
  88. if (!hassearchreset()) {
  89. if (searchString.length == 0) {
  90. searchPanel.find('a.clearSearch').hide();
  91. } else {
  92. searchPanel.find('a.clearSearch').show();
  93. }
  94. }
  95. var hasMatch = false;
  96. var visibleCategories = [];
  97. // search each project
  98. table.find('tr.projectRow').each(function() {
  99. var jThis = $(this);
  100. if (searchString.length < 1) {
  101. jThis.show();
  102. hasMatch = true;
  103. return;
  104. }
  105. if (searchRow(jThis, searchString)) {
  106. jThis.show();
  107. hasMatch = true;
  108. var category = jThis.data('category');
  109. if (category && (jQuery.inArray(category, visibleCategories) == -1)) {
  110. visibleCategories.push(category);
  111. }
  112. } else {
  113. jThis.hide();
  114. }
  115. });
  116. // show categories that have matching projects
  117. table.find('tr.categoryRow').each(function() {
  118. var jThis = $(this);
  119. if (searchString.length < 1) {
  120. jThis.show();
  121. return;
  122. }
  123. var category = jThis.children('th.categoryName').text();
  124. if (category.length > 0) {
  125. if (jQuery.inArray(category, visibleCategories) !== -1) {
  126. jThis.show();
  127. } else {
  128. jThis.hide();
  129. }
  130. }
  131. });
  132. if (hasMatch) {
  133. noMatchesMessage(false);
  134. table.find('tr.projectHeader').show();
  135. } else {
  136. noMatchesMessage(true, searchString)
  137. table.find('tr.projectHeader').hide();
  138. }
  139. };
  140. var init = function(tableElem, searchPanelElem) {
  141. table = tableElem;
  142. searchPanel = searchPanelElem;
  143. self = this;
  144. // store project categories
  145. var category = "";
  146. table.find('tr').each(function() {
  147. var jThis = $(this);
  148. if (jThis.hasClass('categoryRow')) {
  149. category = jThis.children('th.categoryName').text();
  150. } else if (jThis.hasClass('projectRow')) {
  151. if (category.length > 0) {
  152. jThis.data('category', category);
  153. }
  154. }
  155. });
  156. bindEvents();
  157. };
  158. return {
  159. init: init,
  160. search: search
  161. }
  162. }
  163. );