Gestion complète des lieux de stages

This commit is contained in:
champeno 2015-06-14 19:13:27 +02:00
parent a6bb3eee17
commit 2fb603c860
4 changed files with 128 additions and 47 deletions

View file

@ -0,0 +1,5 @@
{
"lieux": [ {% for lieu in lieux %} {% if not forloop.first %},{% endif %}
{ "name": "{{ lieu.name }}", "id": "{{ lieu.id }}", "lat": {{ lieu.lat }}, "lon": {{ lieu.lon }}, "distance": "{{ lieu.distance }}" }
{% endfor %} ]
}

View file

@ -19,13 +19,17 @@
<p>{{ debug }}</p> <p>{{ debug }}</p>
<div id="map_canvas"></div> <div id="map_canvas"></div>
<input id="geocomplete" type="text" placeholder="Chercher un établissement" /> <input id="geocomplete" type="text" placeholder="Chercher un établissement" />
<input type="button" value="Ajouter ce lieu" onclick="addFieldSet(predata);" /> <div id="candidats"></div>
<input type="button" value="Créer un nouveau lieu" onclick="addFieldSet(predata);" />
<form action="{% url 'monstage:stage_edit_lieu' stage.id %}" method="post"> <form action="{% url 'monstage:stage_edit_lieu' stage.id %}" method="post">
{% csrf_token %} {% csrf_token %}
<input type="hidden" id="numplaces" name="numplaces" value="{{ numforms }}" />
<div id="places"> <div id="places">
{% for form in forms %} {% for lieuform in lieuforms %}
<div class="forms"> <div class="form">
{{ form.as_p }} <h3>{{ lieuform.0.name }}</h3>
<p>{{ lieuform.0.ville }}, {{ lieuform.0.get_pays_display }}</p>
{{ lieuform.1.as_p }}
</div> </div>
{% endfor %} {% endfor %}
@ -36,6 +40,7 @@
</form> </form>
<script> <script>
var emptyform = "{{ emptyform |safe }}"; var emptyform = "{{ emptyform |safe }}";
var emptylieu = "{{ emptylieu |safe }}";
$(function(){ $(function(){
$("#geocomplete").geocomplete({ $("#geocomplete").geocomplete({
map: "#map_canvas", map: "#map_canvas",
@ -54,11 +59,19 @@
document.getElementById('id_'+fieldcount+'-pays').value = data.pays; document.getElementById('id_'+fieldcount+'-pays').value = data.pays;
document.getElementById('id_'+fieldcount+'-latitude').value = data.latitude; document.getElementById('id_'+fieldcount+'-latitude').value = data.latitude;
document.getElementById('id_'+fieldcount+'-longitude').value = data.longitude; document.getElementById('id_'+fieldcount+'-longitude').value = data.longitude;
// {innerHTML:'<input id="name" type="text" placeholder="Nom de l\'institution" />\n <input id="ville" type="text" placeholder="Ville" />
// <input id="pays" type="text" placeholder="Pays" />
// <input id="latitude" type="hidden" />
// <input id="longitude" type="hidden" />"
fieldcount++; fieldcount++;
document.getElementById('numplaces').value = fieldcount;
predata = undefined;
}
function addKnownPlace(data) {
if (data == undefined) return;
var t = $("<div>")
t.html(emptylieu.replace(/\{\{ID\}\}/gi, fieldcount));
t.prepend($("<h3>", {html:data.name}));
places.append(t);
document.getElementById('id_'+fieldcount+'-lieu_id').value = data.id;
fieldcount++;
document.getElementById('numplaces').value = fieldcount;
predata = undefined; predata = undefined;
} }
var predata; var predata;
@ -81,6 +94,29 @@
data["longitude"] = gdata.geometry.location.lng(); data["longitude"] = gdata.geometry.location.lng();
data["latitude"] = gdata.geometry.location.lat(); data["latitude"] = gdata.geometry.location.lat();
predata = data; predata = data;
getCandidats(data);
}
function getCandidats (data) {
$.getJSON("{% url 'monstage:lieux_candidats' %}", {lat:data.latitude, lon:data.longitude}, showCandidats)
}
function showCandidats (candidats) {
var liste = $("<ul>");
for (var i in candidats.lieux) {
lieu = candidats.lieux[i];
console.log(lieu)
liste.append($("<li>", {html: lieu.name + " ("+lieu.distance+")"}).prop("data", lieu).click(clickCandidat));
}
var candi = $("#candidats");
clearCandidats();
candi.append(liste);
}
function clearCandidats () {
var candi = $("#candidats");
$.each(candi.children(), function(i, item){$(item).remove()});
}
function clickCandidat () {
addKnownPlace(this.data);
clearCandidats();
} }
</script> </script>
{% endblock %} {% endblock %}

View file

@ -6,6 +6,7 @@ urlpatterns = patterns('',
url(r'^$', views.index, name='index'), url(r'^$', views.index, name='index'),
url(r'^profil/show/(?P<profil_id>\w+)/$', views.profil, name='profil'), url(r'^profil/show/(?P<profil_id>\w+)/$', views.profil, name='profil'),
url(r'^profil/edit/$', views.profil_edit, name='profil_edit'), url(r'^profil/edit/$', views.profil_edit, name='profil_edit'),
url(r'^api/lieux/candidats/$', views.lieux_candidats, name='lieux_candidats'),
url(r'^stage/(?P<stage_id>\d+)/$', views.stage, name='stage'), url(r'^stage/(?P<stage_id>\d+)/$', views.stage, name='stage'),
url(r'^stage/new/$', views.stage_add, name='stage_add'), url(r'^stage/new/$', views.stage_add, name='stage_add'),
url(r'^stage/(?P<stage_id>\d+)/edit/$', views.stage_edit, name='stage_edit'), url(r'^stage/(?P<stage_id>\d+)/edit/$', views.stage_edit, name='stage_edit'),

View file

@ -1,9 +1,13 @@
# coding: utf-8
from django.shortcuts import get_object_or_404, render from django.shortcuts import get_object_or_404, render
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden, HttpResponseNotFound
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django import forms from django import forms
from django.contrib.gis.geos import GEOSGeometry from django.contrib.gis.geos import GEOSGeometry
from django.contrib.gis import measure
from django.forms.widgets import HiddenInput
from monstage.models import * from monstage.models import *
@ -74,21 +78,24 @@ def stage_edit_desc(request, stage_id):
pass pass
return render(request, 'monstage/stage_edit_desc.html', { 'stage': stage, 'debug':bullshit }) return render(request, 'monstage/stage_edit_desc.html', { 'stage': stage, 'debug':bullshit })
class LieuStageForm(forms.Form):
lieu_id = forms.IntegerField(widget = HiddenInput())
delete = forms.BooleanField(help_text=(u'Supprimer ce lieu'), required = False, label = '')
def is_to_delete(self):
return self.cleaned_data['delete']
class LieuForm(forms.ModelForm): class LieuForm(forms.ModelForm):
latitude = forms.DecimalField() latitude = forms.DecimalField()
longitude = forms.DecimalField() longitude = forms.DecimalField()
delete = forms.BooleanField(help_text=(u'Supprimer ce lieu'), required = False, label = '') delete = forms.BooleanField(help_text=(u'Supprimer ce lieu'), required = False, label = '')
temp_id = forms.IntegerField(required = False)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
from django.forms.widgets import HiddenInput
super(LieuForm, self).__init__(*args, **kwargs) super(LieuForm, self).__init__(*args, **kwargs)
self.fields['latitude'].widget = HiddenInput() self.fields['latitude'].widget = HiddenInput()
self.fields['longitude'].widget = HiddenInput() self.fields['longitude'].widget = HiddenInput()
self.fields['temp_id'].widget = HiddenInput()
lieu = kwargs.pop('instance', None) lieu = kwargs.pop('instance', None)
if lieu: if lieu:
self.fields['temp_id'].initial = lieu.id
self.fields['latitude'].initial = lieu.coord.coords[0] self.fields['latitude'].initial = lieu.coord.coords[0]
self.fields['longitude'].initial = lieu.coord.coords[1] self.fields['longitude'].initial = lieu.coord.coords[1]
@ -101,52 +108,84 @@ class LieuForm(forms.ModelForm):
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
lieu = super(LieuForm, self).save(commit=False, *args, **kwargs) lieu = super(LieuForm, self).save(commit=False, *args, **kwargs)
lieu.coord = GEOSGeometry('POINT(%f %f)' % (self.cleaned_data['latitude'], self.cleaned_data['latitude']), srid=4326) lieu.coord = GEOSGeometry('POINT(%f %f)' % (self.cleaned_data['latitude'], self.cleaned_data['longitude']), srid=4326)
return lieu.save(*args, **kwargs) return lieu.save(*args, **kwargs)
def lieux_candidats(request):
if request.GET:
lat = float(request.GET.get('lat', False))
lon = float(request.GET.get('lon', False))
if lat and lon:
coords = GEOSGeometry('POINT(%f %f)' % (lat, lon), srid=4326)
distance = {'km': 0.5}
lieux = Lieu.objects.filter(coord__distance_lte=(coords, measure.D(**distance)))
lieux = lieux.distance(coords).order_by('distance')
retour = [ {'name': addslashes(lieu.name), 'id': lieu.id, 'lat':str(lieu.coord.coords[0]), 'lon':str(lieu.coord.coords[1]), 'distance':lieu.distance } for lieu in lieux.distance(coords) ]
return render(request, 'monstage/lieux_proches.json', { 'lieux':retour }, content_type='text/plain; charset=utf-8')
return HttpResponseNotFound()
def stage_edit_lieu(request, stage_id): def stage_edit_lieu(request, stage_id):
stage = get_object_or_404( Stage, pk = stage_id) stage = get_object_or_404( Stage, pk = stage_id)
bullshit = '' bullshit = ''
if stage.profil_user != request.user.profil: if stage.profil_user != request.user.profil:
return HttpResponseForbidden("Ce stage ne vous appartient pas") return HttpResponseForbidden("Ce stage ne vous appartient pas")
if request.POST: if request.POST:
i = 0
valid = True valid = True
lieux = [] prevLieuxStage = [k for k in stage.lieustage_set.all()]
forms = [] lieuforms = []
for lieustage in stage.lieustage_set.all(): deleted = []
bullshit += str(i) + 'a ' for i in range(0, int(request.POST['numplaces'])):
lieuform = LieuForm(request.POST, instance = lieustage.lieu, prefix = str(i)) if request.POST.get('%d-name' % i, False): # Lieu a modifier / créer
i = i+1 bullshit += str(i) + 'a '
if not lieuform.is_valid(): lieuform = LieuForm(request.POST, prefix = str(i))
valid = False if not lieuform.is_valid():
forms.append(lieuform) valid = False
continue lieuforms.append(lieuform)
if lieuform.is_to_delete(): continue
if lieuform.is_to_delete():
pass
else:
lieu = lieuform.save()
if len(prevLieuxStage) > 0:
lieustage = prevLieuxStage.pop(0)
lieustage.lieu = lieu
lieustage.save()
else:
LieuStage.objects.create(lieu = lieu, stage = stage)
lieuforms.append(LieuStageForm(initial = {'lieu_id': lieu.id}, prefix = str(i)))
elif request.POST.get('%d-lieu_id' % i, False): # Lien vers un lieu déjà existant
bullshit += str(i) + 'b '
lieuform = LieuStageForm(request.POST, prefix = str(i))
if not lieuform.is_valid():
bullshit += 'invalid '
valid = False
lieuforms.append(lieuform)
continue
if lieuform.is_to_delete():
if len(prevLieuxStage) > 0:
deleted.append(prevLieuxStage.pop(0))
else:
lieuforms.append(lieuform)
lieu = Lieu.objects.get( pk = lieuform.cleaned_data['lieu_id'] )
if len(prevLieuxStage) > 0:
lieustage = prevLieuxStage.pop(0)
lieustage.lieu = lieu
lieustage.save()
elif len(deleted) > 0:
lieustage = deleted.pop(0)
lieustage.lieu = lieu
lieustage.save()
else:
LieuStage.objects.create(lieu = lieu, stage = stage)
if valid:
for lieustage in deleted:
lieustage.delete() lieustage.delete()
else: return HttpResponseRedirect(reverse('monstage:stage_edit_feedback', args=(stage.id,)))
forms.append(lieuform)
lieux.append(lieuform.save())
while request.POST.get('%d-name' % i, False) and i<20:
bullshit += str(i) + 'b '
lieuform = LieuForm(request.POST, prefix = str(i))
i = i+1
if not lieuform.is_valid():
bullshit += 'invalid '
valid = False
forms.append(lieuform)
continue
if not lieuform.is_to_delete():
forms.append(lieuform)
lieu = lieuform.save(commit = True)
lieux.append(lieu)
LieuStage.objects.create(lieu = lieu, stage = stage)
# if valid:
# return HttpResponseRedirect(reverse('monstage:stage_edit_feedback', args=(new_stage.id,)))
else: else:
forms = [LieuForm(instance=lieu, prefix=str(counter)) for counter, lieu in enumerate(stage.lieux.all())] lieuforms = [(lieu, LieuStageForm(initial={'lieu_id': lieu.id}, prefix=str(counter))) for counter, lieu in enumerate(stage.lieux.all())]
emptyform = LieuForm(prefix='{{ID}}') emptyform = LieuForm(prefix='{{ID}}')
return render(request, 'monstage/stage_edit_lieu.html', { 'stage': stage, 'debug': bullshit, 'forms': forms, 'emptyform': addslashes(emptyform.as_p()), 'numforms':len(forms) }) emptylieu = LieuStageForm(prefix='{{ID}}')
return render(request, 'monstage/stage_edit_lieu.html', { 'stage': stage, 'debug': bullshit, 'lieuforms': lieuforms, 'emptyform': addslashes(emptyform.as_p()), 'emptylieu': addslashes(emptylieu.as_p()), 'numforms':len(lieuforms) })
class StageFeedbackForm(forms.ModelForm): class StageFeedbackForm(forms.ModelForm):
class Meta: class Meta: