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>
<div id="map_canvas"></div>
<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">
{% csrf_token %}
<input type="hidden" id="numplaces" name="numplaces" value="{{ numforms }}" />
<div id="places">
{% for form in forms %}
<div class="forms">
{{ form.as_p }}
{% for lieuform in lieuforms %}
<div class="form">
<h3>{{ lieuform.0.name }}</h3>
<p>{{ lieuform.0.ville }}, {{ lieuform.0.get_pays_display }}</p>
{{ lieuform.1.as_p }}
</div>
{% endfor %}
@ -36,6 +40,7 @@
</form>
<script>
var emptyform = "{{ emptyform |safe }}";
var emptylieu = "{{ emptylieu |safe }}";
$(function(){
$("#geocomplete").geocomplete({
map: "#map_canvas",
@ -54,11 +59,19 @@
document.getElementById('id_'+fieldcount+'-pays').value = data.pays;
document.getElementById('id_'+fieldcount+'-latitude').value = data.latitude;
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++;
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;
}
var predata;
@ -81,6 +94,29 @@
data["longitude"] = gdata.geometry.location.lng();
data["latitude"] = gdata.geometry.location.lat();
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>
{% endblock %}

View file

@ -6,6 +6,7 @@ urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^profil/show/(?P<profil_id>\w+)/$', views.profil, name='profil'),
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/new/$', views.stage_add, name='stage_add'),
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.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 import forms
from django.contrib.gis.geos import GEOSGeometry
from django.contrib.gis import measure
from django.forms.widgets import HiddenInput
from monstage.models import *
@ -74,21 +78,24 @@ def stage_edit_desc(request, stage_id):
pass
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):
latitude = forms.DecimalField()
longitude = forms.DecimalField()
delete = forms.BooleanField(help_text=(u'Supprimer ce lieu'), required = False, label = '')
temp_id = forms.IntegerField(required = False)
def __init__(self, *args, **kwargs):
from django.forms.widgets import HiddenInput
super(LieuForm, self).__init__(*args, **kwargs)
self.fields['latitude'].widget = HiddenInput()
self.fields['longitude'].widget = HiddenInput()
self.fields['temp_id'].widget = HiddenInput()
lieu = kwargs.pop('instance', None)
if lieu:
self.fields['temp_id'].initial = lieu.id
self.fields['latitude'].initial = lieu.coord.coords[0]
self.fields['longitude'].initial = lieu.coord.coords[1]
@ -101,52 +108,84 @@ class LieuForm(forms.ModelForm):
def save(self, *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)
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):
stage = get_object_or_404( Stage, pk = stage_id)
bullshit = ''
if stage.profil_user != request.user.profil:
return HttpResponseForbidden("Ce stage ne vous appartient pas")
if request.POST:
i = 0
valid = True
lieux = []
forms = []
for lieustage in stage.lieustage_set.all():
bullshit += str(i) + 'a '
lieuform = LieuForm(request.POST, instance = lieustage.lieu, prefix = str(i))
i = i+1
if not lieuform.is_valid():
valid = False
forms.append(lieuform)
continue
if lieuform.is_to_delete():
prevLieuxStage = [k for k in stage.lieustage_set.all()]
lieuforms = []
deleted = []
for i in range(0, int(request.POST['numplaces'])):
if request.POST.get('%d-name' % i, False): # Lieu a modifier / créer
bullshit += str(i) + 'a '
lieuform = LieuForm(request.POST, prefix = str(i))
if not lieuform.is_valid():
valid = False
lieuforms.append(lieuform)
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()
else:
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,)))
return HttpResponseRedirect(reverse('monstage:stage_edit_feedback', args=(stage.id,)))
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}}')
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 Meta: