Résultats de recherche beaucoup presque au point
This commit is contained in:
parent
647f106632
commit
c9beee1f29
12 changed files with 246 additions and 87 deletions
|
@ -143,4 +143,8 @@ section.content.recherche {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#carte {
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1249,6 +1249,11 @@ section.content.recherche .vue-options ul li {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
/* line 146, ../../sass/_recherche.scss */
|
||||||
|
section.content.recherche #carte {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 850px) {
|
@media screen and (max-width: 850px) {
|
||||||
/* line 2, ../../sass/_responsive.scss */
|
/* line 2, ../../sass/_responsive.scss */
|
||||||
|
|
101
avisstage/static/js/recherche.js
Normal file
101
avisstage/static/js/recherche.js
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
function InterfaceRecherche(STATIC_ROOT, API_LIEU, lieux) {
|
||||||
|
var interface_mode, main_container;
|
||||||
|
var lieux_map = {}, lieux_list = [];
|
||||||
|
var stages_data = {};
|
||||||
|
|
||||||
|
function initInterface() {
|
||||||
|
main_container = $(".content.recherche");
|
||||||
|
if (main_container.hasClass("vue-liste")) {
|
||||||
|
interface_mode = "liste";
|
||||||
|
} else if (main_container.hasClass("vue-carte")) {
|
||||||
|
interface_mode = "carte";
|
||||||
|
} else {
|
||||||
|
interface_mode = "hybride";
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(lieux, function(i, item) {
|
||||||
|
var stage_id = item[0];
|
||||||
|
var lieu_id = item[1];
|
||||||
|
if (lieux_map[lieu_id]==undefined) {
|
||||||
|
lieux_map[lieu_id] = [];
|
||||||
|
lieux_list.push(lieu_id);
|
||||||
|
}
|
||||||
|
lieux_map[lieu_id].push(stage_id);
|
||||||
|
});
|
||||||
|
|
||||||
|
changeInterface(interface_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeInterface(mode) {
|
||||||
|
interface_mode = mode;
|
||||||
|
if (mode=="hybride" || mode=="carte") {
|
||||||
|
initCarte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carte
|
||||||
|
|
||||||
|
var map;
|
||||||
|
function initCarte() {
|
||||||
|
if (map !== undefined) return;
|
||||||
|
map = L.map("carte").panTo([30, 15]).setZoom(1);
|
||||||
|
var layer = new L.TileLayer("https://korona.geog.uni-heidelberg.de/tiles/roads/x={x}&y={y}&z={z}", {attribution: 'Map tiles by <a href="http://korona.geog.uni-heidelberg.de/">GIScience Heidelberg</a>'});
|
||||||
|
map.addLayer(layer);
|
||||||
|
|
||||||
|
$.getJSON(API_LIEU + "set/"+lieux_list.join(';')+"/?format=json", onLoadLieux);
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeIcon(couleur){
|
||||||
|
return L.icon({
|
||||||
|
iconUrl: STATIC_ROOT + 'images/marker-'+couleur+'.png',
|
||||||
|
iconSize: [36, 46],
|
||||||
|
iconAnchor: [18, 45],
|
||||||
|
popupAnchor: [0, -48]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var greenIcon = makeIcon('red');
|
||||||
|
|
||||||
|
var marqueurs = L.markerClusterGroup();
|
||||||
|
var marqueurs_db = {};
|
||||||
|
|
||||||
|
function onLoadLieux(data){
|
||||||
|
console.log(data);
|
||||||
|
var lieux = data.objects;
|
||||||
|
$.each(lieux, function(i, item) {
|
||||||
|
var marqueur = L.marker(item.coord, {icon: greenIcon});
|
||||||
|
var txt = item.num_stages > 1 ? item.num_stages+" stages ici": "1 stage ici";
|
||||||
|
txt = "<h3>"+item.nom+"</h3>"+
|
||||||
|
"<p>"+txt+"</p>";
|
||||||
|
marqueur.bindPopup(txt + "<p>Chargement...</p>");
|
||||||
|
marqueurs.addLayer(marqueur);
|
||||||
|
marqueur.on("popupopen", showDetailLieu);
|
||||||
|
marqueur._lieu_data = item;
|
||||||
|
marqueur._popup_header = txt;
|
||||||
|
marqueur._lieu_data_loading = false;
|
||||||
|
marqueurs_db[item.id] = marqueur;
|
||||||
|
});
|
||||||
|
map.addLayer(marqueurs);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showDetailLieu(){
|
||||||
|
var data = this._lieu_data;
|
||||||
|
var marqueur = marqueurs_db[data.id];
|
||||||
|
marqueur._lieu_data = data;
|
||||||
|
var html = $("<div>").html(marqueur._popup_header);
|
||||||
|
var stageliste = $("<ul>");
|
||||||
|
$.each(lieux_map[data.id], function(i, item) {
|
||||||
|
var stage_el = $("#resultat-stage-"+item);
|
||||||
|
var url = stage_el.find('a.stage-sujet').attr('href');
|
||||||
|
var sujet = stage_el.find('a.stage-sujet').text();
|
||||||
|
var auteur = stage_el.find('.auteur').text();
|
||||||
|
var stage = $("<li>")
|
||||||
|
.append($("<a>", {href: url}).text(sujet))
|
||||||
|
.append($("<span>").text(" par "+auteur));
|
||||||
|
stageliste.append(stage);
|
||||||
|
});
|
||||||
|
html.append(stageliste);
|
||||||
|
marqueur.setPopupContent(html[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
initInterface();
|
||||||
|
}
|
|
@ -26,7 +26,7 @@
|
||||||
<img src="{% static 'images/home2.jpg' %}"/>
|
<img src="{% static 'images/home2.jpg' %}"/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>Ne partez plus en stage en terre inconnue : nourrissez-vous de l'expérience des séjours effectués par la communauté normalienne, repérez les bons plans, et ne faites pas les mêmes erreurs !</p>
|
<p>Ne partez plus en stage en terre inconnue : nourrissez-vous des {{ num_stages }} expériences de séjours effectués par la communauté normalienne, repérez les bons plans, et ne faites pas les mêmes erreurs !</p>
|
||||||
{% if user.is_authenticated %}<p><a href="{% url 'avisstage:recherche' %}" class="btn">Rechercher des stages</a></p>{% endif %}
|
{% if user.is_authenticated %}<p><a href="{% url 'avisstage:recherche' %}" class="btn">Rechercher des stages</a></p>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
{% extends "avisstage/base.html" %}
|
|
||||||
{% load staticfiles %}
|
|
||||||
|
|
||||||
{% block title %}Chercher un stage - ExperiENS{% endblock %}
|
|
||||||
|
|
||||||
{% block extra_content_class %}recherche {{ vue }}{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<section class="recherche-liste">
|
|
||||||
<h1>Recherche</h1>
|
|
||||||
<form class="recherche" method="GET" action="">
|
|
||||||
<div>
|
|
||||||
<p class="generale">
|
|
||||||
<span>
|
|
||||||
{{ form.generique }}
|
|
||||||
<input type="submit" action="submit" value="Chercher un stage"/>
|
|
||||||
</span>
|
|
||||||
<a class="toggle_avancee" href="#" onclick="$('#recherche_avancee').toggleClass('expanded'); return false;">Recherche avancée</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="avancee" id="recherche_avancee">
|
|
||||||
<p class="help_text">Le champ principal (ci-dessus) est aussi utilisé dans la recherche, ces champs ne servent qu'à filtrer plus précisément</p>
|
|
||||||
<ul>
|
|
||||||
{% for field in form %}
|
|
||||||
{% if field != form.generique %}
|
|
||||||
<li class="field__{{ field.name }}">
|
|
||||||
{% if field.label %}{{ field.label_tag }}{% endif %}
|
|
||||||
{{ field }}
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
<li class="btnsubmit">
|
|
||||||
<input type="submit" action="submit" value="Chercher un stage"/>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<article class="resultslist">
|
|
||||||
<h2>Résultats de la recherche</h2>
|
|
||||||
<div id="vue-options" class="vue-options">
|
|
||||||
<ul>
|
|
||||||
<li>Affichage :</li>
|
|
||||||
<li><a href="javascript:void(0);" id="display_list">Liste</a></li>
|
|
||||||
<li><a href="javascript:void(0);" id="display_hybrid">Hybride</a></li>
|
|
||||||
<li><a href="javascript:void(0);" id="display_map">Carte</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<ul class="stage-liste">
|
|
||||||
{% for stage in stages %}
|
|
||||||
{% if tri == '-date_maj' %}
|
|
||||||
{% ifchanged stage.date_maj.date %}<li class="date-maj">Mis à jour le {{ stage.date_maj.date }}</li>{% endifchanged %}
|
|
||||||
{% endif %}
|
|
||||||
<li class="stage">
|
|
||||||
<div class="misc-hdr">
|
|
||||||
<h3><a href="{% url "avisstage:stage" stage.id %}">{{ stage.sujet }}</a><span class="auteur"> par <a href="{% url "avisstage:profil" stage.auteur.user.username %}">{{ stage.auteur.nom }}</a></span></h3>
|
|
||||||
<p class="dates"><span class="detail"><span class="debut">{{ stage.date_debut|date:"d/m" }}</span><span class="fin">{{ stage.date_fin|date:"d/m" }}</span></span><span class="year">{{ stage.date_debut|date:"Y" }}</span></p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<ul class="infos">
|
|
||||||
<li class="type">{{ stage.get_type_stage_display }}</li>
|
|
||||||
<li class="structure">{{ stage.structure }}</li>
|
|
||||||
{% for lieu in stage.lieux.all %}<li class="lieu">{{ lieu.nom }}</li>{% endfor %}
|
|
||||||
{% for matiere in stage.matieres.all %}
|
|
||||||
<li class="matiere">{{ matiere.nom }}</li>
|
|
||||||
{% endfor %}
|
|
||||||
{% for thematique in stage.thematiques.all %}
|
|
||||||
<li class="thematique">{{ thematique.name }}</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{% empty %}
|
|
||||||
<li class="stage">Aucun stage ne correspond à votre recherche et vos critères</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</article>
|
|
||||||
</section>
|
|
||||||
<section class="recherche-carte">
|
|
||||||
|
|
||||||
</section>
|
|
||||||
{% endblock %}
|
|
27
avisstage/templates/avisstage/recherche/formulaire.html
Normal file
27
avisstage/templates/avisstage/recherche/formulaire.html
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<form class="recherche" method="GET" action="{% url 'avisstage:recherche_resultats' %}">
|
||||||
|
<div>
|
||||||
|
<p class="generale">
|
||||||
|
<span>
|
||||||
|
{{ form.generique }}
|
||||||
|
<input type="submit" action="submit" value="Chercher un stage"/>
|
||||||
|
</span>
|
||||||
|
<a class="toggle_avancee" href="#" onclick="$('#recherche_avancee').toggleClass('expanded'); return false;">Recherche avancée</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="avancee" id="recherche_avancee">
|
||||||
|
<p class="help_text">Le champ principal (ci-dessus) est aussi utilisé dans la recherche, ces champs ne servent qu'à filtrer plus précisément</p>
|
||||||
|
<ul>
|
||||||
|
{% for field in form %}
|
||||||
|
{% if field != form.generique %}
|
||||||
|
<li class="field__{{ field.name }}">
|
||||||
|
{% if field.label %}{{ field.label_tag }}{% endif %}
|
||||||
|
{{ field }}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<li class="btnsubmit">
|
||||||
|
<input type="submit" action="submit" value="Chercher un stage"/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</form>
|
14
avisstage/templates/avisstage/recherche/recherche.html
Normal file
14
avisstage/templates/avisstage/recherche/recherche.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends "avisstage/base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
|
||||||
|
{% block title %}Chercher un stage - ExperiENS{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_content_class %}recherche{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Chercher un stage</h1>
|
||||||
|
{% include "avisstage/recherche/formulaire.html" with form=form %}
|
||||||
|
<h2>Ou alors</h2>
|
||||||
|
<p><a href="{% url 'avisstage:recherche_resultats' %}?vue=carte">Afficher la carte de tous les stages</a></p>
|
||||||
|
<p><a href="{% url 'avisstage:recherche_resultats' %}?vue=liste&tri=-date_maj">Afficher les dernières mises à jour</a></p>
|
||||||
|
{% endblock %}
|
78
avisstage/templates/avisstage/recherche/resultats.html
Normal file
78
avisstage/templates/avisstage/recherche/resultats.html
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
{% extends "avisstage/base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
|
||||||
|
{% block title %}Chercher un stage - ExperiENS{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_head %}
|
||||||
|
<script type="text/javascript" src="{% static 'js/leaflet.js' %}"></script>
|
||||||
|
<script type="text/javascript" src="{% static 'js/leaflet.markercluster.js' %}"></script>
|
||||||
|
<script type="text/javascript" src="{% static 'js/recherche.js' %}"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'css/leaflet.css' %}" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'css/MarkerCluster.css' %}" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'css/MarkerCluster.Default.css' %}" />
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_content_class %}recherche {{ vue }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<section class="recherche-liste" id="recherche-liste">
|
||||||
|
{% include "avisstage/recherche/formulaire.html" with form=form %}
|
||||||
|
|
||||||
|
<article class="resultslist">
|
||||||
|
<h2>Résultats de la recherche</h2>
|
||||||
|
{% if stages %}
|
||||||
|
<div id="vue-options" class="vue-options">
|
||||||
|
<ul>
|
||||||
|
<li>Affichage :</li>
|
||||||
|
<li><a href="javascript:void(0);" id="display_list">Liste</a></li>
|
||||||
|
<li><a href="javascript:void(0);" id="display_hybrid">Hybride</a></li>
|
||||||
|
<li><a href="javascript:void(0);" id="display_map">Carte</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<p class="numresults">{{ stages|length }} expérience{{ stages|length|pluralize }} trouvée{{ stages|length|pluralize }}</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<ul class="stage-liste" id="resultats">
|
||||||
|
{% for stage in stages %}
|
||||||
|
{% if tri == '-date_maj' %}
|
||||||
|
{% ifchanged stage.date_maj.date %}<li class="date-maj">Mis à jour le {{ stage.date_maj.date }}</li>{% endifchanged %}
|
||||||
|
{% endif %}
|
||||||
|
<li class="stage" id="resultat-stage-{{ stage.id }}">
|
||||||
|
<div class="misc-hdr">
|
||||||
|
<h3><a href="{% url "avisstage:stage" stage.id %}" class="stage-sujet">{{ stage.sujet }}</a><span class="auteur"> par <a href="{% url "avisstage:profil" stage.auteur.user.username %}" class="stage-auteur">{{ stage.auteur.nom }}</a></span></h3>
|
||||||
|
<p class="dates"><span class="detail"><span class="debut">{{ stage.date_debut|date:"d/m" }}</span><span class="fin">{{ stage.date_fin|date:"d/m" }}</span></span><span class="year">{{ stage.date_debut|date:"Y" }}</span></p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<ul class="infos">
|
||||||
|
<li class="type">{{ stage.get_type_stage_display }}</li>
|
||||||
|
<li class="structure">{{ stage.structure }}</li>
|
||||||
|
{% for lieu in stage.lieux.all %}<li class="lieu">{{ lieu.nom }}</li>{% endfor %}
|
||||||
|
{% for matiere in stage.matieres.all %}
|
||||||
|
<li class="matiere">{{ matiere.nom }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% for thematique in stage.thematiques.all %}
|
||||||
|
<li class="thematique">{{ thematique.name }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
{% empty %}
|
||||||
|
<li class="stage">Aucun stage ne correspond à votre recherche et vos critères</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{% if lieux %}
|
||||||
|
<section class="recherche-carte" id="recherche-carte">
|
||||||
|
<div id="carte"></div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var lieux = [{{ lieux|join:',' }}];
|
||||||
|
var interfaceRecherche = new InterfaceRecherche("{{ STATIC_URL|escapejs }}", "{% url 'avisstage:api_dispatch_list' resource_name="lieu" api_name="v1" %}", lieux);
|
||||||
|
</script>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
|
@ -22,6 +22,7 @@ urlpatterns = [
|
||||||
name='profil'),
|
name='profil'),
|
||||||
url(r'^profil/edit/$', views.ProfilEdit.as_view(), name='profil_edit'),
|
url(r'^profil/edit/$', views.ProfilEdit.as_view(), name='profil_edit'),
|
||||||
url(r'^recherche/$', views.recherche, name='recherche'),
|
url(r'^recherche/$', views.recherche, name='recherche'),
|
||||||
|
url(r'^recherche/resultats/$', views.recherche_resultats, name='recherche_resultats'),
|
||||||
url(r'^feedback/$', views.feedback, name='feedback'),
|
url(r'^feedback/$', views.feedback, name='feedback'),
|
||||||
url(r'^api/', include(v1_api.urls)),
|
url(r'^api/', include(v1_api.urls)),
|
||||||
]
|
]
|
||||||
|
|
|
@ -24,7 +24,9 @@ import random, math
|
||||||
|
|
||||||
# Page d'accueil
|
# Page d'accueil
|
||||||
def index(request):
|
def index(request):
|
||||||
return render(request, 'avisstage/index.html')
|
num_stages = Stage.objects.filter(public=True).count()
|
||||||
|
return render(request, 'avisstage/index.html',
|
||||||
|
{"num_stages": num_stages})
|
||||||
|
|
||||||
# Espace personnel
|
# Espace personnel
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -56,7 +58,7 @@ class StageView(LoginRequiredMixin, DetailView):
|
||||||
#login_required
|
#login_required
|
||||||
class StageListe(LoginRequiredMixin, ListView):
|
class StageListe(LoginRequiredMixin, ListView):
|
||||||
model = Stage
|
model = Stage
|
||||||
template_name = 'avisstage/liste/stage.html'
|
template_name = 'avisstage/recherche/stage.html'
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return Stage.objects.filter(public=True).order_by('-date_maj')
|
return Stage.objects.filter(public=True).order_by('-date_maj')
|
||||||
|
|
|
@ -124,17 +124,25 @@ def cherche(**kwargs):
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def recherche(request):
|
def recherche(request):
|
||||||
|
form = SearchForm()
|
||||||
|
return render(request, 'avisstage/recherche/recherche.html',
|
||||||
|
{"form": form})
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def recherche_resultats(request):
|
||||||
stages = []
|
stages = []
|
||||||
tri = ''
|
tri = ''
|
||||||
vue = 'vue-liste'
|
vue = 'vue-liste'
|
||||||
|
lieux = []
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
form = SearchForm(request.GET)
|
form = SearchForm(request.GET)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
stages, tri = cherche(**form.cleaned_data)
|
stages, tri = cherche(**form.cleaned_data)
|
||||||
|
lieux = map(list, stages.values_list('id', 'lieux'))
|
||||||
else:
|
else:
|
||||||
form = SearchForm()
|
form = SearchForm()
|
||||||
if stages:
|
if stages:
|
||||||
vue = 'vue-hybride'
|
vue = 'vue-hybride'
|
||||||
return render(request, 'avisstage/liste/recherche_resultats.html',
|
return render(request, 'avisstage/recherche/resultats.html',
|
||||||
{"form": form, "stages":stages,
|
{"form": form, "stages":stages,
|
||||||
"tri": tri, "vue": vue})
|
"tri": tri, "vue": vue, "lieux": lieux})
|
||||||
|
|
Loading…
Reference in a new issue