From b7f8749cdfbd01d19a71d560f5c8b4322f11542e Mon Sep 17 00:00:00 2001
From: Aditya Telange <21258296+adityatelange@users.noreply.github.com>
Date: Fri, 18 Dec 2020 11:45:10 +0530
Subject: [PATCH] Search: Keyboard Bindings for easier navigation (#138)
* set up basic actions on keypress
* add actions to perform conditionally
* add simple highlight animation
* prevent mouseclick to change active element
* clear input box on Escape
* click on Arrow Right
* clear results and focus search-input on esc
* refactor
---
assets/css/search.css | 8 +++--
assets/js/fastsearch.js | 66 ++++++++++++++++++++++++++++++++++--
layouts/_default/search.html | 2 +-
3 files changed, 71 insertions(+), 5 deletions(-)
diff --git a/assets/css/search.css b/assets/css/search.css
index d788cd22..275cbe10 100644
--- a/assets/css/search.css
+++ b/assets/css/search.css
@@ -1,4 +1,4 @@
-.searchbox input {
+#searchbox input {
padding: 4px 10px;
width: 100%;
color: var(--primary);
@@ -7,7 +7,7 @@
border-radius: var(--radius);
}
-.searchbox input:focus {
+#searchbox input:focus {
border-color: var(--secondary);
}
@@ -38,3 +38,7 @@
left: 0px;
outline: none;
}
+
+#searchResults .active {
+ transform: scale(.98);
+}
diff --git a/assets/js/fastsearch.js b/assets/js/fastsearch.js
index e76f9193..152d31c1 100644
--- a/assets/js/fastsearch.js
+++ b/assets/js/fastsearch.js
@@ -1,4 +1,8 @@
var fuse; // holds our search engine
+var resList = document.getElementById('searchResults');
+var sInput = document.getElementById('searchInput');
+var first, last = null
+var resultsAvailable = false;
// load our search index, only executed onload
function loadSearch() {
@@ -35,6 +39,15 @@ function loadSearch() {
xhr.send();
}
+
+function itemGen(name, link) {
+ return `
`
+}
+
+function activeToggle() {
+ document.activeElement.parentElement.classList.toggle("active")
+}
+
// execute search as each character is typed
document.getElementById("searchInput").onkeyup = function (e) {
// run a search query (for "term") every time a letter is typed
@@ -50,11 +63,60 @@ document.getElementById("searchInput").onkeyup = function (e) {
}
document.getElementById("searchResults").innerHTML = resultSet;
+ resultsAvailable = true;
+ first = resList.firstChild;
+ last = resList.lastChild;
} else {
+ resultsAvailable = false;
document.getElementById("searchResults").innerHTML = '';
}
}
-function itemGen(name, link) {
- return ``
+// kb bindings
+document.onkeydown = function (e) {
+ let key = e.key;
+ let ae = document.activeElement;
+
+ if (key === "ArrowDown" && resultsAvailable) {
+ e.preventDefault();
+ if (ae == sInput) {
+ // if the currently focused element is the search input, focus the of first
+ activeToggle(); // rm active class
+ resList.firstChild.lastChild.focus();
+ activeToggle(); // add active class
+ } else if (ae.parentElement == last) {
+ // if the currently focused element's parent is last, do nothing
+ } else {
+ // otherwise select the next search result
+ activeToggle(); // rm active class
+ ae.parentElement.nextSibling.lastChild.focus();
+ activeToggle(); // add active class
+ }
+ } else if (key === "ArrowUp" && resultsAvailable) {
+ e.preventDefault();
+ if (ae == sInput) {
+ // if the currently focused element is input box, do nothing
+ } else if (ae.parentElement == first) {
+ // if the currently focused element is first item, go to input box
+ activeToggle(); // rm active class
+ sInput.focus();
+ } else {
+ // otherwise select the previous search result
+ activeToggle(); // rm active class
+ ae.parentElement.previousSibling.lastChild.focus();
+ activeToggle(); // add active class
+ }
+ } else if (key === "ArrowRight" && resultsAvailable) {
+ ae.click(); // click on active link
+ } else if (key === "Escape") {
+ resultsAvailable = false;
+ document.getElementById("searchResults").innerHTML = sInput.value = ''; // clear inputbox and searchResults
+ sInput.focus(); // shift focus to input box
+ }
+}
+
+document.onmousedown = function (e) {
+ if (e.type === "mousedown") {
+ e.preventDefault(); // prevent mousedown to change focus
+ }
}
diff --git a/layouts/_default/search.html b/layouts/_default/search.html
index 44b72c57..2105c298 100644
--- a/layouts/_default/search.html
+++ b/layouts/_default/search.html
@@ -30,7 +30,7 @@
{{- end}}
-