Skip to content

Instantly share code, notes, and snippets.

@joelcardinal
Last active November 28, 2018 15:36
Show Gist options
  • Save joelcardinal/bcde2e4843030ee7999d3db3fc27a7b6 to your computer and use it in GitHub Desktop.
Save joelcardinal/bcde2e4843030ee7999d3db3fc27a7b6 to your computer and use it in GitHub Desktop.
Prototype of a potential solution for search feature for static sites, where static site generator would produce a JSON file with potential search data to be used by client-side search algorithm.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>STATIC SITE SEARCH</title>
</head>
<body>
<h1>STATIC SITE SEARCH</h1>
<label for="queryz">Query:</label>
<input type="text" id="queryz" name="query" maxlength="80" size="10" autocomplete="off">
<div id="queryResults"></div>
<script>
/*
STATIC SITE SEARCH
TODO:
- maybe show ... when downloading JSON and searching for query results
- improve suggestion html/css
Requirements:
JSON file in the following format where keys are potential search terms (synonyms separated by space) and values are array of page data:
NOTE: Likely not performant when JSON file is heavily populated, but upperbound has not been tested.
A different data structure and search algorithm may improve performance ranther than iterating over all keys.
{
"magic tricks" : [
{
"title" : "Houdini",
"url" : "/houdini.html"
},
{
"title" : "Hare from Hat",
"url" : "/hare.html"
}
],
"crime" : [
{
"title" : "Cuffed",
"url" : "/cuffed.html"
},
{
"title" : "Booked",
"url" : "/booked.html"
}
]
}
*/
(function(inputID,resultsID,jsonPath){
var queryData = {};
// load data onmouseover (only once)
document.getElementById(inputID).onmouseover = function getQuery(e){
if(!Object.keys(queryData).length){
fetch(jsonPath)
.then(function(response){
return response.json();
})
.then(function(myJson){
queryData = myJson;
var input = document.getElementById(inputID);
execSearch(input);
});
}
}
document.getElementById(inputID).onkeyup = function getQuery(e){
execSearch(e.target);
}
// perform search
function execSearch(elem){
var value = elem.value;
if(value && value.trim() && value.length > 1){
var arr = [];
for (k in queryData){
if(fuzzysearch(value.toLowerCase(), k.toLowerCase())){
for(var i=0,len=queryData[k].length;i<len;i++){
arr.push(`<li><a href="${queryData[k][i].url}">${queryData[k][i].title}</a></li>`);
}
}
}
document.getElementById(resultsID).innerHTML = `<ul>${arr.join('')}<ul>`;
}else{
document.getElementById(resultsID).innerHTML = '';
}
}
// search algorithm
// https://github.com/bevacqua/fuzzysearch
function fuzzysearch (needle, haystack) {
var hlen = haystack.length;
var nlen = needle.length;
if (nlen > hlen) {
return false;
}
if (nlen === hlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < nlen; i++) {
var nch = needle.charCodeAt(i);
while (j < hlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
})("queryz","queryResults","/test.json");
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment