mirror of
https://github.com/Floriansylvain/projet_programmation_web.git
synced 2026-08-19 19:53:18 +02:00
✨ Added suggestion feature
This commit is contained in:
+14
-2
@@ -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
@@ -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')
|
||||
});
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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">
|
||||
<button>
|
||||
<img src="assets/search.svg" alt="search">
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<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" id="search-button">
|
||||
</button>
|
||||
</form>
|
||||
<div id="suggestions"></div>
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user