WIP: interface de saisie de la position par une carte (trop complexe, abandonnée

pour l'instant)
This commit is contained in:
Jean-Marie Favreau 2024-10-16 12:09:23 +02:00
parent fba52afbb0
commit 3fbae56cbf
4 changed files with 91 additions and 23 deletions

View File

@ -246,7 +246,7 @@ class Place(models.Model):
null=True,
)
city = models.CharField(verbose_name=_("City"), help_text=_("City name"))
location = LocationField(based_fields=["name", "address", "city"], zoom=12, default=Point(3.08333, 45.783329))
location = LocationField(based_fields=["name", "address", "city"], zoom=12, default=Point(3.08333, 45.783329), srid=4326)
aliases = ArrayField(
models.CharField(max_length=512),

View File

@ -130,6 +130,10 @@ details[role="list"] summary + ul li.selected>a:hover {
display: none;
}
}
// on les cache pour le cas il n'y a pas de js
.nojs, .hidden {
display: none;
}
}
@media (min-width: 992px) {
@ -325,7 +329,7 @@ footer [data-tooltip] {
text-align: center;
position: fixed;
top: 65vh;
z-index: 10;
z-index: 1000;
opacity: 0.9;
a {
color: var(--primary-inverse);

View File

@ -1,6 +1,7 @@
{% load cat_extra %}
{% load tag_extra %}
{% load utils_extra %}
{% load static %}
{% if not noarticle %}
<article id="filters">
@ -23,9 +24,9 @@
{% for s in filter.get_status_names %}
{{ s }}
{% endfor %}
{% for c in filter.get_cities %}
{{ c }}
{% endfor %}
{% if filter.get_position %}
<span data-tooltip="{{ filter.get_position }}">{% picto_from_name "map-pin" %}</span>
{% endif %}
{{ filter.get_recurrence_filtering }}
{% else %}
Autres filtres
@ -37,8 +38,47 @@
</summary>
<form method="get" class="form django-form main-filter">
{{ filter.form.as_p }}
<div class="map-widget">
<div id="map_position_map" style="width: 100%; height: 50vh;" class="nojs"></div>
{% for f in filter.form.visible_fields %}
{% if f.id_for_label and f.id_for_label in "id_position_filter,id_position_map,id_position_gps" %}
<div {% if f.id_for_label == "id_position_map" %}
class="hidden"
{% else %}
{% if f.id_for_label == "id_position_gps" %}
class="nojs"
{% else %}
class="withjs"
{% endif %}
{% endif %}
>
{{ f.errors }}
{{ f.label_tag }} {{ f }}
<span class="helptext">{{ f.help_text }}</span>
</div>
{% endif %}
{% endfor %}
</div>
{{ form.media }}
{% for f in filter.form.visible_fields %}
{% if not f.id_for_label or not f.id_for_label in "id_position_filter,id_position_map,id_position_gps" %}
<p>
{{ f.errors }}
{{ f.label_tag }} {{ f }}
<span class="helptext">{{ f.help_text }}</span>
</p>
{% endif %}
{% endfor %}
<button type="submit">Appliquer le filtre</button>
<script src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script src="/static/admin/js/jquery.init.js"></script>
<script src="/static/location_field/js/form.js"></script>
<script>
document.querySelectorAll('.nojs').forEach(function(item) {
item.classList.remove('nojs'); });
document.querySelectorAll('.withjs').forEach(function(item) {
item.classList.add('nojs'); });
</script>
</form>
</details>
<div class="clear"></div>

View File

@ -11,10 +11,15 @@ from django import forms
from django.contrib.postgres.search import SearchQuery, SearchHeadline
from django.utils.safestring import mark_safe
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import D
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse
from collections import Counter
from location_field.widgets import LocationWidget
from django.forms import formset_factory
from .forms import (
@ -32,7 +37,8 @@ from .forms import (
CategorisationForm,
EventAddPlaceForm,
PlaceForm,
MultipleHiddenInput
MultipleHiddenInput,
HiddenInput
)
from .models import (
@ -170,6 +176,21 @@ class EventFilter(django_filters.FilterSet):
("only_recurrent", "Montrer uniquement les événements récurrents"),
]
position_filter = django_filters.CharFilter(
label="Filtrer par position",
method="filter_position",
help_text="Format: latitude,longitude,distance (km). Exemple: 45.783329,3.08333,3"
)
position_gps = django_filters.CharFilter(
label="Recherche par adresse",
)
position_map = django_filters.CharFilter(
label="Position sur la carte",
widget=LocationWidget(based_fields=['position_gps'])
)
exclude_tags = django_filters.MultipleChoiceFilter(
label="Exclure les étiquettes",
choices=[(t, t) for t in Event.get_all_tags()],
@ -201,13 +222,6 @@ class EventFilter(django_filters.FilterSet):
widget=MultipleHiddenInput,
)
city = django_filters.MultipleChoiceFilter(
label="Filtrer par ville",
field_name="exact_location__city",
choices=[(c, c) for c in Place.get_all_cities()],
widget=forms.CheckboxSelectMultiple,
)
status = django_filters.MultipleChoiceFilter(
label="Filtrer par status",
choices=Event.STATUS.choices,
@ -217,13 +231,22 @@ class EventFilter(django_filters.FilterSet):
class Meta:
model = Event
fields = ["category", "city", "tags", "exclude_tags", "status", "recurrences"]
fields = ["category", "tags", "exclude_tags", "status", "recurrences"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not kwargs["request"].user.is_authenticated:
self.form.fields.pop("status")
def filter_position(self, queryset, name, value):
values = value.split(',')
if len(values) != 3:
return queryset
else:
p = Point(float(values[1]), float(values[0]), srid=4326)
d = float(values[2])
return queryset.exclude(exact_location=False).filter(exact_location__location__distance_lt=(p, D(km=d)))
def filter_recurrences(self, queryset, name, value):
# construct the full lookup expression
lookup = "__".join([name, "isnull"])
@ -296,12 +319,13 @@ class EventFilter(django_filters.FilterSet):
def get_status(self):
return self.get_cleaned_data("status")
def get_cities(self):
return self.get_cleaned_data("city")
def get_position(self):
return self.get_cleaned_data("position_filter")
def to_str(self, prefix=''):
self.form.full_clean()
result = ' '.join([c.name for c in self.get_categories()] + [t for t in self.get_tags()] + [c for c in self.get_cities()])
result = ' '.join([c.name for c in self.get_categories()] + [t for t in self.get_tags()] + [t for t in self.get_exclude_tags()] + [p for p in self.get_position()])
if len(result) > 0:
result = prefix + result
return result
@ -346,7 +370,7 @@ class EventFilter(django_filters.FilterSet):
len(self.get_cleaned_data("tags")) != 0
or len(self.get_cleaned_data("exclude_tags")) != 0
or len(self.get_cleaned_data("recurrences")) != 0
or len(self.get_cleaned_data("city")) != 0
or len(self.get_cleaned_data("position_filter")) != 0
)
def is_active(self, only_categories=False):
@ -361,7 +385,7 @@ class EventFilter(django_filters.FilterSet):
len(self.get_cleaned_data("tags")) != 0
or len(self.get_cleaned_data("exclude_tags")) != 0
or len(self.get_cleaned_data("recurrences")) != 0
or len(self.get_cleaned_data("city")) != 0
or len(self.get_cleaned_data("position_filter")) != 0
)
def is_selected(self, cat):
@ -1889,7 +1913,7 @@ class PlaceUpdateView(
class PlaceCreateView(
UpdatePlaces, PermissionRequiredMixin, SuccessMessageMixin, CreateView
UpdatePlaces, SuccessMessageMixin, CreateView
):
model = Place
permission_required = "agenda_culturel.add_place"