added search suggestions and autocomplete
This commit is contained in:
sairaj mote 2020-05-24 22:49:25 +05:30
parent 776f05a318
commit 5a66a46d7d
4 changed files with 187 additions and 148 deletions

View File

@ -1,5 +1,4 @@
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Quicksand:wght@500&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Barlow:wght@500;600;700&family=Roboto:wght@400;500;700&display=swap");
*,
::before,
::after {
@ -15,7 +14,7 @@ body {
--text: 17, 17, 17;
--text-light: 100, 100, 100;
--foreground: 255, 255, 255;
--background: #efefef;
--background: #e8e8e8;
--dark-shade: #dadada;
font-size: 16px;
color: rgba(var(--text), 1);
@ -28,7 +27,7 @@ body[data-theme='dark'] {
--text: 218, 218, 218;
--text-light: 170, 170, 170;
--foreground: 20, 20, 20;
--background: #111;
--background: #0a0a0a;
--dark-shade: #1a1a1a;
}
@ -125,8 +124,7 @@ h3 {
}
.other-font {
font-family: 'Quicksand', sans-serif;
font-weight: 500;
font-family: 'Barlow', sans-serif;
}
.uppercase {
@ -320,19 +318,18 @@ ul .balance:last-of-type {
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
#main_search h1 {
#main_search h2 {
margin-top: 2rem;
-ms-flex-item-align: start;
align-self: flex-start;
margin-top: 2rem;
font-weight: 500;
font-size: 4rem;
letter-spacing: 0.1em;
font-weight: 600;
}
#main_search h3 {
#main_search h4 {
line-height: 1.4em;
margin: 1rem 0 2rem 0;
font-weight: 400;
@ -343,6 +340,51 @@ ul .balance:last-of-type {
border-radius: 0.5rem;
}
#main_search .input input:valid ~ #suggestions {
opacity: 1;
pointer-events: all;
-webkit-transform: none;
transform: none;
}
#main_search label {
position: relative;
}
#main_search #suggestions {
opacity: 0;
pointer-events: none;
-webkit-transform: translateY(-0.5rem);
transform: translateY(-0.5rem);
-webkit-transition: opacity 0.3s, -webkit-transform 0.3s;
transition: opacity 0.3s, -webkit-transform 0.3s;
transition: transform 0.3s, opacity 0.3s;
transition: transform 0.3s, opacity 0.3s, -webkit-transform 0.3s;
position: absolute;
top: 100%;
width: 100%;
background: var(--background);
border-radius: 0.5rem;
padding: 0.5rem 0;
max-height: 20vh;
overflow-y: auto;
margin-top: 0.5rem;
}
#main_search #suggestions:empty {
padding: 0;
}
#main_search .suggestion {
padding: 0.6rem 1.5rem 0.6rem 3rem;
opacity: 0.8;
cursor: pointer;
}
#main_search .suggestion:hover, #main_search .suggestion:focus {
opacity: 1;
}
.input {
position: relative;
display: -ms-grid;
@ -357,7 +399,7 @@ ul .balance:last-of-type {
align-items: center;
padding: 0.8rem;
gap: 1em;
background: rgba(var(--text), 0.1);
background: var(--background);
}
.input input {
@ -370,9 +412,9 @@ ul .balance:last-of-type {
}
.icon {
height: 1.2em;
height: 1.2rem;
overflow: visible;
width: 1.5em;
width: 1.2rem;
fill: none;
stroke: rgba(var(--text), 1);
stroke-linecap: round;
@ -615,8 +657,6 @@ ul .balance:last-of-type {
.page {
padding: 0 0 1rem 0;
-webkit-animation: fade 0.3s;
animation: fade 0.3s;
}
.page h3.heading {

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,4 @@
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@500&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Barlow:wght@500;600;700&family=Roboto:wght@400;500;700&display=swap');
*,
::before,
::after{
@ -13,7 +12,7 @@ body{
--text: 17, 17, 17;
--text-light: 100, 100, 100;
--foreground: 255, 255, 255;
--background: #efefef;
--background: #e8e8e8;
--dark-shade: #dadada;
font-size: 16px;
color: rgba(var(--text), 1);
@ -25,7 +24,7 @@ body[data-theme='dark']{
--text: 218, 218, 218;
--text-light: 170, 170, 170;
--foreground: 20, 20, 20;
--background: #111;
--background: #0a0a0a;
--dark-shade: #1a1a1a;
}
input[type=text]::-ms-clear { display: none; width : 0; height: 0; }
@ -88,8 +87,7 @@ h3{
letter-spacing: 0.06em;
}
.other-font{
font-family: 'Quicksand', sans-serif;
font-weight: 500;
font-family: 'Barlow', sans-serif;
}
.uppercase{
text-transform: uppercase !important;
@ -230,14 +228,14 @@ ul{
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
//text-align: center;
h1{
align-self: flex-start;
h2{
margin-top: 2rem;
font-weight: 500;
align-self: flex-start;
font-size: 4rem;
letter-spacing: 0.1em;
font-weight: 600;
}
h3{
h4{
line-height: 1.4em;
margin: 1rem 0 2rem 0;
font-weight: 400;
@ -245,6 +243,40 @@ ul{
}
.input{
border-radius: 0.5rem;
input:valid ~ #suggestions{
opacity: 1;
pointer-events: all;
transform: none;
}
}
label{
position: relative;
}
#suggestions{
opacity: 0;
pointer-events: none;
transform: translateY(-0.5rem);
transition: transform 0.3s, opacity 0.3s;
position: absolute;
top: 100%;
width: 100%;
background: var(--background);
border-radius: 0.5rem;
padding: 0.5rem 0;
max-height: 20vh;
overflow-y: auto;
&:empty{
padding: 0;
}
margin-top: 0.5rem;
}
.suggestion{
padding: 0.6rem 1.5rem 0.6rem 3rem;
opacity: 0.8;
cursor: pointer;
&:hover, &:focus{
opacity: 1;
}
}
}
.input{
@ -257,7 +289,7 @@ ul{
align-items: center;
padding: 0.8rem;
gap: 1em;
background: rgba(var(--text), 0.1);
background: var(--background);
input{
border: none;
width: 100%;
@ -268,9 +300,9 @@ ul{
}
}
.icon{
height: 1.2em;
height: 1.2rem;
overflow: visible;
width: 1.5em;
width: 1.2rem;
fill: none;
stroke: rgba(var(--text), 1);
stroke-linecap: round;
@ -405,7 +437,6 @@ ul{
}
.page{
padding: 0 0 1rem 0;
animation: fade 0.3s;
h3.heading{
text-transform: capitalize;
font-weight: 500;

View File

@ -86,17 +86,17 @@
</label>
</header>
<div id="main_search">
<h1 class="other-font">FLO SCOUT</h1>
<h3>Search for<br>block, transaction, address,<br>token and contract</h3>
<h2 class="other-font">FLO SCOUT</h2>
<h4>Search for<br>block, transaction, address,<br>token and contract</h4>
<label id="primary_search" class="input">
<svg class="icon" viewBox="0 0 64 64">
<title>search icon</title>
<circle cx="25.34" cy="25.34" r="24.84"/>
<line x1="63.65" y1="63.65" x2="42.91" y2="42.91"/>
</svg>
<input id='main-search-text' type="search" placeholder="Search">
<input id='main_search_field' autocomplete="off" type="search" placeholder="Search" required>
<ul id="suggestions"></ul>
</label>
<div id="suggetions"></div>
</div>
<div id="highlights">
<div class="highlight-item">
@ -279,7 +279,7 @@
page.id = "contract_page";
page.innerHTML = `
<div class="status closed">Closed</div>
<h2 class="uppercase">${contract}</h2>
<h3 class="uppercase">${contract}</h3>
<div class="card">
<h5 class="label">Contract Type</h5>
<h4>${contractType}</h4>
@ -500,7 +500,7 @@
let addressTxs = await getAddressTxs(field);*/
let [addressInfo, addressBalance, addressTxs] = await Promise.all([getAddressInfo(field), getAddressBalance(field), getAddressTxs(field)])
console.log(addressInfo, addressBalance, addressTxs)
pageContainer.append(create.addressPage({balance: addressBalance, address: field}))
pageContainer.append(create.addressPage({balance: addressBalance, address: -field}))
pageTitle.textContent = 'Address'
loading()
}
@ -565,7 +565,7 @@
loading();
// add event listener to input dialog box
document.getElementById("main-search-text").addEventListener("keydown", function (e) {
document.getElementById("main_search_field").addEventListener("keydown", function (e) {
if (e.key === 'Enter') { //checks whether the pressed key is "Enter"
processNavbarSearch();
}
@ -596,6 +596,8 @@
}
});
getAllSuggestions()
latestTxs.forEach(tx => {
if (tx["type"] == "tokentransfer")
frag.append(create.tokenTransferCard(tx))
@ -636,7 +638,7 @@
render("homepage");
history.pushState(appState, null, null);
document.querySelector("main").addEventListener("click", (e) => {
this.addEventListener("click", (e) => {
if (e.target.closest(".address") && prevField !== e.target.textContent) {
render("address_page", e.target.textContent)
appState = {
@ -674,13 +676,43 @@
if (e.target.closest(".tab")) {
showTab(e.target.closest(".tab"));
}
if (e.target.closest("#secondary_search")) {
render("homepage");
document.getElementById("primary_search").click();
if (e.target.closest("#secondary_search_btn")) {
render("homepage")
//document.getElementById("primary_search").click();
}
if(e.target.closest('.suggestion')){
let searchBox = document.getElementById('main_search_field');
searchBox.value = e.target.textContent;
processNavbarSearch()
}
});
});
window.addEventListener('keyup', e => {
if(e.target.closest('.suggestion') && e.key === 'Enter'){
processNavbarSearch()
}
if(e.target.closest('.suggestion') && e.key === 'Tab'){
let searchBox = document.getElementById('main_search_field');
searchBox.value = e.target.textContent;
}
if(e.target.closest('#main_search_field')){
let results = index.search(e.target.value, 25),
entry, childs = suggestions.childNodes,
i = 0, len = results.length;
for (; i < len; i++) {
entry = childs[i];
if (!entry && data[results[i]]) {
suggestions.append(suggestion(data[results[i]]))
}
}
while (childs.length > len) {
suggestions.removeChild(childs[i])
}
suggestions.append(frag)
}
})
let tabMounted = false;
function showTab(tab) {
let targetTab = tab.getAttribute('data-target'),
@ -1552,53 +1584,50 @@
//console.log('data entered is noise')
}
//document.getElementById('main-search-text').value = '';
}
}
function processNavbarSearch() {
userinput = document.getElementById('main-search-text');
console.log(userinput.value);
userinput = document.getElementById('main_search_field');
if (userinput.value != '') {
categoriseText(userinput.value, userinput);
}
}
function runScriptJs() {
var $cell = $('.card');
// function runScriptJs() {
// var $cell = $('.card');
//open and close card when clicked on card
$cell.find('.js-expander').click(function () {
// //open and close card when clicked on card
// $cell.find('.js-expander').click(function () {
var $thisCell = $(this).closest('.card');
// var $thisCell = $(this).closest('.card');
if ($thisCell.hasClass('is-collapsed')) {
$cell.not($thisCell).removeClass('is-expanded').addClass('is-collapsed').addClass('is-inactive');
$thisCell.removeClass('is-collapsed').addClass('is-expanded');
// if ($thisCell.hasClass('is-collapsed')) {
// $cell.not($thisCell).removeClass('is-expanded').addClass('is-collapsed').addClass('is-inactive');
// $thisCell.removeClass('is-collapsed').addClass('is-expanded');
if ($cell.not($thisCell).hasClass('is-inactive')) {
//do nothing
} else {
$cell.not($thisCell).addClass('is-inactive');
}
// if ($cell.not($thisCell).hasClass('is-inactive')) {
// //do nothing
// } else {
// $cell.not($thisCell).addClass('is-inactive');
// }
} else {
$thisCell.removeClass('is-expanded').addClass('is-collapsed');
$cell.not($thisCell).removeClass('is-inactive');
}
});
// } else {
// $thisCell.removeClass('is-expanded').addClass('is-collapsed');
// $cell.not($thisCell).removeClass('is-inactive');
// }
// });
//close card when click on cross
$cell.find('.js-collapser').click(function () {
// //close card when click on cross
// $cell.find('.js-collapser').click(function () {
var $thisCell = $(this).closest('.card');
// var $thisCell = $(this).closest('.card');
$thisCell.removeClass('is-expanded').addClass('is-collapsed');
$cell.not($thisCell).removeClass('is-inactive');
// $thisCell.removeClass('is-expanded').addClass('is-collapsed');
// $cell.not($thisCell).removeClass('is-inactive');
});
}
// });
// }
// First load
@ -1606,8 +1635,9 @@
// loading of global variables which contains name of all tokens and smart contracts
var data = [];
fetch(`${window.tokenapiUrl}/api/v1.0/getTokenSmartContractList`)
function getAllSuggestions(){
window.data = [];
fetch(`${window.tokenapiUrl}/api/v1.0/getTokenSmartContractList`)
.then(function (response) {
return response.json();
})
@ -1626,7 +1656,6 @@
data.push(ranchimallflo.smartcontractlist[i]['contractName']);
ranchimallflo.smartcontractnamelist.push(ranchimallflo.smartcontractlist[i]['contractName']);
ranchimallflo.smartcontractnameaddresslist.push(ranchimallflo.smartcontractlist[i]['contractName'] + '-' + ranchimallflo.smartcontractlist[i]['contractAddress']);
}
for (var i = 0; i < ranchimallflo.tokenlist.length; i++) {
@ -1634,8 +1663,7 @@
data.push(ranchimallflo.tokenlist[i]);
}
var index = new FlexSearch({
window.index = new FlexSearch({
encode: "advanced",
tokenize: "reverse",
suggest: true
@ -1645,76 +1673,16 @@
index.add(i, data[i]);
}
var suggestions = document.getElementById("suggestions");
var autocomplete = document.getElementById("autocomplete");
var userinput = document.getElementById("userinput");
//userinput.addEventListener("input", show_results, true);
//userinput.addEventListener("keyup", accept_autocomplete, true);
//suggestions.addEventListener("click", accept_suggestion, true);
function show_results() {
var value = this.value;
var results = index.search(value, 25);
var entry, childs = suggestions.childNodes;
var i = 0, len = results.length;
for (; i < len; i++) {
entry = childs[i];
if (!entry) {
entry = document.createElement("div");
suggestions.appendChild(entry);
}
entry.textContent = data[results[i]];
}
while (childs.length > len) {
suggestions.removeChild(childs[i])
}
var first_result = data[results[0]];
var match = first_result && first_result.toLowerCase().indexOf(value.toLowerCase());
if (first_result && (match !== -1)) {
autocomplete.value = value + first_result.substring(match + value.length);
autocomplete.current = first_result;
}
else {
autocomplete.value = autocomplete.current = value;
}
}
function accept_autocomplete(event) {
if ((event || window.event).keyCode === 13) {
this.value = autocomplete.value = autocomplete.current;
}
}
function accept_suggestion(event) {
var target = (event || window.event).target;
userinput.value = autocomplete.value = target.textContent;
while (suggestions.lastChild) {
suggestions.removeChild(suggestions.lastChild);
}
return false;
window.suggestion = function(str){
let li = document.createElement('li')
li.textContent = str
li.tabIndex = 0
li.classList.add('suggestion')
return li;
}
});
}
</script>
</body>