Skip to content

Commit

Permalink
Merge pull request #96 from navendu-pottekkat/feat/search/daily
Browse files Browse the repository at this point in the history
  • Loading branch information
pottekkat authored Aug 7, 2023
2 parents bb8db73 + 1f38181 commit 6038475
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 4 deletions.
165 changes: 165 additions & 0 deletions assets/js/fastsearch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import * as params from "@params";

let fuse; // holds our search engine
let resList = document.getElementById("searchResults");
let sInput = document.getElementById("searchInput");
let first,
last,
current_elem = null;
let resultsAvailable = false;

// load our search index
window.onload = function () {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
let data = JSON.parse(xhr.responseText);
let searchBox = document.querySelector("#searchInput");
let showOnly = searchBox.dataset.showOnly;
let omit = searchBox.dataset.omit;

// Filter data based on "showOnly" and "omit"
if (showOnly) {
data = data.filter(function (item) {
return item.categories.indexOf(showOnly) !== -1;
});
} else if (omit) {
data = data.filter(function (item) {
return item.categories.indexOf(omit) === -1;
});
}
if (data) {
// fuse.js options; check fuse.js website for details
let options = {
distance: 100,
threshold: 0.4,
ignoreLocation: true,
keys: ["title", "permalink", "summary", "content", "categories"],
};
if (params.fuseOpts) {
options = {
isCaseSensitive: params.fuseOpts.iscasesensitive ?? false,
includeScore: params.fuseOpts.includescore ?? false,
includeMatches: params.fuseOpts.includematches ?? false,
minMatchCharLength: params.fuseOpts.minmatchcharlength ?? 1,
shouldSort: params.fuseOpts.shouldsort ?? true,
findAllMatches: params.fuseOpts.findallmatches ?? false,
keys: params.fuseOpts.keys ?? [
"title",
"permalink",
"summary",
"content",
"categories",
],
location: params.fuseOpts.location ?? 0,
threshold: params.fuseOpts.threshold ?? 0.4,
distance: params.fuseOpts.distance ?? 100,
ignoreLocation: params.fuseOpts.ignorelocation ?? true,
};
}
fuse = new Fuse(data, options); // build the index from the json file
}
} else {
console.log(xhr.responseText);
}
}
};
xhr.open("GET", "../index.json");
xhr.send();
};

function activeToggle(ae) {
document.querySelectorAll(".focus").forEach(function (element) {
// rm focus class
element.classList.remove("focus");
});
if (ae) {
ae.focus();
document.activeElement = current_elem = ae;
ae.parentElement.classList.add("focus");
} else {
document.activeElement.parentElement.classList.add("focus");
}
}

function reset() {
resultsAvailable = false;
resList.innerHTML = sInput.value = ""; // clear inputbox and searchResults
sInput.focus(); // shift focus to input box
}

// execute search as each character is typed
sInput.onkeyup = function (e) {
// run a search query (for "term") every time a letter is typed
// in the search box
if (fuse) {
const results = fuse.search(this.value.trim(), {limit: params.fuseOpts.limit}); // the actual query being run using fuse.js
if (results.length !== 0) {
// build our html if result exists
let resultSet = ""; // our results bucket

for (let item in results) {
resultSet +=
`<li class="post-entry"><header class="entry-header">${results[item].item.title}&nbsp;»</header>` +
`<a href="${results[item].item.permalink}" aria-label="${results[item].item.title}"></a></li>`;
}

resList.innerHTML = resultSet;
resultsAvailable = true;
first = resList.firstChild;
last = resList.lastChild;
} else {
resultsAvailable = false;
resList.innerHTML = "";
}
}
};

sInput.addEventListener("search", function (e) {
// clicked on x
if (!this.value) reset();
});

// kb bindings
document.onkeydown = function (e) {
let key = e.key;
let ae = document.activeElement;

let inbox = document.getElementById("searchbox").contains(ae);

if (ae === sInput) {
let elements = document.getElementsByClassName("focus");
while (elements.length > 0) {
elements[0].classList.remove("focus");
}
} else if (current_elem) ae = current_elem;

if (key === "Escape") {
reset();
} else if (!resultsAvailable || !inbox) {
return;
} else if (key === "ArrowDown") {
e.preventDefault();
if (ae == sInput) {
// if the currently focused element is the search input, focus the <a> of first <li>
activeToggle(resList.firstChild.lastChild);
} else if (ae.parentElement != last) {
// if the currently focused element's parent is last, do nothing
// otherwise select the next search result
activeToggle(ae.parentElement.nextSibling.lastChild);
}
} else if (key === "ArrowUp") {
e.preventDefault();
if (ae.parentElement == first) {
// if the currently focused element is first item, go to input box
activeToggle(sInput);
} else if (ae != sInput) {
// if the currently focused element is input box, do nothing
// otherwise select the previous search result
activeToggle(ae.parentElement.previousSibling.lastChild);
}
} else if (key === "ArrowRight") {
ae.click(); // click on active link
}
};
1 change: 1 addition & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ params:
distance: 1000
threshold: 0.1
minMatchCharLength: 0
limit: 5
keys: ["title", "permalink", "summary", "content"]
menu:
main:
Expand Down
2 changes: 1 addition & 1 deletion layouts/_default/archives.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ <h1>{{ .Title }}</h1>

<div id="searchbox">
<input id="searchInput" autofocus placeholder="{{ .Params.placeholder | default (printf "%s " .Title) }}"
aria-label="search" type="search" autocomplete="off">
aria-label="search" type="search" autocomplete="off" data-omit="Daily Dose of Pottekkat">
<ul id="searchResults" aria-label="search results"></ul>
</div>

Expand Down
6 changes: 6 additions & 0 deletions layouts/_default/dailies.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ <h1>
</div>
</article>

<div id="searchbox">
<input id="searchInput" autofocus placeholder="{{ .Params.placeholder | default (printf "Search ") }}"
aria-label="search" type="search" autocomplete="off" data-show-only="Daily Dose of Pottekkat">
<ul id="searchResults" aria-label="search results"></ul>
</div>

{{- $pages := where site.RegularPages "Type" "in" site.Params.dailySections }}

{{- if site.Params.ShowAllPagesInArchive }}
Expand Down
4 changes: 2 additions & 2 deletions layouts/_default/index.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{{- $.Scratch.Add "index" slice -}}
{{- range .Site.RegularPages -}}
{{- if and (not .Params.searchHidden) (ne .Layout `archives`) (ne .Layout `dailies`) (ne .Layout `stats`) (ne .Layout `about`) (ne .Layout `search`) (ne .Layout `subscribe`) (ne .Layout `daily-theme`) }}
{{- $.Scratch.Add "index" (dict "title" .Title "content" .Plain "permalink" .Permalink "summary" .Summary) -}}
{{- if and (not .Params.searchHidden) (ne .Layout `archives`) (ne .Layout `dailies`) (ne .Layout `stats`) (ne .Layout `about`) (ne .Layout `search`) (ne .Layout `subscribe`) }}
{{- $.Scratch.Add "index" (dict "title" .Title "content" .Plain "permalink" .Permalink "summary" .Summary "categories" .Params.categories) -}}
{{- end }}
{{- end -}}
{{- $.Scratch.Get "index" | jsonify -}}
2 changes: 1 addition & 1 deletion layouts/partials/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

{{- /* Search */}}
{{- if or (eq .Layout `search`) (eq .Layout `archives`) -}}
{{- if or (eq .Layout `search`) (eq .Layout `archives`) (eq .Layout `dailies`) -}}
<link crossorigin="anonymous" rel="preload" as="fetch" href="../index.json">
{{- $fastsearch := resources.Get "js/fastsearch.js" | js.Build (dict "params" (dict "fuseOpts" site.Params.fuseOpts)) | resources.Minify }}
{{- $fusejs := resources.Get "js/fuse.basic.min.js" }}
Expand Down

0 comments on commit 6038475

Please sign in to comment.