Dynamic search
This commit is contained in:
parent
30da722bac
commit
b56da36893
5 changed files with 55 additions and 51 deletions
|
@ -1,4 +1,5 @@
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.core import serializers
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.http import Http404, HttpResponseRedirect, HttpResponseBadRequest, JsonResponse
|
from django.http import Http404, HttpResponseRedirect, HttpResponseBadRequest, JsonResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
@ -62,4 +63,4 @@ def edit(request, boat_id: int):
|
||||||
|
|
||||||
|
|
||||||
def ajax_search(request, text: str):
|
def ajax_search(request, text: str):
|
||||||
return JsonResponse(Boat.objects.filter(Q(name__icontains=text) | Q(description__icontains=text)))
|
return JsonResponse(serializers.serialize("json", Boat.objects.filter(Q(name__icontains=text) | Q(description__icontains=text))), safe=False)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.core import serializers
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.http import Http404, HttpResponseRedirect, HttpResponseBadRequest, JsonResponse
|
from django.http import Http404, HttpResponseRedirect, HttpResponseBadRequest, JsonResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
@ -58,4 +59,4 @@ def edit(request, rescue_id: int):
|
||||||
|
|
||||||
|
|
||||||
def ajax_search(request, text: str):
|
def ajax_search(request, text: str):
|
||||||
return JsonResponse(Rescue.objects.filter(Q(name__icontains=text) | Q(date__icontains=text) | Q(resume__icontains=text)))
|
return JsonResponse(serializers.serialize("json", Rescue.objects.filter(Q(name__icontains=text) | Q(date__icontains=text) | Q(resume__icontains=text))), safe=False)
|
||||||
|
|
|
@ -356,7 +356,7 @@ nav .right .search:hover {
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
-webkit-box-align: center;
|
-webkit-box-align: center;
|
||||||
-ms-flex-align: center;
|
-ms-flex-align: center;
|
||||||
align-items: center;
|
align-items: baseline;
|
||||||
}
|
}
|
||||||
#quicksearch .fast-search .flex-search .search-col {
|
#quicksearch .fast-search .flex-search .search-col {
|
||||||
-webkit-box-flex: 0;
|
-webkit-box-flex: 0;
|
||||||
|
|
49
static/js/search.js
Normal file
49
static/js/search.js
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
let input = document.querySelector(".search-bar input");
|
||||||
|
let typingTimer;
|
||||||
|
let doneTypingInterval = 2000;
|
||||||
|
|
||||||
|
|
||||||
|
input.addEventListener('keyup', () => {
|
||||||
|
clearTimeout(typingTimer);
|
||||||
|
typingTimer = setTimeout(doneTyping, doneTypingInterval);
|
||||||
|
});
|
||||||
|
|
||||||
|
input.addEventListener('keydown', () => {
|
||||||
|
clearTimeout(typingTimer);
|
||||||
|
});
|
||||||
|
|
||||||
|
function httpGetAsync(theUrl, callback)
|
||||||
|
{
|
||||||
|
let xmlHttp = new XMLHttpRequest();
|
||||||
|
xmlHttp.responseType = 'json';
|
||||||
|
|
||||||
|
xmlHttp.onreadystatechange = function() {
|
||||||
|
if (xmlHttp.readyState === 4 && xmlHttp.status === 200)
|
||||||
|
callback(xmlHttp.response);
|
||||||
|
}
|
||||||
|
xmlHttp.open("GET", theUrl, true); // true for asynchronous
|
||||||
|
xmlHttp.send(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertSearch(number, name, id, id_l) {
|
||||||
|
document.querySelectorAll(`#quicksearch > div.fast-search > div > div:nth-child(${number}) div`).forEach(el => el.remove());
|
||||||
|
document.querySelector(`#quicksearch > div.fast-search > div > div:nth-child(${number})`).insertAdjacentHTML("beforeend", `<a href="/${id_l}/${id}/"><div class="search-card">
|
||||||
|
<img src="/static/images/pesquet.jpg">
|
||||||
|
<p class="name">${name}</p>
|
||||||
|
</div></a>`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function doneTyping () {
|
||||||
|
httpGetAsync("/a/ajax/search/"+input.value+"/", j => {
|
||||||
|
for (const i of JSON.parse(j))
|
||||||
|
insertSearch(2, i.fields.name, i.pk, "a")
|
||||||
|
});
|
||||||
|
httpGetAsync("/p/ajax/search/"+input.value+"/", j => {
|
||||||
|
for (const i of JSON.parse(j))
|
||||||
|
insertSearch(1, i.fields.first_name + " " + i.fields.last_name, i.pk, "p")
|
||||||
|
});
|
||||||
|
httpGetAsync("/b/ajax/search/"+input.value+"/", j => {
|
||||||
|
for (const i of JSON.parse(j))
|
||||||
|
insertSearch(3, i.fields.name, i.pk, "b")
|
||||||
|
});
|
||||||
|
}
|
|
@ -12,61 +12,14 @@
|
||||||
<div class="flex-search">
|
<div class="flex-search">
|
||||||
<div class="search-col">
|
<div class="search-col">
|
||||||
<p class="titre">Personnes</p>
|
<p class="titre">Personnes</p>
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/pesquet.jpg' %}">
|
|
||||||
<p class="name">Thomas Pesquet</p>
|
|
||||||
</div>
|
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/pesquet.jpg' %}">
|
|
||||||
<p class="name">Thomas Pesquet</p>
|
|
||||||
</div>
|
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/pesquet.jpg' %}">
|
|
||||||
<p class="name">Thomas Pesquet</p>
|
|
||||||
</div>
|
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/pesquet.jpg' %}">
|
|
||||||
<p class="name">Thomas Pesquet</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="search-col">
|
<div class="search-col">
|
||||||
<p class="titre">Sauvetages</p>
|
<p class="titre">Sauvetages</p>
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/sauvetage.png' %}">
|
|
||||||
<p class="name">Sauvetage risqué en côte d'Ivoire</p>
|
|
||||||
</div>
|
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/sauvetage.png' %}">
|
|
||||||
<p class="name">Sauvetage risqué en côte d'Ivoire</p>
|
|
||||||
</div>
|
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/sauvetage.png' %}">
|
|
||||||
<p class="name">Sauvetage risqué en côte d'Ivoire</p>
|
|
||||||
</div>
|
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/sauvetage.png' %}">
|
|
||||||
<p class="name">Sauvetage risqué en côte d'Ivoire</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="search-col">
|
<div class="search-col">
|
||||||
<p class="titre">Bateaux</p>
|
<p class="titre">Bateaux</p>
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/bateau.jpg' %}">
|
|
||||||
<p class="name">SNS 147</p>
|
|
||||||
</div>
|
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/bateau.jpg' %}">
|
|
||||||
<p class="name">SNS 147</p>
|
|
||||||
</div>
|
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/bateau.jpg' %}">
|
|
||||||
<p class="name">SNS 147</p>
|
|
||||||
</div>
|
|
||||||
<div class="search-card">
|
|
||||||
<img src="{% static 'images/bateau.jpg' %}">
|
|
||||||
<p class="name">SNS 147</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="{% static "js/search.js" %}"></script>
|
||||||
</div>
|
</div>
|
Loading…
Reference in a new issue