search.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*jslint browser: true */
  2. /*global jQuery: true */
  3. (function ($) {
  4. "use strict";
  5. var list = $('.search-list'),
  6. form = $('form#search-form'),
  7. showResults,
  8. doSearch,
  9. searching = false,
  10. searchQueued = false,
  11. previousQuery = form.serialize(),
  12. firstQuery = true;
  13. showResults = function (page) {
  14. var newList = $(page);
  15. list.html(newList.html());
  16. list.parent().removeClass('hidden');
  17. list.find('ul.packages li:first').addClass('selected');
  18. $('.order-by-group').attr('href', function (index, current) {
  19. return current.replace(/q=.*?&/, 'q=' + encodeURIComponent($('input[type="search"]', form).val()) + '&')
  20. });
  21. $('.js-search-field-wrapper').removeClass('col-xs-12').addClass('col-xs-8');
  22. $('#order-bys-wrapper').removeClass('hidden');
  23. searching = false;
  24. if (searchQueued) {
  25. doSearch();
  26. searchQueued = false;
  27. }
  28. };
  29. doSearch = function () {
  30. var currentQuery,
  31. q,
  32. pathname,
  33. urlPrefix,
  34. url,
  35. title;
  36. if (searching) {
  37. searchQueued = true;
  38. return;
  39. }
  40. if ($('#search_query_query').val().match(/^\s*$/) !== null) {
  41. if (!firstQuery) {
  42. list.parent().addClass('hidden');
  43. $('#order-bys-wrapper').addClass('hidden');
  44. }
  45. return;
  46. }
  47. currentQuery = form.serialize();
  48. if (previousQuery === currentQuery) {
  49. return;
  50. }
  51. $('.order-by-group .active').removeClass('active');
  52. if (window.history.pushState) {
  53. q = encodeURIComponent($('input[type="search"]', form).val());
  54. pathname = window.location.pathname;
  55. if (pathname.indexOf('/app_dev.php') === 0) {
  56. urlPrefix = '/app_dev.php';
  57. } else if (pathname.indexOf('/app.php') === 0) {
  58. urlPrefix = '/app.php';
  59. } else {
  60. urlPrefix = '';
  61. }
  62. url = urlPrefix + '/search/?q=' + q;
  63. title = 'Search';
  64. if (firstQuery) {
  65. window.history.pushState(null, title, url);
  66. firstQuery = false;
  67. } else {
  68. window.history.replaceState(null, title, url);
  69. }
  70. }
  71. $.ajax({
  72. url: form.attr('action'),
  73. data: currentQuery,
  74. success: showResults
  75. });
  76. searching = true;
  77. previousQuery = currentQuery;
  78. };
  79. form.bind('keyup search', doSearch);
  80. form.bind('keydown', function (event) {
  81. var keymap,
  82. currentSelected,
  83. nextSelected;
  84. keymap = {
  85. enter: 13,
  86. left: 37,
  87. up: 38,
  88. right: 39,
  89. down: 40
  90. };
  91. if (keymap.up !== event.which && keymap.down !== event.which && keymap.enter !== event.which) {
  92. return;
  93. }
  94. if ($('#search_query_query').val().match(/^\s*$/) !== null) {
  95. document.activeElement.blur();
  96. return;
  97. }
  98. event.preventDefault();
  99. currentSelected = list.find('ul.packages li.selected');
  100. nextSelected = (keymap.down === event.which) ? currentSelected.next('li') : currentSelected.prev('li');
  101. if (currentSelected.length === 0 && keymap.down === event.which) {
  102. currentSelected = list.find('ul.packages li:first').addClass('selected');
  103. }
  104. if (keymap.enter === event.which && currentSelected.data('url')) {
  105. window.location = currentSelected.data('url');
  106. return;
  107. }
  108. if (nextSelected.length > 0) {
  109. currentSelected.removeClass('selected');
  110. nextSelected.addClass('selected');
  111. var elTop = nextSelected.position().top,
  112. elHeight = nextSelected.height(),
  113. windowTop = $(window).scrollTop(),
  114. windowHeight = $(window).height();
  115. if (elTop < windowTop) {
  116. $(window).scrollTop(elTop);
  117. } else if (elTop + elHeight > windowTop + windowHeight) {
  118. $(window).scrollTop(elTop + elHeight + 20 - windowHeight);
  119. }
  120. }
  121. });
  122. // handle pressing S to focus the search
  123. $(document.body).bind('keyup', function (event) {
  124. if (event.which === 83 && (!document.activeElement || -1 === ['INPUT','SELECT','TEXTAREA'].indexOf(document.activeElement.tagName))) {
  125. $('#search_query_query').focus();
  126. }
  127. });
  128. if ($(document).width() >= 992) {
  129. $('#search_query_query').focus();
  130. }
  131. }(jQuery));