algolia-search.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /* global instantsearch, algoliasearch, CONFIG */
  2. window.addEventListener('DOMContentLoaded', () => {
  3. const algoliaSettings = CONFIG.algolia;
  4. const { indexName, appID, apiKey } = algoliaSettings;
  5. let search = instantsearch({
  6. indexName,
  7. searchClient : algoliasearch(appID, apiKey),
  8. searchFunction: helper => {
  9. let searchInput = document.querySelector('.search-input');
  10. if (searchInput.value) {
  11. helper.search();
  12. }
  13. }
  14. });
  15. window.pjax && search.on('render', () => {
  16. window.pjax.refresh(document.getElementById('algolia-hits'));
  17. });
  18. // Registering Widgets
  19. search.addWidgets([
  20. instantsearch.widgets.configure({
  21. hitsPerPage: algoliaSettings.hits.per_page || 10
  22. }),
  23. instantsearch.widgets.searchBox({
  24. container : '.search-input-container',
  25. placeholder : algoliaSettings.labels.input_placeholder,
  26. // Hide default icons of algolia search
  27. showReset : false,
  28. showSubmit : false,
  29. showLoadingIndicator: false,
  30. cssClasses : {
  31. input: 'search-input'
  32. }
  33. }),
  34. instantsearch.widgets.stats({
  35. container: '#algolia-stats',
  36. templates: {
  37. text: data => {
  38. let stats = algoliaSettings.labels.hits_stats
  39. .replace(/\$\{hits}/, data.nbHits)
  40. .replace(/\$\{time}/, data.processingTimeMS);
  41. return `${stats}
  42. <span class="algolia-powered">
  43. <img src="${CONFIG.root}images/algolia_logo.svg" alt="Algolia">
  44. </span>
  45. <hr>`;
  46. }
  47. }
  48. }),
  49. instantsearch.widgets.hits({
  50. container: '#algolia-hits',
  51. templates: {
  52. item: data => {
  53. let link = data.permalink ? data.permalink : CONFIG.root + data.path;
  54. return `<a href="${link}" class="algolia-hit-item-link">${data._highlightResult.title.value}</a>`;
  55. },
  56. empty: data => {
  57. return `<div id="algolia-hits-empty">
  58. ${algoliaSettings.labels.hits_empty.replace(/\$\{query}/, data.query)}
  59. </div>`;
  60. }
  61. },
  62. cssClasses: {
  63. item: 'algolia-hit-item'
  64. }
  65. }),
  66. instantsearch.widgets.pagination({
  67. container: '#algolia-pagination',
  68. scrollTo : false,
  69. showFirst: false,
  70. showLast : false,
  71. templates: {
  72. first : '<i class="fa fa-angle-double-left"></i>',
  73. last : '<i class="fa fa-angle-double-right"></i>',
  74. previous: '<i class="fa fa-angle-left"></i>',
  75. next : '<i class="fa fa-angle-right"></i>'
  76. },
  77. cssClasses: {
  78. root : 'pagination',
  79. item : 'pagination-item',
  80. link : 'page-number',
  81. selectedItem: 'current',
  82. disabledItem: 'disabled-item'
  83. }
  84. })
  85. ]);
  86. search.start();
  87. // Handle and trigger popup window
  88. document.querySelectorAll('.popup-trigger').forEach(element => {
  89. element.addEventListener('click', () => {
  90. document.body.style.overflow = 'hidden';
  91. document.querySelector('.search-pop-overlay').classList.add('search-active');
  92. document.querySelector('.search-input').focus();
  93. });
  94. });
  95. // Monitor main search box
  96. const onPopupClose = () => {
  97. document.body.style.overflow = '';
  98. document.querySelector('.search-pop-overlay').classList.remove('search-active');
  99. };
  100. document.querySelector('.search-pop-overlay').addEventListener('click', event => {
  101. if (event.target === document.querySelector('.search-pop-overlay')) {
  102. onPopupClose();
  103. }
  104. });
  105. document.querySelector('.popup-btn-close').addEventListener('click', onPopupClose);
  106. window.addEventListener('pjax:success', onPopupClose);
  107. window.addEventListener('keyup', event => {
  108. if (event.key === 'Escape') {
  109. onPopupClose();
  110. }
  111. });
  112. });