1$(function () { 2 $(document).ready(function () { 3 $('#index-filter a').on('click', function (e) { 4 e.preventDefault(); 5 6 if ($(this).attr("data-target") === "all") { 7 $(".search-hits").removeClass("d-none"); 8 } else { 9 $(".search-hits").addClass("d-none"); 10 $($(this).attr("data-target")).removeClass("d-none"); 11 } 12 13 $("#index-filter a").removeClass("active"); 14 $(this).addClass("active"); 15 }); 16 17 (function handleQueryString() { 18 const url = new URL(window.location.href); 19 const params = new URLSearchParams(url.search); 20 21 for (const [key, value] of params) { 22 switch (key) { 23 case 'tab': 24 $(`[data-target="#${value}"]`).trigger("click"); 25 break; 26 } 27 } 28 })(); 29 30 const searchClient = algoliasearch( 31 'U7VRLA9UWN', 32 'ee2588c95b2e489100f159af3cf4486e' 33 ); 34 35 const search = instantsearch({ 36 indexName: 'programs', 37 searchClient, 38 }); 39 40 // Create a render function 41 const renderSearchBox = (renderOptions, isFirstRender) => { 42 const { query, refine, clear, isSearchStalled, widgetParams } = renderOptions; 43 44 if (isFirstRender) { 45 const input = document.createElement('input'); 46 input.setAttribute("id", "search-input"); 47 input.setAttribute("placeholder", "Search"); 48 input.setAttribute("type", "search"); 49 50 const loadingIndicator = document.createElement('span'); 51 loadingIndicator.textContent = 'Loading...'; 52 53 const button = document.createElement('button'); 54 button.textContent = 'Search'; 55 button.className = "btn btn-blue"; 56 57 input.addEventListener("search", event => { 58 let char = event.which || event.keyCode; 59 if (char === 13) { 60 clear(); 61 } else { 62 refine(document.getElementById("search-input").value); 63 } 64 }); 65 66 document.getElementById("btn-search").addEventListener('click', () => { 67 refine(document.getElementById("search-input").value); 68 }); 69 70 widgetParams.container.appendChild(input); 71 } 72 }; 73 74 // create custom widget 75 const customSearchBox = instantsearch.connectors.connectSearchBox( 76 renderSearchBox 77 ); 78 79 const renderPagination = (renderOptions, isFirstRender) => { 80 const { 81 pages, 82 currentRefinement, 83 nbPages, 84 isFirstPage, 85 isLastPage, 86 refine, 87 createURL, 88 widgetParams 89 } = renderOptions; 90 91 widgetParams.container.innerHTML = ` 92 <div class="search-pagination"> 93 <button 94 data-value="${currentRefinement - 1}" 95 ${isFirstPage ? 'disabled' : ''} 96 > 97 <i class="fas fa-arrow-left"></i> 98 </button> 99 <button 100 data-value="${currentRefinement + 1}" 101 ${isLastPage ? 'disabled' : ''} 102 > 103 <i class="fas fa-arrow-right"></i> 104 </button> 105 </div> 106 `; 107 108 widgetParams.container.querySelectorAll('button').forEach(element => { 109 element.addEventListener('click', event => { 110 event.preventDefault(); 111 refine(event.currentTarget.dataset.value); 112 }, false); 113 }); 114 }; 115 116 const customPagination = instantsearch.connectors.connectPagination( 117 renderPagination 118 ); 119 120 const renderProgramHits = (renderOptions, isFirstRender) => { 121 const { hits, widgetParams } = renderOptions; 122 123 widgetParams.container.innerHTML = ` 124 <div class="container"> 125 <div class="row"> 126 ${hits 127 .map( 128 item => 129 `<div class="col-md-6 tile"> 130 <a href="/programs/${item.slug}"> 131 <p class="m-0 hit-title">${instantsearch.highlight({ attribute: 'programTitle', hit: item })}</p> 132 <p class="hit-desc">${instantsearch.snippet({attribute: 'programDescription', hit: item})}</p> 133 </a> 134 </div>` 135 ) 136 .join('')} 137 </div> 138 </div> 139 `; 140 }; 141 142 const renderNewsHits = (renderOptions, isFirstRender) => { 143 const { hits, widgetParams } = renderOptions; 144 145 widgetParams.container.innerHTML = ` 146 <div class="container"> 147 <div class="row"> 148 ${hits 149 .map( 150 item => 151 `<div class="col-lg-3 mb-3 mb-lg-0"> 152 <a href="/newsroom/${item.archive ? 'archive/' : 'news/'}${item.slug}"> 153 <div class="card tile h-100"> 154 <div class="card-img-top"> 155 <div class="search-card-img" style="background-image: url(${item.storyFeatureImage});"></div> 156 </div> 157 <div class="card-header"> 158 <p class="hit-title mb-1">${instantsearch.highlight({ attribute: 'storyTitle', hit: item })}</p> 159 </div> 160 <div class="card-body"> 161 <p class="hit-desc mb-1">${instantsearch.snippet({attribute: 'story', hit: item})}</p> 162 </div> 163 <div class="card-footer"> 164 <p class="m-0"><i class="far fa-user mr-2"></i> ${item.author}</p> 165 <p class="m-0"><i class="far fa-calendar mr-2"></i> ${item.storyDate}</p> 166 </div> 167 </div> 168 </a> 169 </div>` 170 ) 171 .join('')} 172 </div> 173 </div> 174 `; 175 }; 176 177 const renderDocsHits = (renderOptions, isFirstRender) => { 178 const { hits, widgetParams } = renderOptions; 179 180 widgetParams.container.innerHTML = ` 181 <div class="container"> 182 <div class="row"> 183 ${hits 184 .map( 185 item => 186 `<div class="col-lg-3 mb-3 mb-lg-0"> 187 <a href="/newsroom/documents/${item.slug}"> 188 <div class="card tile h-100"> 189 <div class="card-img-top"> 190 <div class="search-card-img" style="background-image: url(${item.documentThumbn
190ail});"></div> 191 </div> 192 <div class="card-header"> 193 <span class="badge badge-pill">${item.documentType[0]}</span> 194 <p class="hit-title mb-1">${instantsearch.highlight({ attribute: 'documentTitle', hit: item })}</p> 195 </div> 196 <div class="card-body"> 197 <p class="hit-desc mb-1">${instantsearch.snippet({attribute: 'documentDescription', hit: item})}</p> 198 </div> 199 <div class="card-footer"> 200 <p class="m-0"><i class="far fa-calendar mr-2"></i> ${item.documentDate}</p> 201 </div> 202 </div> 203 </a> 204 </div>` 205 ) 206 .join('')} 207 </div> 208 </div> 209 `; 210 }; 211 212 const renderFaqHits = (renderOptions, isFirstRender) => { 213 const { hits, widgetParams } = renderOptions; 214 215 widgetParams.container.innerHTML = ` 216 <div class="container"> 217 <div class="row"> 218 ${hits 219 .map( 220 item => 221 `<div class="col-md-6 tile"> 222 <a href="#"> 223 <p class="m-0 hit-title">${instantsearch.highlight({ attribute: 'question', hit: item })}</p> 224 <p class="hit-desc">${instantsearch.snippet({attribute: 'answer', hit: item})}</p> 225 </a> 226 </div>` 227 ) 228 .join('')} 229 </div> 230 </div> 231 `; 232 }; 233 234 const customProgramHits = instantsearch.connectors.connectHits(renderProgramHits); 235 const customNewsHits = instantsearch.connectors.connectHits(renderNewsHits); 236 const customDocsHits = instantsearch.connectors.connectHits(renderDocsHits); 237 const customFaqHits = instantsearch.connectors.connectHits(renderFaqHits); 238 239 search.addWidgets([ 240 customSearchBox({ 241 container: document.querySelector('#searchbox') 242 }), 243 customProgramHits({ 244 container: document.querySelector('#programHits') 245 }), 246 instantsearch.widgets.configure({ 247 hitsPerPage: 4, 248 distinct: true, 249 attributesToSnippet: ['programDescription:20'], 250 snippetEllipsisText: 'â¦' 251 }), 252 customPagination({ 253 container: document.querySelector('#programPagination'), 254 }), 255 256 instantsearch.widgets.stats({ 257 container: '#programStats', 258 templates: { 259 text: ` 260 {{#hasNoResults}}No results{{/hasNoResults}} 261 {{#hasOneResult}}1 result{{/hasOneResult}} 262 {{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}} 263 `, 264 } 265 }), 266 267 instantsearch.widgets 268 .index({indexName: 'news'}) 269 .addWidgets([ 270 customNewsHits({ 271 container: document.querySelector('#newsHits') 272 }), 273 customPagination({ 274 container: document.querySelector('#newsPagination'), 275 }), 276 instantsearch.widgets.stats({ 277 container: '#newsStats', 278 templates: { 279 text: ` 280 {{#hasNoResults}}No results{{/hasNoResults}} 281 {{#hasOneResult}}1 result{{/hasOneResult}} 282 {{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}} 283 `, 284 } 285 }), 286 instantsearch.widgets.configure({ 287 hitsPerPage: 4, 288 distinct: true, 289 attributesToSnippet: ['story:20'], 290 snippetEllipsisText: 'â¦' 291 }), 292 ]), 293 instantsearch.widgets 294 .index({indexName: 'documents'}) 295 .addWidgets([ 296 customDocsHits({ 297 container: document.querySelector('#docHits') 298 }), 299 customPagination({ 300 container: document.querySelector('#docPagination'), 301 }), 302 instantsearch.widgets.stats({ 303 container: '#docStats', 304 templates: { 305 text: ` 306 {{#hasNoResults}}No results{{/hasNoResults}} 307 {{#hasOneResult}}1 result{{/hasOneResult}} 308 {{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}} 309 `, 310 } 311 }), 312 instantsearch.widgets.configure({ 313 hitsPerPage: 4, 314 distinct: true, 315 attributesToSnippet: ['documentDescription:20'], 316 snippetEllipsisText: 'â¦' 317 }), 318 ]), 319 // instantsearch.widgets 320 // .index({indexName: 'faqs'}) 321 // .addWidgets([ 322 // customFaqHits({ 323 // container: document.querySelector('#faqHits') 324 // }), 325 // customPagination({ 326 // container: document.querySelector('#faqPagination'), 327 // }), 328 // instantsearch.widgets.stats({ 329 // container: '#faqStats', 330 // templates: { 331 // text: ` 332 // {{#hasNoResults}}No results{{/hasNoResults}} 333 // {{#hasOneResult}}1 result{{/hasOneResult}} 334 // {{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}} 335 // `, 336 // } 337 // }), 338 // instantsearch.widgets.configure({ 339 // hitsPerPage: 4, 340 // distinct: true, 341 // attributesToSnippet: ['answer:20'], 342 // snippetEllipsisText: 'â¦' 343 // }), 344 // ]) 345 ]); 346 347 search.start(); 348 }); 349});
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.