PageSourceSearch

https://planetark.com/javascripts/search.js

js planetark.com collected 2026-10-02 03:07:58 UTC 14,858 bytes, 349 lines download raw bytes

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.