Init autocomplete. Still needs some testing and fixes.
This commit is contained in:
41
css/main.css
41
css/main.css
@@ -32,9 +32,11 @@ body {
|
||||
width: 50%;
|
||||
margin: 0 auto 50px auto;
|
||||
height: 45px;
|
||||
padding-top: 35px; }
|
||||
.main #search-bar input {
|
||||
height: inherit;
|
||||
padding-top: 35px;
|
||||
position: relative;
|
||||
display: inline-block; }
|
||||
.main #search-bar #search-bar-input {
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
background: #2e2e2e;
|
||||
box-shadow: none;
|
||||
@@ -44,10 +46,36 @@ body {
|
||||
outline: none;
|
||||
padding: 7px 14px;
|
||||
font-size: 18px;
|
||||
color: #fff; }
|
||||
.main #search-bar input:focus {
|
||||
color: #fff;
|
||||
box-sizing: border-box; }
|
||||
.main #search-bar #search-bar-input:focus {
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); }
|
||||
.main #search-bar .autocomplete-items-container {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 99;
|
||||
border-radius: 6px; }
|
||||
.main #search-bar .autocomplete-items-container .autocomplete-item {
|
||||
width: 100%;
|
||||
background: #2e2e2e;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
text-align: center;
|
||||
outline: none;
|
||||
padding: 7px 14px;
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); }
|
||||
.main #search-bar .autocomplete-items-container .autocomplete-item:hover {
|
||||
background-color: red; }
|
||||
.main #search-bar .autocomplete-items-container .autocomplete-active {
|
||||
background-color: DodgerBlue !important;
|
||||
color: #ffffff; }
|
||||
@media only screen and (max-width: 791px) {
|
||||
.main #search-bar {
|
||||
width: 65%; } }
|
||||
@@ -57,7 +85,8 @@ body {
|
||||
.main #other-content .sqr {
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
margin: 5px;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
width: 170px;
|
||||
background: #2e2e2e;
|
||||
padding: 15px 15px;
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
</div>
|
||||
<div id="search-bar">
|
||||
<input id="search-bar-input"></input>
|
||||
<div class="autocomplete-items-container">
|
||||
</div>
|
||||
</div>
|
||||
<div id="other-content">
|
||||
</div>
|
||||
@@ -38,6 +40,7 @@
|
||||
<script src="js/jsoneditor.min.js"></script>
|
||||
<!--Custom JS-->
|
||||
<script src="js/settings.js"></script>
|
||||
<script src="js/autocomplete.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
108
js/autocomplete.js
Normal file
108
js/autocomplete.js
Normal file
@@ -0,0 +1,108 @@
|
||||
function autocomplete(inp, passedValues) {
|
||||
var currentFocus;
|
||||
|
||||
/*execute a function when someone writes in the text field:*/
|
||||
inp.addEventListener("input", function(e) {
|
||||
var parentContainer, item, val = this.value;
|
||||
|
||||
/*close any already open lists of autocompleted values*/
|
||||
closeAllLists();
|
||||
if (!val) { return false;}
|
||||
currentFocus = -1;
|
||||
|
||||
/*create a DIV element that will contain the items (values):*/
|
||||
parentContainer = document.getElementsByClassName("autocomplete-items-container")[0];
|
||||
parentContainer.setAttribute("id", this.id + "autocomplete-list");
|
||||
|
||||
|
||||
/*for each item in the array...*/
|
||||
Object.keys(passedValues).forEach((el, i, arr) => {
|
||||
|
||||
/*check if the item starts with the same letters as the text field value:*/
|
||||
if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
|
||||
/*create a DIV element for each matching element:*/
|
||||
item = document.createElement("DIV");
|
||||
item.setAttribute("class", "autocomplete-item");
|
||||
// Add the url as an attribute
|
||||
item.setAttribute('url', passedValues[el]);
|
||||
|
||||
/*make the matching letters bold:*/
|
||||
item.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
|
||||
item.innerHTML += arr[i].substr(val.length);
|
||||
/*insert a input field that will hold the current array item's value:*/
|
||||
item.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
|
||||
/*execute a function when someone clicks on the item value (DIV element):*/
|
||||
item.addEventListener("click", function(e) {
|
||||
/*insert the value for the autocomplete text field:*/
|
||||
inp.value = this.getElementsByTagName("input")[0].value;
|
||||
/*close the list of autocompleted values,
|
||||
(or any other open lists of autocompleted values:*/
|
||||
closeAllLists();
|
||||
});
|
||||
parentContainer.appendChild(item);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
/*execute a function presses a key on the keyboard:*/
|
||||
inp.addEventListener("keydown", function(e) {
|
||||
var x = document.getElementById(this.id + "autocomplete-list");
|
||||
if (x) x = x.getElementsByTagName("div");
|
||||
if (e.keyCode == 40) {
|
||||
/*If the arrow DOWN key is pressed,
|
||||
increase the currentFocus variable:*/
|
||||
currentFocus++;
|
||||
/*and and make the current item more visible:*/
|
||||
addActive(x);
|
||||
}
|
||||
else if (e.keyCode == 38) {
|
||||
/*If the arrow UP key is pressed,
|
||||
decrease the currentFocus variable:*/
|
||||
currentFocus--;
|
||||
/*and and make the current item more visible:*/
|
||||
addActive(x);
|
||||
}
|
||||
else if (e.keyCode == 13) {
|
||||
/*If the ENTER key is pressed, prevent the form from being submitted,*/
|
||||
if (currentFocus > -1) {
|
||||
x.preventDefault();
|
||||
/*and simulate a click on the "active" item:*/
|
||||
if (x) window.location = x[0].getAttribute('url');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function addActive(x) {
|
||||
/*a function to classify an item as "active":*/
|
||||
if (!x) return false;
|
||||
/*start by removing the "active" class on all items:*/
|
||||
removeActive(x);
|
||||
if (currentFocus >= x.length) currentFocus = 0;
|
||||
if (currentFocus < 0) currentFocus = (x.length - 1);
|
||||
/*add class "autocomplete-active":*/
|
||||
x[currentFocus].classList.add("autocomplete-active");
|
||||
}
|
||||
|
||||
function removeActive(x) {
|
||||
/*a function to remove the "active" class from all autocomplete items:*/
|
||||
for (var i = 0; i < x.length; i++) {
|
||||
x[i].classList.remove("autocomplete-active");
|
||||
}
|
||||
}
|
||||
|
||||
function closeAllLists(elmnt) {
|
||||
/*close all autocomplete lists in the document,
|
||||
except the one passed as an argument:*/
|
||||
var x = document.getElementsByClassName("autocomplete-item");
|
||||
for (var i = 0; i < x.length; i++) {
|
||||
if (elmnt != x[i] && elmnt != inp) {
|
||||
x[i].parentNode.removeChild(x[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*execute a function when someone clicks in the document:*/
|
||||
document.addEventListener("click", function (e) {
|
||||
closeAllLists(e.target);
|
||||
});
|
||||
}
|
||||
40
js/main.js
40
js/main.js
@@ -1,7 +1,9 @@
|
||||
window.onload = function() {
|
||||
this.initBody()
|
||||
this.initBody();
|
||||
}
|
||||
|
||||
|
||||
debug = false; // Enable while testing on local
|
||||
searchBarDivId = "search-bar"
|
||||
searchBarId = "search-bar-input"
|
||||
messageDivId = "message"
|
||||
@@ -37,6 +39,8 @@ searchEngines = {
|
||||
validWeatherUnit = [
|
||||
"fah", "cel"
|
||||
]
|
||||
validQuickLinks = {}
|
||||
|
||||
|
||||
function initBody() {
|
||||
/**
|
||||
@@ -45,6 +49,12 @@ function initBody() {
|
||||
* Do everything like adding an event listener to
|
||||
* other things.
|
||||
*/
|
||||
// If running on local, just read the conf
|
||||
if (debug) {
|
||||
readJSON("config.json");
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the json file
|
||||
BROWSER.storage.sync.get(result => {
|
||||
Object.keys(result).length == 0 ? readJSON("config.json") : parseAndCreate(result)
|
||||
@@ -64,14 +74,17 @@ function initSearchBar(jsonData) {
|
||||
document.getElementById(searchBarId).addEventListener("keypress", (event) => {
|
||||
if (event.key != 'Enter') return
|
||||
|
||||
// Open google with the search results.
|
||||
// Do whatever the user wants to do
|
||||
query = document.getElementById(searchBarId).value
|
||||
|
||||
// Open settings
|
||||
if (query == "--setting") {
|
||||
showSettings()
|
||||
document.getElementById(searchBarId).value = ""
|
||||
return
|
||||
}
|
||||
|
||||
// If not others, then it's probably a search
|
||||
query = query.replace(/\ /g, "+")
|
||||
document.location = searchUrl + query
|
||||
})
|
||||
@@ -171,6 +184,8 @@ function readJSON(fileName) {
|
||||
}
|
||||
|
||||
function saveSettings(settings) {
|
||||
if (debug) return;
|
||||
|
||||
BROWSER.storage.sync.set(settings)
|
||||
}
|
||||
|
||||
@@ -213,6 +228,10 @@ function parseAndCreate(jsonData) {
|
||||
|
||||
sqrs = jsonData["squares"]
|
||||
|
||||
// Extract the quicklinks from the sqrs
|
||||
extractQuickLinks(sqrs);
|
||||
console.log(validQuickLinks);
|
||||
|
||||
sqrs.forEach((element, index) => {
|
||||
sqr = createSqr(element, index)
|
||||
document.getElementById(otherContentId).appendChild(sqr)
|
||||
@@ -335,4 +354,21 @@ function createClass(color) {
|
||||
document.getElementsByTagName('head')[0].appendChild(style);
|
||||
|
||||
return newClassName;
|
||||
}
|
||||
|
||||
|
||||
function extractQuickLinks(passedSqrs) {
|
||||
/**
|
||||
* Extract the quicklinks passed in the config
|
||||
*
|
||||
* Cache the quicklinks passed by the user in the config JSON
|
||||
* so that they can be used as a shortcut called from the
|
||||
* search bar.
|
||||
*/
|
||||
passedSqrs.forEach(linksContainer => {
|
||||
linksContainer.links.forEach(linkObject => this.validQuickLinks[linkObject.name] = linkObject.url);
|
||||
});
|
||||
|
||||
// Start the autocomplete
|
||||
autocomplete(document.getElementById("search-bar-input"), this.validQuickLinks);
|
||||
}
|
||||
@@ -61,9 +61,12 @@ body {
|
||||
margin: 0 auto 50px auto;
|
||||
height: 45px;
|
||||
padding-top: 35px;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
input {
|
||||
height: inherit;
|
||||
|
||||
#search-bar-input {
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
background: lighten($background, 5);
|
||||
box-shadow: none;
|
||||
@@ -74,12 +77,46 @@ body {
|
||||
padding: 7px 14px;
|
||||
font-size: 18px;
|
||||
color: $foreground;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:focus {
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.autocomplete-items-container {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 99;
|
||||
border-radius: 6px;
|
||||
|
||||
.autocomplete-item {
|
||||
width: 100%;
|
||||
background: lighten($background, 5);
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
text-align: center;
|
||||
outline: none;
|
||||
padding: 7px 14px;
|
||||
font-size: 18px;
|
||||
color: $foreground;
|
||||
box-sizing: border-box;
|
||||
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||
|
||||
&:hover {
|
||||
background-color: red;
|
||||
}
|
||||
}
|
||||
|
||||
.autocomplete-active {
|
||||
background-color: DodgerBlue !important;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 791px) {
|
||||
|
||||
Reference in New Issue
Block a user