PageSourceSearch

https://www.hoover.org/themes/hoover/templates/assets/scripts/algolia-research_type.js?v=1790215045

js hoover.org collected 2026-09-24 06:23:57 UTC 18,865 bytes, 552 lines download raw bytes

1var filterSection = document.querySelector(".filters-block")
2var hitsWrap = filterSection.querySelector("#hits")
3var functionExecuted = false
4var loading = '<div class="tenor-gif-embed" style="text-align: center; margin:auto;"><svg version="1.1" id="L9" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"  style="width: 80px;" viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve">'+
5' <path fill="#98002e" d="M73,50c0-12.7-10.3-23-23-23S27,37.3,27,50 M30.9,50c0-10.5,8.5-19.1,19.1-19.1S69.1,39.5,69.1,50">'+
6 '<animateTransform  attributeName="transform" attributeType="XML" type="rotate" dur="1s" from="0 50 50" to="360 50 50" repeatCount="indefinite" />'+
7'</path>'+
8'</svg></div>'
9
10hitsWrap.innerHTML =loading
11
12/*
13    scroll to the section if query params are present
14    */
15
16    function isElementInViewport(el) {
17      const rect = el.getBoundingClientRect();
18 
19      return (
20          rect.top >= 300 ? true : false
21      );
22    }
23    window.addEventListener("DOMContentLoaded", function () {
24      function scrollToSection() {
25        const url = window.location.search;
26   
27        if (url) {
28               if (filterSection) {
29                setTimeout(()=>{
30                  if (isElementInViewport(filterSection)) {
31                    var topDistance = filterSection.getBoundingClientRect().top - 150
32                    const scrollY = window.scrollY;
33                    topDistance = scrollY + topDistance
34                    window.scrollTo({
35                      top: topDistance,
36                      behavior: 'smooth'
37                    });
38                  };
39                },2000)
40               }
41               fetchAlgolia()
42         }else{
43          window.addEventListener("scroll", function () {
44            const top = filterSection.getBoundingClientRect().top;
45            const wHeight = window.innerHeight - 400
46            if (top < wHeight && !functionExecuted) {
47              functionExecuted = true;
48                fetchAlgolia()
49            } else if (top >= wHeight) {
50              functionExecuted = false;
51            }
52            
53          })
54         }
55       }scrollToSection()
56    });
57function fetchAlgolia() {
58
59  /*
60  Declare Algolia key
61  */
62  const searchClient = algoliasearch(
63    '9TYF7RJUHQ',
64    '8f9bc807e8439d755c4fa23f113f99e7'
65  );
66
67  /*
68  Define Algolia index
69  */
70  const search = instantsearch({
71    indexName: 'research_descending',
72    searchClient,
73    routing: searchRouting
74  });
75
76  
77  /*
78  After render
79  */
80  const customafterResultFunction = () => {
81    var topicTextContainer = document.getElementById("selected-topic");
82    var topicFiltersSelected = document.querySelector("#topic .ais-RefinementList-item--selected");
83    var topicFiltersSelectedLength = document.querySelectorAll("#topic .ais-RefinementList-item--selected");
84    
85    var typeTextContainer = document.getElementById("selected-type");
86    var typeFiltersSelected = document.querySelector("#content-type .ais-RefinementList-item--selected");
87    var typeFiltersSelectedLength = document.querySelectorAll("#content-type .ais-RefinementList-item--selected");
88    
89    var focusAreaTextContainer = document.getElementById("selected-focus-area");
90    var focusAreaFiltersSelected = document.querySelector("#keyFocus .ais-RefinementList-item--selected");
91    var focusAreaFiltersSelectedLength = document.querySelectorAll("#keyFocus .ais-RefinementList-item--selected");
92  
93    var publicationTextContainer = document.getElementById("selected-publication");
94    var publicationFiltersSelected = document.querySelector("#publication .ais-RefinementList-item--selected");
95    var publicationFiltersSelectedLength = document.querySelectorAll("#publication .ais-RefinementList-item--selected");
96  
97    var regionTextContainer = document.getElementById("selected-region");
98    var regionFiltersSelected = document.querySelector("#region .ais-RefinementList-item--selected");
99    var regionFiltersSelectedLength = document.querySelectorAll("#region .ais-RefinementList-item--selected");
100    
101    var teamTextContainer = document.getElementById("selected-team");
102    var teamFiltersSelected = document.querySelector("#team .ais-RefinementList-item--selected");
103    var teamFiltersSelectedLength = document.querySelectorAll("#team .ais-RefinementList-item--selected");
104    selectedFilterNumber(topicTextContainer, topicFiltersSelected, topicFiltersSelectedLength);
105    selectedFilterNumber(typeTextContainer, typeFiltersSelected, typeFiltersSelectedLength);
106    selectedFilterNumber(focusAreaTextContainer, focusAreaFiltersSelected, focusAreaFiltersSelectedLength);
107    selectedFilterNumber(publicationTextContainer, publicationFiltersSelected, publicationFiltersSelectedLength);
108    selectedFilterNumber(regionTextContainer, regionFiltersSelected, regionFiltersSelectedLength);
109    selectedFilterNumber(teamTextContainer, teamFiltersSelected, teamFiltersSelectedLength);
110    // hideEmptyRefinments();
111    hideEmptyRefinmentsSearch();
112    selectedFacets();
113    setTimeout(() => {
114      selectedFacets();
115      // hideEmptyRefinments();
116      hideEmptyRefinmentsSearch();
117      //Show date instead timestamp
118      const items = document.querySelectorAll("#hits .ais-Hits-item");
119      showcurrentResults(items);
120      var length = document.querySelectorAll('.filters-block .filter-dropdown').length - document.querySelectorAll('.filters-block .filter-dropdown.hide').length
121      
122      const linkMore = document.querySelector('.filters-block .filter-wrapper .btn-wrap .link-more');
123      if (length < 4) {
124        linkMore.classList.add('hide');
125      } else {
126        if (linkMore.classList.contains("hide")) {
127          linkMore.classList.remove('hide');
128        }
129      }
130      const clearDate = document.querySelector('.daterangepicker .cancelBtn');
131      const clearGlobal = document.querySelector("#clearGlobal button");
132      const customFacet = document.getElementById("global-date-facet");
133      if (document.body.contains(clearGlobal)) {
134        clearGlobal.addEventListener("click", function () {
135          clearDate.click();
136          customFacet.classList.add('hide');
137        });
138        const clearGlobal1 = document.querySelector("#clearGlobal1 button");
139        clearGlobal1.addEventListener("click", function () {
140          clearDate.click();
141          customFacet.classList.add('hide');
142        });
143      }
144
145      handlePagination()
146    }, 1000);
147  }
148  const afterResultFunction = instantsearch.connectors.connectStats(
149    customafterResultFunction
150  );
151
152  /*
153  Cutomised content fetch
154  */
155  var fellowName = document.querySelector("h1").textContent;
156  var weFacetFilters = "";
157  var weFacetFull = [];
158  if (typeof fellowName !== 'undefined') {
159    weFacetFilters = 'research_type_name:"' + fellowName.trim() + '"';
160  }
161  let timerId;
162  /*
163  Declare search widget
164  */
165  search.addWidgets([
166    /*
167    Declare input search
168    */
169    instantsearch.widgets.searchBox({
170      container: '#searchbox',
171      placeholder: 'Search Research',
172      queryHook(query, refine) {
173        clearTimeout(timerId)
174        timerId = setTimeout(() => refine(query), 1000)
175      },
176      
177    }),
178
179    /* 
180    configure index
181    */
182    instantsearch.widgets.configure({
183      hitsPerPage: 9,
184      filters: weFacetFilters
185    }),
186
187    /*
188    HTML for result Item
189    */
190    instantsearch.widgets.hits({
191      container: '#hits',
192      transformItems(items) {
193        return items.map(item => ({
194          ...item,
195          research_type: handle_research_type(item.research_type_name, "research", item.research_category),
196          author: handleAuthors(item.author_url, item.author_title, item.contributors, item.contributors_label, item.contributors_url, item.editor_url, item.editor_title),
197          publications: typeof (item.publication) == "object" ? item.publication[0] : item.publication,
198          date: dateconverter(item.field_research_date),
199          icon: iconHandler(item.research_type_name),
200          editLink: handleEdit(item.objectID),
201          body: handleBody(item.body, item.news_body),
202          image: awsImageUrl(item.image, item.media_image, '/styles/410x410/public'),
203          imageGrid: awsImageUrl(item.image, item.media_image, '/styles/630x420/public'),
204          additional_contributor_name: additional_nameHandler(item.additional_contributor_name),
205          additional_author_name: additional_nameHandler(item.additional_author_name),
206        }));
207      },
208      templates: {
209        item: ` 
210      <div class="col-three">
211      {{^external_article_url}}<a href="{{{url}}}">Read More</a>{{/external_article_url}}
212      {{#external_article_url}} <a target="_blank" href="{{{external_article_url}}}">Read More</a>{{/external_article_url}}
213      {{#image}}<div class="bg-img">
214          <img class="lazyloaded" src="{{image}}" alt="Image">
215          <img class="lazyloaded gridimage" src="{{imageGrid}}" alt="Image">
216      </div>{{/image}}
217    
218      <div class="content">
219          <div class="text-wrap">
220              {{^external_article_url}}<span class="tag">{{{research_type}}}</span>{{/external_article_url}}
221        {{#external_article_url}}<span class="tag external-link">{{{research_type}}}</span>{{/external_article_url}}
222        <div class="image-wrap">
223				<img src="{{icon}}" alt="{{research_type_name}}">
224			</div>
225          </div>
226          <h6>{{{title}}}{{#subscription}}<span class="subscription-icon"><img src="/themes/hoover/templates/assets/images/drupal-icon/icon_lock.svg" alt="subscription"></span>{{/subscription}}</h6>
227          <p>{{{body}}}</p>
228          <div class="description">
229      <span class="date">{{date}}</span>
230      {{#author}}{{{author}}}{{/author}}{{#additional_author_name}}{{^author}}<span class="authors">by </span>{{/author}}{{#author}}<span class="additional-authors">,</span>{{/author}}{{/additional_author_name}}{{#additional_author_name}}<span class="additional-authors">{{additional_author_name}}</span>{{/additional_author_name}}
231      {{#additional_contributor_name}}{{^author}}<span class="authors">{{contributors_label}} </span>{{/author}}{{#author}}<span class="additional-authors">,</span>{{/author}}{{/additional_contributor_name}}{{#additional_contributor_name}}<span class="additional-authors">{{additional_contributor_name}}</span>{{/additional_contributor_name}}   
232      {{#publisher}}<span>via {{publisher}}</span>{{/publisher}}
233        {{^publisher}}{{#publications}}<span>via {{publications}}</span>{{/publications}}{{/publisher}}
234        {{#editLink}}{{{editLink}}}{{/editLink}}  
235        </div>
236      </div>
237  </div>
238      `,
239        empty: `
240              <span>No result found for "{{query}}"<span>
241          `,
242      }
243    }),
244
245    /*
246    Declare current refinement function
247    */
248    customCurrentRefinements({
249      container: document.querySelector('#global-facet'),
250    }),
251  
252    /*
253    Declare filter content topic
254    */
255    topic({
256      container: '#topic',
257      attribute: 'research_topic_name',
258      limit: 2000,
259      searchable: false,
260      showMore: false,
261      showMoreLimit: 200,
262      operator: "or",
263      sortBy: ["name:asc"],
264    }),
265    
266    /*
267    Declare filter content type
268    */
269    contentType({
270      container: '#content-type',
271      attribute: 'research_type_name',
272      limit: 1000,
273      searchable: false,
274      showMore: false,
275      showMoreLimit: 1000,
276      sortBy: ["name:asc"],
277    }),
278    
279    /*
280    Declare filter focus area
281    */
282    keyFocus({
283      container: '#keyFocus',
284      attribute: 'focus_area',
285      limit: 1000,
286      searchable: false,
287      showMore: false,
288      showMoreLimit: 1000,
289      sortBy: ["name:asc"],
290    }),
291    
292    /*
293    Declare filter publication
294    */
295    publication({
296      container: '#publication',
297      attribute: 'publication',
298      limit: 1000,
299      searchable: false,
300      showMore: false,
301      showMoreLimit: 1000,
302      sortBy: ["name:asc"],
303    }),
304    
305    /*
306    Declare filter region
307    */
308    region({
309      container: '#region',
310      attribute: 'region',
311      limit: 1000,
312      searchable: false,
313      showMore: false,
314      showMoreLimit: 1000,
315      sortBy: ["name:asc"],
316    }),
317    
318    /*
319    Declare filter team
320    */
321    team({
322      container: '#team',
323      attribute: 'team',
324      limit: 1000,
325      searchable: false,
326      showMore: false,
327      showMoreLimit: 1000,
328      sortBy: ["name:asc"],
329    }),
330
331    /*
332    Declare filter contributors
333    */
334    contributors({
335      container: '#contributors',
336      attribute: 'contributors',
337      limit: 1000,
338      searchable: true,
339      showMore: false,
340      showMoreLimit: 1000,
341      operator: "and",
342      sortBy: ["name:asc"],
343    }),
344  
345    /*
346    Declare filter author
347    */
348    author({
349      container: '#author',
350      attribute: 'author_title',
351      limit: 1000,
352      searchable: true,
353      showMore: false,
354      showMoreLimit: 1000,
355      operator: "and",
356      sortBy: ["name:asc"],
357    }),
358
359    /*
360    Declare filter additional author
361    */
362    additional_author({
363      container: '#additional_author',
364      attribute: 'additional_author_name',
365      limit: 1000,
366      searchable: true,
367      showMore: false,
368      showMoreLimit: 1000,
369      operator: "and",
370      sortBy: ["name:asc"],
371    }),
372
373    /*
374    Declare filter additional contributor
375    */
376    additional_contributor({
377      container: '#additional_contributor',
378      attribute: 'additional_contributor_name',
379      limit: 1000,
380      searchable: true,
381      showMore: false,
382      showMoreLimit: 1000,
383      operator: "and",
384      sortBy: ["name:asc"],
385    }),
386    
387    /*
388    Declare custom range input filter
389    */
390    customRangeInputEvent({
391      container: document.querySelector('#date'),
392      attribute: 'field_research_date',
393    }),
394    
395    /*
396    Declare after render function
397    */
398    afterResultFunction({}),
399
400    /*
401    Declare stats widget to display current results number
402    */
403    instantsearch.widgets.stats({
404      container: '#stats',
405      templates: {
406        text: `
407        Displaying <span id="hitPage"></span> of {{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}}
408        `
409      }
410    }),
411
412    /*
413    Declare sort widget
414    */
415    instantsearch.widgets.sortBy({
416      container: '#sort',
417      items: [
418        { label: 'Ascending', value: 'research_ascending' },
419        { label: 'Descending', value: 'research_descending' },
420      ],
421    }),
422    
423    /*
424    Declare clear filter
425    */
426    instantsearch.widgets.clearRefinements({
427      container: '#clearGlobal',
428      templates: {
429        resetLabel: 'Clear All',
430      },
431    }),
432
433    /*
434    Declare clear filter
435    */
436    instantsearch.widgets.clearRefinements({
437      container: '#clearGlobal1',
438      templates: {
439        resetLabel: 'Clear All',
440      },
441    }),
442
443    /*
444    Declare pagination
445    */
446    instantsearch.widgets.pagination({
447      container: '#pagination',
448      scrollTo: '#filter',
449    }),
450  
451  ]).on('render', function () {
452    var intervalId = setInterval(function() {
453      let hitList = document.querySelector("#hits .ais-Hits-list")
454      if (hitList) {
455          clearInterval(intervalId); 
456           let childrenLen = hitList.childElementCount
457            setTimeout(()=>{
458              if(hitList.parentNode){
459                if((!(hitList.parentNode.classList.contains("ais-Hits--empty"))) && childrenLen == 0){
460                  hitList.remove()
461                }
462              }
463            },100)  
464
465      }
466    }, 10);
467  });
468
469  /*
470  Initiate algolia search
471  */
472  search.start();
473  
474  /*
475  Close custom date facet
476  */
477  const dataFacet = document.querySelector("#global-date-facet span");
478  dataFacet.addEventListener("click", function () {
479    const defaultDateFacets = document.querySelectorAll("#global-facet button");
480    defaultDateFacets.forEach(function (item) {
481      const buttonAttr = item.getAttribute("data-attribute");
482      if (buttonAttr == "field_research_date") {
483        item.click();
484      }
485    });
486    document.querySelector("#global-date-facet").classList.add("hide");
487    const clearDate = document.querySelector('.daterangepicker .cancelBtn');
488    clearDate.click();
489    const globalDateFacet = document.querySelectorAll("#global-facet li");
490    globalDateFacet.forEach(function (item) {
491      const attrValue = item.getAttribute("data-value");
492      if (attrValue == "field_research_date") {
493        item.querySelector("button").click();
494      }
495    });
496  });
497
498  //select author name on search  
499
500  var fellowInput = document.querySelector(".algolia-research #searchItem");
501  fellowInput.addEventListener("input", function () {
502    const inputValue = fellowInput.value;
503    const input = document.querySelector(".algolia-research #author .ais-SearchBox-input");
504    const inputContri = document.querySelector(".algolia-research #contributors .ais-SearchBox-input");
505    const inputadditionalContri = document.querySelector(".algolia-research #additional_contributor .ais-SearchBox-input");
506    const inputadditionalAuthor = document.querySelector(".algolia-research #additional_author .ais-SearchBox-input");
507    inputadditionalContri.value = inputValue;
508    inputadditionalAuthor.value = inputValue;
509    input.value = inputValue;
510    inputContri.value = inputValue;
511    var event = new Event('input', {
512      'bubbles': true,
513      'cancelable': true
514    });
515    input.dispatchEvent(event);
516    inputContri.dispatchEvent(event);
517    inputadditionalContri.dispatchEvent(event);
518    inputadditionalAuthor.dispatchEvent(event);
519  });
520
521  /*
522  Date range provider
523  */
524  function daterangeDate(start) {
525    const startNew = start * 1000;
526    const startdate = new Date(startNew);
527    const startyear = startdate.getFullYear();
528    const startday = ("0" + startdate.getDate()).slice(-2);
529    const startmonthIndex = startdate.getMonth();
530    const startmonth = startmonthIndex + 1;
531    const finalStartDate = startmonth + "/" + startday + "/" + startyear;
532    return finalStartDate
533  }
534  window.addEventListener("load", function () {
535    const url = window.location.search;
536    /*
537    Add selected date facet from url on load
538    */
539    if (url.indexOf("field_research_date") >= 0) {
540      const mindaterange = document.getElementById("mindaterange");
541      const maxdaterange = document.getElementById("maxdaterange");
542      var facetParent = document.querySelector("#global-date-facet");
543      var facet = document.querySelector("#global-date-facet .date-facet span");
544      dateConverter(maxdaterange.value, mindaterange.value, facet, facetParent);
545      const daterange = document.getElementById("daterange");
546      const printStart = daterangeDate(mindaterange.value);
547      const printEnd = daterangeDate(maxdaterange.value);
548      const printDate = printStart + " - " + printEnd;
549      daterange.value = printDate;
550    }
551  });
552}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.