@@ -5,38 +5,93 @@ const search = new (function() {
5
5
6
6
function removeListItems ( listId ) {
7
7
8
- if ( ! list . firstChild ) return ;
8
+ if ( ! list || ! list . firstChild ) return ;
9
9
var list = document . getElementById ( listId ) ;
10
10
while ( list . firstChild ) {
11
11
list . firstChild . remove ( ) ;
12
12
}
13
13
}
14
14
15
- function fetchSearchData ( ) {
16
-
15
+ function fetchSearchData ( ) {
17
16
fetch ( '/templates/data/site-search.json' )
18
17
. then ( response => response . json ( ) )
19
18
. 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
+
35
75
enableComboboxes . init ( ) ;
76
+ } ) ;
36
77
} )
37
78
. catch ( error => {
38
79
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 = [ ] ;
40
95
}
41
96
42
97
this . init = ( ) => {
0 commit comments