diff --git a/public/assets/js/modules/Search.mjs b/public/assets/js/modules/Search.mjs index 3ff18af..1570cb5 100644 --- a/public/assets/js/modules/Search.mjs +++ b/public/assets/js/modules/Search.mjs @@ -6,18 +6,21 @@ export default class Search { this.lastQuery = ""; this.throttle = null; + this.controller = null; // AbortController will be assigned here this.results = results; this.input = input; this.input?.addEventListener("keyup",event => this.keyEvent(event)) ?? false; } + // Destroy the result DOM tree clearResults() { while(this.results.firstChild) { this.results.removeChild(this.results.lastChild); } } + // Display output as HTML output(html) { this.clearResults(); if(typeof html === "string") { @@ -27,6 +30,7 @@ export default class Search { this.results.appendChild(html); } + // Display a status message in a paragraph status(text,classList = false) { const element = document.createElement("p"); if(classList !== false) { @@ -37,12 +41,15 @@ export default class Search { this.output(element); } + // Fetch search results from endpoint async search(query) { const url = new URL(this.endpoint); url.searchParams.set("q",query); const timeout = new Promise(reject => setTimeout(() => reject("Request timed out"),3000)); + // Fetch response from server const api = fetch(url,{ + signal: this.controller.signal, headers: { "Content-Type": "text/html" } @@ -51,29 +58,33 @@ export default class Search { const result = Promise.race([api,timeout]); result.then(response => { if(!response.ok) { - console.error("Response from server:",response); + this.status("oh no, something went wrong","error"); throw new Error("Invalid response from server"); } return response.text(); }) .then(html => this.output(html)) - .catch(error => this.status(error,"error")); + .catch(error => {}); } // Wait until the user stops typing for a few miliseconds queue(query) { clearTimeout(this.throttle); + this.controller = new AbortController(); // Spawn a new AbortController for each fetch this.throttle = setTimeout(() => this.search(query),500); } keyEvent(event) { const query = event.target.value; + // Don't do the search thing if query is too weak if(query.length < 1) { + this.controller.abort(); // Abort queued search this.lastQuery = ""; this.status("search results will appear here as you type"); return; } + // Pressing a modifier key (Ctrl, Shift etc.) doesn't change the query if(query === this.lastQuery) { return false; } diff --git a/public/assets/js/noscript.js b/public/assets/js/noscript.js new file mode 100644 index 0000000..b265ca3 --- /dev/null +++ b/public/assets/js/noscript.js @@ -0,0 +1,6 @@ +const search = document.getElementById("search").children[0]; +const results = document.getElementById("results").children[0]; + +search.style.setProperty("display","none"); +results.classList.add("error"); +results.innerText = "Sorry, your browser isn't supported yet"; \ No newline at end of file diff --git a/public/assets/js/search.js b/public/assets/js/search.js deleted file mode 100644 index 5294587..0000000 --- a/public/assets/js/search.js +++ /dev/null @@ -1,7 +0,0 @@ -import { default as Search } from "./modules/Search.mjs"; - -const searchBox = document.getElementById("search")?.children[0] ?? false; -const resultsContainer = document.getElementById("results"); - -new Search(searchBox,resultsContainer); -window.addEventListener("keydown",() => searchBox.focus()); \ No newline at end of file diff --git a/public/assets/js/search.mjs b/public/assets/js/search.mjs new file mode 100644 index 0000000..cb9b9ef --- /dev/null +++ b/public/assets/js/search.mjs @@ -0,0 +1,9 @@ +import { default as Search } from "./modules/Search.mjs"; + +const searchBox = document.getElementById("search")?.getElementsByTagName("input")[0] ?? false; +const resultsContainer = document.getElementById("results"); + +new Search(searchBox,resultsContainer); + +// Set focus on searchbox when typing from anywhere +window.addEventListener("keydown",() => searchBox.focus()); \ No newline at end of file diff --git a/public/search.html b/public/search.html index b8d2445..f888da6 100644 --- a/public/search.html +++ b/public/search.html @@ -9,7 +9,6 @@ -
@@ -21,6 +20,7 @@

search results will appear here as you type

- + + diff --git a/src/search/Search.php b/src/search/Search.php index a271a70..966027d 100644 --- a/src/search/Search.php +++ b/src/search/Search.php @@ -27,7 +27,7 @@ // Perform a seach on the given query and return the results as an array private function get_results() { - $sql = "SELECT template,title,content,href FROM `search` WHERE `title` LIKE '%{$this->query}%'"; + $sql = "SELECT template,title,content,href FROM `search` WHERE `title` LIKE '%{$this->query}%' OR `content` LIKE '%{$this->query}%'"; $rows = $this->get_rows($sql); return $rows; } @@ -47,7 +47,7 @@ $results = $this->get_results(); if(count($results) < 1) { - $results[] = ["message","info","no results :("]; + $results[] = ["message","info","no results 😞"]; } // Load HTML and format each response from template