11module . exports = function ( options ) {
2- const { query, register} = options ;
2+ const { query, register, manufacturers } = options ;
33
4- let searchQuery ;
4+ const searchQuery = ( query . q || '' ) . trim ( ) ;
55
6- if ( ! ( 'q' in query ) || ( searchQuery = query . q . trim ( ) ) . length == 0 ) {
6+ if ( ! ( 'q' in query ) || ( searchQuery . length == 0 ) ) {
77 options . title = 'Search - Open Fixture Library' ;
88
99 let str = require ( '../partials/header' ) ( options ) ;
@@ -16,37 +16,86 @@ module.exports = function(options) {
1616 return str ;
1717 }
1818
19+ const searchQueryCompare = searchQuery . toLowerCase ( ) ;
1920 const searchQueryEscaped = htmlescape ( searchQuery ) ;
2021
2122 options . title = `Search "${ searchQueryEscaped } " - Open Fixture Library` ;
23+ options . searchQueryEscaped = searchQueryEscaped ;
24+
25+ if ( ! ( 'm' in query ) || query . m === '' ) {
26+ query . m = [ ] ;
27+ }
28+ else if ( typeof query . m == 'string' ) {
29+ query . m = [ query . m ] ;
30+ }
31+
32+ if ( ! ( 'c' in query ) || query . c === '' ) {
33+ query . c = [ ] ;
34+ }
35+ else if ( typeof query . c == 'string' ) {
36+ query . c = [ query . c ] ;
37+ }
38+ query . c = query . c . map ( decodeURIComponent ) ;
2239
2340 let results = [ ] ;
24- for ( const fix in register . filesystem ) {
25- const fixData = register . filesystem [ fix ] ;
26- if ( fix . indexOf ( query . q . toLowerCase ( ) ) > - 1 || ( fixData . manufacturerName + ' ' + fixData . name ) . toLowerCase ( ) . indexOf ( query . q . toLowerCase ( ) ) > - 1 ) {
27- results . push ( fix ) ;
41+ for ( const key in register . filesystem ) {
42+ const [ man , fix ] = key . split ( '/' ) ;
43+ const fixData = register . filesystem [ key ] ;
44+ const name = ( fixData . manufacturerName + ' ' + fixData . name ) . toLowerCase ( ) ;
45+
46+ // very primitive match algorithm, maybe put more effort into it sometime
47+ if (
48+ ( key . indexOf ( searchQueryCompare ) > - 1 || name . indexOf ( searchQueryCompare ) > - 1 ) // name matches
49+ && ( query . m . length == 0 || query . m . indexOf ( man ) > - 1 ) // manufacturer is not relevant or matches
50+ && ( query . c . length == 0 || categoryMatch ( query . c , key , register ) ) // categories are not relevant or match
51+ ) {
52+ results . push ( key ) ;
2853 }
2954 }
30-
55+
3156 let str = require ( '../partials/header' ) ( options ) ;
3257
3358 str += `<h1>Search <em>${ searchQueryEscaped } </em></h1>` ;
3459
60+ str += '<form class="filter" action="/search">' ;
61+ str += ` <input type="search" name="q" value="${ searchQueryEscaped } " />` ;
62+ str += ' <select name="m" multiple>' ;
63+ str += ' <option value="">Filter by manufacturer</option>' ;
64+ str += Object . keys ( manufacturers ) . map ( man => `<option value="${ man } "${ query . m . indexOf ( man ) > - 1 ? ' selected' : '' } >${ manufacturers [ man ] . name } </option>` ) . join ( '' ) ;
65+ str += ' </select>' ;
66+ str += ' <select name="c" multiple>' ;
67+ str += ' <option value="">Filter by category</option>' ;
68+ str += Object . keys ( register . categories ) . map ( cat => `<option value="${ cat } "${ query . c . indexOf ( cat ) > - 1 ? ' selected' : '' } >${ cat } </option>` ) . join ( '' ) ;
69+ str += ' </select>' ;
70+ str += ' <button type="submit">Search</button>' ;
71+ str += '</form>' ;
72+
73+ str += '<div class="search-results">' ;
3574 if ( results . length > 0 ) {
36- for ( const fix of results ) {
37- const fixData = register . filesystem [ fix ] ;
38- str += `<p><a href="/${ fix } ">${ fixData . manufacturerName } ${ fixData . name } </p>` ;
75+ for ( const key of results ) {
76+ const fixData = register . filesystem [ key ] ;
77+ str += `<p><a href="/${ key } ">${ fixData . manufacturerName } ${ fixData . name } </p>` ;
3978 }
4079 }
4180 else {
4281 str += `<p>Your search for <em>${ searchQueryEscaped } </em> did not match any fixtures. Try using another query or browse by <a href="/manufacturers">manufacturer</a> or <a href="/categories">category</a>.</p>` ;
4382 }
83+ str += '</div>' ;
4484
4585 str += require ( '../partials/footer' ) ( options ) ;
4686
4787 return str ;
4888} ;
4989
90+ function categoryMatch ( categoryQuery , key , register ) {
91+ for ( const cat of categoryQuery ) {
92+ if ( cat in register . categories && register . categories [ cat ] . indexOf ( key ) > - 1 ) {
93+ return true ;
94+ }
95+ }
96+ return false ;
97+ }
98+
5099function htmlescape ( str ) {
51100 return str . replace ( / [ ^ 0 - 9 A - Z a - z ] / g, c => `&#${ c . charCodeAt ( 0 ) } ;` ) ;
52101}
0 commit comments