Added suggestion feature

This commit is contained in:
Florian Sylvain
2021-10-31 00:19:53 +02:00
parent 794f4094c9
commit 214ff958aa
5 changed files with 166 additions and 29 deletions
+14 -2
View File
@@ -2,7 +2,19 @@
require_once("class/dump.php");
if (!isset($_GET['q']) || !isset($_GET['author'])) {
print_r(json_encode(array("status" => 400, "message" => "Missing query type or attributs.")));
exit();
}
$author_name = $_GET['author'];
$these_array = dump::getTheseByAuthor($author_name);
$json = json_encode($these_array);
$q = $_GET['q'];
$json_object = match ($q) {
"theses" => dump::getTheseByAuthor($author_name),
"authors" => dump::getAuthorsByAuthors($author_name),
default => NULL,
};
$json = json_encode($json_object);
print_r($json);
+46 -3
View File
@@ -1,14 +1,23 @@
let navbarForm = document.getElementsByClassName('navbar-form')[0]
let searchbar = document.getElementById('searchbar')
let suggestions = document.getElementById('suggestions')
let searchBarButton = document.getElementById('search-button')
let loader = document.getElementsByClassName('loader')[0]
let last = new Date().getTime()
let authorName = "";
function requestToApi(author) {
loader.style.display = "block"
authorName = author
fetch(`api.php?author=${author}`)
fetch(`api.php?q=theses&author=${author}`)
.then(response => response.json())
.then(data => displayResults(data))
}
// TODO : Faire un système de page plutôt que de charger 10000 résultats en une fois s'il y en a 10000..
function displayResults(results) {
document.getElementsByClassName('loader')[0].style.display = "block"
let count = 0
results.forEach(function(elem) {
let result = document.createElement('div')
@@ -26,5 +35,39 @@ function displayResults(results) {
let nb = document.createElement("p")
nb.innerHTML = `Nombre de résultats pour "${authorName}": ${count}.`
document.getElementById('results-count').appendChild(nb)
document.getElementsByClassName('loader')[0].style.display = "none"
loader.style.display = "none"
}
function realTimeDisplay() {
if (last === null || (new Date().getTime() - last) > 500) {
let search = document.getElementsByName("author")[0].value
if (search.length > 3) {
last = new Date().getTime()
fetch(`api.php?q=authors&author=${search}`)
.then(response => response.json())
.then(function(data) {
suggestions.innerHTML = ""
data.forEach(function(elem) {
let name = document.createElement('p')
name.innerHTML = elem
suggestions.appendChild(name)
})
})
}
}
}
searchbar.addEventListener('focus', () => {
navbarForm.style.borderRadius = '15px 15px 0 0'
suggestions.style.display = 'block'
searchBarButton.style.boxShadow = 'none'
searchBarButton.classList.remove('animation-in')
searchBarButton.classList.add('animation-out')
});
searchbar.addEventListener('focusout', () => {
navbarForm.style.borderRadius = '15px'
suggestions.style.display = 'none'
searchBarButton.style.boxShadow = 'rgba(0, 0, 0, 0.15) 4px 2px 5px'
searchBarButton.classList.remove('animation-out')
searchBarButton.classList.add('animation-in')
});
+23
View File
@@ -43,6 +43,29 @@ class dump {
return $theses_array;
}
public static function getAuthorsByAuthors(mixed $author_name) : array {
$array = [];
$author_name = '%' . $author_name . '%';
$pdo_obj = new conf();
$pdo = $pdo_obj->getPDO();
$stmt = $pdo->prepare("SELECT author FROM theses WHERE author LIKE :author_name LIMIT 10;");
$stmt->bindParam(':author_name', $author_name, PDO::PARAM_STR, 100);
$stmt->execute();
$i = 0;
while ($obj = $stmt->fetchObject()) {
foreach ($obj as $elem) {
array_push($array, $elem);
}
$i++;
}
return $array;
}
public function sendThese() {
$data = [
'author' => $this->these->getAuthor(),
+8 -3
View File
@@ -1,11 +1,16 @@
<header>
<nav class="navbar">
<h1>theses.fr</h1>
<form action="index.php" method="GET" class="navbar-input">
<input type="text" name="author" placeholder="nom auteur">
<div class="research-section">
<form action="index.php" method="GET" class="navbar-form">
<input type="text" name="author" placeholder="nom auteur" onkeyup="realTimeDisplay()" id="searchbar">
<button>
<img src="assets/search.svg" alt="search">
<img src="assets/search.svg" alt="search" id="search-button">
</button>
</form>
<div id="suggestions"></div>
</div>
</nav>
</header>
+71 -17
View File
@@ -15,7 +15,8 @@ body {
.navbar {
display: flex;
align-items: center;
gap: 10px;
justify-content: center;
flex-direction: column;
background-color: rgba(57, 180, 231, 0.50);
box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 5px;
height: 75px;
@@ -24,13 +25,17 @@ body {
font-family: sans-serif;
}
.navbar-input {
.research-section {
position: relative;
width: 100%;
}
.navbar-form {
box-shadow: rgba(0, 0, 0, 0.15) 0 2px 5px;
border-radius: 15px;
height: 35px;
height: 40px;
display: flex;
align-items: center;
width: 100%;
background-color: white;
}
@@ -40,44 +45,88 @@ body {
border: none;
height: 100%;
font-size: 18px;
padding: 15px 5px 15px 15px;
padding: 20px 5px 20px 20px;
width: 100%;
}
.navbar img {
background: white;
border-radius: 100px;
width: 50px;
right: 5px;
padding: 10px;
box-shadow: rgba(0, 0, 0, 0.15) 4px 2px 5px;
cursor: pointer;
}
.navbar button {
align-self: center;
height: 60px;
border: none;
background: none;
margin: 0;
padding: 0;
}
.navbar img {
border-radius: 50px;
width: 60px;
padding: 10px;
cursor: pointer;
background-color: white;
box-shadow: rgba(0, 0, 0, 0.15) 4px 2px 5px;
}
.animation-in {
animation: bg-in 70ms linear;
box-shadow: rgba(0, 0, 0, 0.15) 4px 2px 5px;
animation-fill-mode: forwards;
}
.animation-out {
animation: bg-out 70ms linear;
box-shadow: none;
animation-fill-mode: forwards;
}
@keyframes bg-out {
from {background-color: rgba(255, 255, 255, 1.0);}
to {background-color: rgba(255, 255, 255, 0.0);}
}
@keyframes bg-in {
from {background-color: rgba(255, 255, 255, 0.0);}
to {background-color: rgba(255, 255, 255, 1.0);}
}
.navbar h1 {
display: none;
}
#suggestions {
display: none;
position: absolute;
z-index: 10;
background-color: white;
box-shadow: rgba(0, 0, 0, 0.15) 0 5px 5px;
border-radius: 0 0 15px 15px;
padding: 0 10px 10px 10px;
width: 100%;
border: none;
border-top: solid 1px lightgray;
}
#suggestions p {
padding: 10px;
margin: 5px;
border-radius: 10px;
}
#suggestions p:hover {
background-color: rgba(0, 0, 0, 0.05);
}
#results {
font-family: sans-serif;
margin: 10px;
display: flex;
flex-direction: column;
gap: 15px;
overflow: scroll;
}
#results-count {
font-family: sans-serif;
margin: 15px;
opacity: 50%;
margin: 0 0 0 15px;
}
.result-element {
@@ -93,9 +142,14 @@ body {
}
.loader {
display: none;
width: 150px;
height: 150px;
align-self: center;
justify-self: center;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.loader svg {