@@ -5,38 +5,93 @@ const search = new (function() {
55
66 function removeListItems ( listId ) {
77
8- if ( ! list . firstChild ) return ;
8+ if ( ! list || ! list . firstChild ) return ;
99 var list = document . getElementById ( listId ) ;
1010 while ( list . firstChild ) {
1111 list . firstChild . remove ( ) ;
1212 }
1313 }
1414
15- function fetchSearchData ( ) {
16-
15+ function fetchSearchData ( ) {
1716 fetch ( '/templates/data/site-search.json' )
1817 . then ( response => response . json ( ) )
1918 . then ( data => {
20-
21- //Add all options to the list
22- const list = document . getElementById ( 'home-search__list' ) ;
23-
24- for ( let i = 0 ; i < data . length ; i ++ ) {
25- const listItem = document . createElement ( 'li' ) ;
26- const link = document . createElement ( 'a' ) ;
27- link . textContent = data [ i ] . title ;
28- listItem . setAttribute ( 'role' , 'option' ) ;
29- listItem . setAttribute ( 'tabindex' , '-1' ) ;
30- link . setAttribute ( 'href' , data [ i ] . link ) ;
31- listItem . appendChild ( link )
32- list . append ( listItem ) ;
33- }
34-
19+ const inputField = document . querySelector ( '[role="combobox"]' ) ;
20+ const list = document . getElementById ( 'home-search__list' ) ;
21+
22+ inputField . addEventListener ( 'input' , ( ) => {
23+ const searchTerm = inputField . value . trim ( ) . toLowerCase ( ) ;
24+
25+ removeListItems ( 'home-search__list' ) ;
26+ clearComboboxState ( ) ;
27+
28+ // Separate title and descriptions to order accordingly
29+ const titleMatches = [ ] ;
30+ const descMatches = [ ] ;
31+
32+ data . forEach ( item => {
33+ const originalTitle = item . title ;
34+ const originalDesc = item . desc ;
35+
36+ if ( originalTitle . toLowerCase ( ) . includes ( searchTerm ) ) {
37+ titleMatches . push ( item ) ;
38+ } else if ( originalDesc . toLowerCase ( ) . includes ( searchTerm ) ) {
39+ descMatches . push ( item ) ;
40+ }
41+ } ) ;
42+
43+ // Helper function to populate list
44+ const populateList = ( items ) => {
45+ items . forEach ( item => {
46+ const listItem = document . createElement ( 'li' ) ;
47+ listItem . setAttribute ( 'role' , 'option' ) ;
48+ listItem . setAttribute ( 'tabindex' , '-1' ) ;
49+
50+ const link = document . createElement ( 'a' ) ;
51+ link . setAttribute ( 'href' , item . link ) ;
52+ link . style . display = 'block' ;
53+ link . style . textDecoration = 'none' ;
54+
55+ // Highlight title and description
56+ const title = document . createElement ( 'strong' ) ;
57+ title . innerHTML = highlightText ( item . title , searchTerm ) ;
58+
59+ const desc = document . createElement ( 'p' ) ;
60+ desc . innerHTML = highlightText ( item . desc , searchTerm ) ;
61+ desc . style . margin = '4px 0' ;
62+
63+ link . appendChild ( title ) ;
64+ link . appendChild ( document . createElement ( 'br' ) ) ;
65+ link . appendChild ( desc ) ;
66+
67+ listItem . appendChild ( link ) ;
68+ list . appendChild ( listItem ) ;
69+ } ) ;
70+ } ;
71+
72+ populateList ( titleMatches ) ;
73+ populateList ( descMatches ) ;
74+
3575 enableComboboxes . init ( ) ;
76+ } ) ;
3677 } )
3778 . catch ( error => {
3879 console . error ( 'Error fetching the JSON file:' , error ) ;
39- } ) ;
80+ } ) ;
81+ }
82+
83+ function highlightText ( text , searchTerm ) {
84+ if ( ! searchTerm ) return text ;
85+ const regex = new RegExp ( `(${ searchTerm } )` , "gi" ) ;
86+ return text . replace ( regex , '<span class="highlight">$1</span>' ) ;
87+ }
88+
89+ function clearComboboxState ( ) {
90+ const listbox = document . querySelector ( '[role="listbox"]' ) ;
91+ if ( listbox ) {
92+ listbox . innerHTML = '' ;
93+ }
94+ enableComboboxes . list = [ ] ;
4095 }
4196
4297 this . init = ( ) => {
0 commit comments