Price range and exact word matching.

This commit is contained in:
Mario Zechner 2023-05-15 22:35:36 +02:00
parent 2b7c03d143
commit debed60c6d
3 changed files with 72 additions and 11 deletions

View File

@ -14,9 +14,14 @@
<h2>Heisse Preise</h2> <h2>Heisse Preise</h2>
<input id="search" class="search" type="text" placeholder="Produkte suchen..."> <input id="search" class="search" type="text" placeholder="Produkte suchen...">
<div class="filters"> <div class="filters">
<input id="billa" type="checkbox" checked="true"><label>Billa</label> <label><input id="billa" type="checkbox" checked="true"> Billa</label>
<input id="spar" type="checkbox" checked="true"><label>Spar</label> <label><input id="spar" type="checkbox" checked="true"> Spar</label>
<input id="eigenmarken" type="checkbox"><label>Nur CLEVER & S-BUDGET</label> <label><input id="eigenmarken" type="checkbox"> Nur CLEVER & S-BUDGET</label>
</div>
<div class="filters">
<label>Min € <input id="minprice" type="number" min="0" value="0"></label>
<label>Max € <input id="maxprice" type="number" min="0" value="100"></label>
<label><input id="exact" type="checkbox"> Exaktes Wort</label>
</div> </div>
<div class="results"> <div class="results">
<table id="result"> <table id="result">

View File

@ -2,13 +2,16 @@ let items = null;
async function load() { async function load() {
let response = await fetch("api/index") let response = await fetch("api/index")
items = await response.json(); items = await response.json();
let units = {};
for (item of items) { for (item of items) {
item.search = item.name + " " + item.unit; item.search = item.name + " " + item.unit;
item.search = item.search.toLowerCase(); item.search = item.search.toLowerCase();
units[item.unit] = item.unit;
} }
console.log(items.length); console.log(Object.keys(units));
setupUI(); setupUI();
} }
@ -18,7 +21,7 @@ function dom(el, html) {
return element; return element;
} }
function searchItems(query) { function searchItems(query, exact) {
if (query.length < 3) return []; if (query.length < 3) return [];
const tokens = query.split(/\s+/).map(token => token.toLowerCase()); const tokens = query.split(/\s+/).map(token => token.toLowerCase());
@ -27,10 +30,22 @@ function searchItems(query) {
for (item of items) { for (item of items) {
let allFound = true; let allFound = true;
for (token of tokens) { for (token of tokens) {
if (item.search.indexOf(token) < 0) { if (token.length == 0) continue;
const index = item.search.indexOf(token);
if (index < 0) {
allFound = false; allFound = false;
break; break;
} }
if (exact) {
if (index > 0 && (item.search.charAt(index - 1) != " " && item.search.charAt(index - 1) != "-")) {
allFound = false;
break;
}
if (index + token.length < item.search.length && item.search.charAt(index + token.length) != " ") {
allFound = false;
break;
}
}
} }
if (allFound) if (allFound)
hits.push({ doc: item }); hits.push({ doc: item });
@ -38,12 +53,23 @@ function searchItems(query) {
return hits; return hits;
} }
function toNumber(value, defaultValue) {
try {
return Number.parseFloat(value);
} catch(e) {
return defaultValue;
}
}
function search(query) { function search(query) {
const hits = searchItems(query); const exact = document.querySelector("#exact").checked;
const hits = searchItems(query, exact);
const table = document.querySelector("#result"); const table = document.querySelector("#result");
const eigenmarken = document.querySelector("#eigenmarken").checked; const eigenmarken = document.querySelector("#eigenmarken").checked;
const billa = document.querySelector("#billa").checked; const billa = document.querySelector("#billa").checked;
const spar = document.querySelector("#spar").checked; const spar = document.querySelector("#spar").checked;
const minPrice = toNumber(document.querySelector("#minprice").value, 0);
const maxPrice = toNumber(document.querySelector("#maxprice").value, 100);
table.innerHTML = ""; table.innerHTML = "";
if (hits.length == 0) return; if (hits.length == 0) return;
@ -60,6 +86,8 @@ function search(query) {
const name = hit.doc.name.toLowerCase(); const name = hit.doc.name.toLowerCase();
if (hit.doc.store == "billa" && !billa) continue; if (hit.doc.store == "billa" && !billa) continue;
if (hit.doc.store == "spar" && !spar) continue; if (hit.doc.store == "spar" && !spar) continue;
if (hit.doc.price < minPrice) continue;
if (hit.doc.price > maxPrice) continue;
if (eigenmarken && !(name.indexOf("clever") == 0 || name.indexOf("s-budget") == 0)) if (eigenmarken && !(name.indexOf("clever") == 0 || name.indexOf("s-budget") == 0))
continue; continue;
@ -73,13 +101,20 @@ function search(query) {
} }
function setupUI() { function setupUI() {
const searchInput = document.querySelector("#search"); let searchInput = document.querySelector("#search");
searchInput.addEventListener("input", (event) => { searchInput.addEventListener("input", (event) => {
if (searchInput.value.length == 0) {
document.querySelector("#minprice").value = 0;
document.querySelector("#maxprice").value = 100;
}
search(searchInput.value); search(searchInput.value);
}); });
document.querySelector("#eigenmarken").addEventListener("change", () => search(searchInput.value)); document.querySelector("#eigenmarken").addEventListener("change", () => search(searchInput.value));
document.querySelector("#billa").addEventListener("change", () => search(searchInput.value)); document.querySelector("#billa").addEventListener("change", () => search(searchInput.value));
document.querySelector("#spar").addEventListener("change", () => search(searchInput.value)); document.querySelector("#spar").addEventListener("change", () => search(searchInput.value));
document.querySelector("#exact").addEventListener("change", () => search(searchInput.value));
document.querySelector("#minprice").addEventListener("change", () => search(searchInput.value));
document.querySelector("#maxprice").addEventListener("change", () => search(searchInput.value));
} }
load(); load();

View File

@ -23,6 +23,10 @@ body {
margin-bottom: 1em; margin-bottom: 1em;
} }
input[type="number"] {
max-width: 3em;
}
.results { .results {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -31,6 +35,23 @@ body {
table { table {
width: 100%; width: 100%;
border-collapse: collapse;
border: 1px solid;
}
th {
border: 1px solid;
padding: 0.2em;
background: #aaa;
}
tr {
border-collapse: collapse;
border: 1px solid #ddd;
}
td {
padding: 0.2em;
} }
th { th {