Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 60 additions & 11 deletions views/pages/search.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module.exports = function(options) {
const {query, register} = options;
const {query, register, manufacturers} = options;

let searchQuery;
const searchQuery = (query.q || '').trim();

if (!('q' in query) || (searchQuery = query.q.trim()).length == 0) {
if (!('q' in query) || (searchQuery.length == 0)) {
options.title = 'Search - Open Fixture Library';

let str = require('../partials/header')(options);
Expand All @@ -16,37 +16,86 @@ module.exports = function(options) {
return str;
}

const searchQueryCompare = searchQuery.toLowerCase();
const searchQueryEscaped = htmlescape(searchQuery);

options.title = `Search "${searchQueryEscaped}" - Open Fixture Library`;
options.searchQueryEscaped = searchQueryEscaped;

if (!('m' in query) || query.m === '') {
query.m = [];
}
else if (typeof query.m == 'string') {
query.m = [query.m];
}

if (!('c' in query) || query.c === '') {
query.c = [];
}
else if (typeof query.c == 'string') {
query.c = [query.c];
}
query.c = query.c.map(decodeURIComponent);

let results = [];
for (const fix in register.filesystem) {
const fixData = register.filesystem[fix];
if (fix.indexOf(query.q.toLowerCase()) > -1 || (fixData.manufacturerName + ' ' + fixData.name).toLowerCase().indexOf(query.q.toLowerCase()) > -1) {
results.push(fix);
for (const key in register.filesystem) {
const [man, fix] = key.split('/');
const fixData = register.filesystem[key];
const name = (fixData.manufacturerName + ' ' + fixData.name).toLowerCase();

// very primitive match algorithm, maybe put more effort into it sometime
if (
(key.indexOf(searchQueryCompare) > -1 || name.indexOf(searchQueryCompare) > -1) // name matches
&& (query.m.length == 0 || query.m.indexOf(man) > -1) // manufacturer is not relevant or matches
&& (query.c.length == 0 || categoryMatch(query.c, key, register)) // categories are not relevant or match
) {
results.push(key);
}
}

let str = require('../partials/header')(options);

str += `<h1>Search <em>${searchQueryEscaped}</em></h1>`;

str += '<form class="filter" action="/search">';
str += ` <input type="search" name="q" value="${searchQueryEscaped}" />`;
str += ' <select name="m" multiple>';
str += ' <option value="">Filter by manufacturer</option>';
str += Object.keys(manufacturers).map(man => `<option value="${man}"${query.m.indexOf(man) > -1 ? ' selected' : ''}>${manufacturers[man].name}</option>`).join('');
str += ' </select>';
str += ' <select name="c" multiple>';
str += ' <option value="">Filter by category</option>';
str += Object.keys(register.categories).map(cat => `<option value="${cat}"${query.c.indexOf(cat) > -1 ? ' selected' : ''}>${cat}</option>`).join('');
str += ' </select>';
str += ' <button type="submit">Search</button>';
str += '</form>';

str += '<div class="search-results">';
if (results.length > 0) {
for (const fix of results) {
const fixData = register.filesystem[fix];
str += `<p><a href="/${fix}">${fixData.manufacturerName} ${fixData.name}</p>`;
for (const key of results) {
const fixData = register.filesystem[key];
str += `<p><a href="/${key}">${fixData.manufacturerName} ${fixData.name}</p>`;
}
}
else {
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>`;
}
str += '</div>';

str += require('../partials/footer')(options);

return str;
};

function categoryMatch(categoryQuery, key, register) {
for (const cat of categoryQuery) {
if (cat in register.categories && register.categories[cat].indexOf(key) > -1) {
return true;
}
}
return false;
}

function htmlescape(str) {
return str.replace(/[^0-9A-Za-z ]/g, c => `&#${c.charCodeAt(0)};`);
}
2 changes: 1 addition & 1 deletion views/partials/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = function(options) {
<a href="/" class="home-logo" title="Open Fixture Library">Open Fixture Library</a>

<form action="/search">
<input type="search" name="q" placeholder="Search fixture" />
<input type="search" name="q" placeholder="Search fixtures" value="${options.searchQueryEscaped || ''}" />
<button type="submit">Search</button>
</form>

Expand Down