search prototipo

This commit is contained in:
Guido García 2022-08-26 22:55:17 +02:00
parent 99330e27f4
commit f9bf3acce8
5 changed files with 120 additions and 1 deletions

View File

@ -10,7 +10,9 @@
<html>
<head>
<title>{% if title %}{{ title }} - {% endif %}Observatorio de seguridad web</title>
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://stats.pucelabits.org; font-src 'self'; img-src 'self' https://stats.pucelabits.org; object-src 'none'; script-src 'self' https://stats.pucelabits.org; style-src 'self'; frame-ancestors 'none'">
<!-- TODO reenable CSP
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://stats.pucelabits.org; font-src 'self'; img-src 'self' https://stats.pucelabits.org; object-src 'none'; script-src 'self' 'nonce-search' https://stats.pucelabits.org; style-src 'self'; frame-ancestors 'none'">
-->
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
<meta property="og:type" content="website">

0
assets/js/searchbox.js Normal file
View File

View File

@ -5,6 +5,7 @@
@import "libs/breakpoints";
@import "libs/html-grid";
@import "fontawesome-all.min.css";
@import "searchbox.css";
/*
Phantom by HTML5 UP

52
assets/sass/searchbox.css Normal file
View File

@ -0,0 +1,52 @@
.search-input input {
color: black;
outline: none;
border: 1px solid darkgray;
width: 100%;
}
.search-input.active input {
border-radius: 5px 5px 0 0;
}
.search-input .autocom-box {
position: absolute;
padding: 0;
opacity: 0;
pointer-events: none;
max-height: 280px;
overflow-y: auto;
border-radius: 0 0 5px 5px;
}
.search-input.active .autocom-box {
background-color: #ffc;
color: black;
z-index: 9999;
padding: 10px 8px;
opacity: 1;
pointer-events: auto;
}
.autocom-box li {
list-style: none;
padding: 8px 12px;
display: none;
width: 100%;
cursor: default;
border-radius: 3px;
}
.search-input.active .autocom-box li {
display: block;
}
.autocom-box li:hover {
background: #f56a6a;
color: white;
cursor: pointer;
}
.autocom-box li.notfound {
cursor: default;
}

64
pages/search.njk Normal file
View File

@ -0,0 +1,64 @@
---
layout: base
permalink: "/search/"
title: "Buscador"
---
{#
INIT SEARCH
Local search, no backend involved.
XXX this could go in the header.
XXX this could be a macro or something like that to import it from the pages that need the search box.
#}
<div class="search-input">
<a href="#" class="hidden" hidden aria-hidden="true">enlace dinámico</a>
<input id="search" autocomplete="false" role="search" title="Nombre del sitio que quieres buscar" type="search" placeholder="Busca entre los {{ all | length }} sitios...">
<div class="autocom-box">
</div>
</div>
<script nonce="search">
let suggestions = [
{% for site in all %}{"name": "{{ site.name }} ({{ site.territorio }})", "href": "/w/{{ site.url | replace(".", "!") }}"}{{',' if not loop.last}}{% endfor %}
];
const searchWrapper = document.querySelector(".search-input");
const inputBox = searchWrapper.querySelector("input");
const suggestionBox = searchWrapper.querySelector(".autocom-box");
const icon = searchWrapper.querySelector(".icon");
let linkTag = searchWrapper.querySelector("a");
inputBox.onkeyup = (e) => {
const userData = e.target.value;
if (userData) {
const list = suggestions.filter((data) => data.name.toLowerCase().includes(userData.toLowerCase()))
.map((data) => '<li class="whitespace-nowrap" onclick="select(this)">' + data.name + '</li>');
searchWrapper.classList.add("active");
showSuggestions(list);
} else {
searchWrapper.classList.remove("active");
}
}
function select(element) {
const selectData = element.textContent;
inputBox.value = selectData;
const site = suggestions.find((data) => data.name === selectData);
if (site) {
searchWrapper.classList.remove("active");
linkTag.setAttribute("href", site.href);
linkTag.click();
}
}
function showSuggestions(list) {
let listData;
if (!list.length) {
userValue = inputBox.value;
listData = '<li class="notfound">No encuentro ningún resultado</li>';
} else {
listData = list.join('');
}
suggestionBox.innerHTML = listData;
}
</script>
{# END SEARCH #}