search.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import _ from 'lodash'
  2. import { formatWikiHit, searchWiki } from '../algolia-search/search-wiki'
  3. import { sendMB } from '../../infrastructure/event-tracking'
  4. import { materialIcon } from '@/features/utils/material-icon'
  5. export function setupSearch(formEl) {
  6. const inputEl = formEl.querySelector('[name="subject"]')
  7. const resultsEl = formEl.querySelector('[data-ol-search-results]')
  8. const wrapperEl = formEl.querySelector('[data-ol-search-results-wrapper]')
  9. let lastValue = ''
  10. function hideResults() {
  11. wrapperEl.setAttribute('hidden', '')
  12. }
  13. function showResults() {
  14. wrapperEl.removeAttribute('hidden')
  15. }
  16. async function handleChange() {
  17. const value = inputEl.value
  18. if (value === lastValue) return
  19. lastValue = value
  20. if (value.length < 3) {
  21. hideResults()
  22. return
  23. }
  24. try {
  25. const { hits, nbHits } = await searchWiki(value, {
  26. hitsPerPage: 3,
  27. typoTolerance: 'strict',
  28. })
  29. resultsEl.innerText = ''
  30. for (const hit of hits) {
  31. const { url, pageName } = formatWikiHit(hit)
  32. const liEl = document.createElement('li')
  33. const linkEl = document.createElement('a')
  34. linkEl.className = 'contact-suggestion-list-item'
  35. linkEl.href = url
  36. linkEl.target = '_blank'
  37. liEl.append(linkEl)
  38. const contentEl = document.createElement('span')
  39. contentEl.innerHTML = pageName
  40. linkEl.append(contentEl)
  41. const iconEl = materialIcon('open_in_new')
  42. iconEl.classList.add('dropdown-item-trailing-icon')
  43. linkEl.append(iconEl)
  44. resultsEl.append(liEl)
  45. }
  46. if (nbHits > 0) {
  47. showResults()
  48. sendMB('contact-form-suggestions-shown')
  49. } else {
  50. hideResults()
  51. }
  52. } catch (e) {
  53. hideResults()
  54. }
  55. }
  56. inputEl.addEventListener('input', _.debounce(handleChange, 350))
  57. // display initial results
  58. handleChange()
  59. }