feat: add search-as-you-type functionality
This commit is contained in:
parent
4576ac68e0
commit
cc97fe32aa
@ -196,4 +196,4 @@ class AdoptionNoticeSearchForm(forms.Form):
|
|||||||
sex = forms.ChoiceField(choices=SexChoicesWithAll, label=_("Geschlecht"), required=False,
|
sex = forms.ChoiceField(choices=SexChoicesWithAll, label=_("Geschlecht"), required=False,
|
||||||
initial=SexChoicesWithAll.ALL)
|
initial=SexChoicesWithAll.ALL)
|
||||||
max_distance = forms.ChoiceField(choices=DistanceChoices, initial=DistanceChoices.ONE_HUNDRED, label=_("Suchradius"))
|
max_distance = forms.ChoiceField(choices=DistanceChoices, initial=DistanceChoices.ONE_HUNDRED, label=_("Suchradius"))
|
||||||
location_string = forms.CharField(max_length=20, label=_("Stadt"), required=False)
|
location_string = forms.CharField(max_length=100, label=_("Stadt"), required=False)
|
||||||
|
@ -909,6 +909,25 @@ div.announcement {
|
|||||||
width: 49%;
|
width: 49%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#results {
|
||||||
|
margin-top: 10px;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-item {
|
||||||
|
padding: 8px;
|
||||||
|
margin: 4px 0;
|
||||||
|
background-color: #ddd1a5;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-item:hover {
|
||||||
|
background-color: #ede1b5;
|
||||||
|
}
|
||||||
|
|
||||||
/************************/
|
/************************/
|
||||||
/* GENERAL HIGHLIGHTING */
|
/* GENERAL HIGHLIGHTING */
|
||||||
/************************/
|
/************************/
|
||||||
@ -939,7 +958,8 @@ div.announcement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.animal-shelter-marker {
|
.animal-shelter-marker {
|
||||||
background-image: url('../img/animal_shelter.png'); !important;
|
background-image: url('../img/animal_shelter.png');
|
||||||
|
!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.maplibregl-popup {
|
.maplibregl-popup {
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input type="hidden" name="longitude" maxlength="200" id="longitude">
|
<input type="hidden" name="longitude" maxlength="200" id="longitude">
|
||||||
<input type="hidden" name="latitude" maxlength="200" id="latitude">
|
<input type="hidden" name="latitude" maxlength="200" id="latitude">
|
||||||
|
<input type="hidden" id="place_id" name="place_id">
|
||||||
{{ search_form.as_p }}
|
{{ search_form.as_p }}
|
||||||
|
<ul id="results"></ul>
|
||||||
<div class="container-edit-buttons">
|
<div class="container-edit-buttons">
|
||||||
<button class="btn" type="submit" value="search" name="search">
|
<button class="btn" type="submit" value="search" name="search">
|
||||||
<i class="fas fa-search"></i> {% trans 'Suchen' %}
|
<i class="fas fa-search"></i> {% trans 'Suchen' %}
|
||||||
@ -40,4 +42,47 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% include "fellchensammlung/lists/list-adoption-notices.html" %}
|
{% include "fellchensammlung/lists/list-adoption-notices.html" %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const locationInput = document.getElementById('id_location_string');
|
||||||
|
const resultsList = document.getElementById('results');
|
||||||
|
const placeIdInput = document.getElementById('place_id');
|
||||||
|
|
||||||
|
locationInput.addEventListener('input', async function () {
|
||||||
|
const query = locationInput.value.trim();
|
||||||
|
|
||||||
|
if (query.length < 3) {
|
||||||
|
resultsList.innerHTML = ''; // Don't search for or show results if input is less than 3 characters
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`https://photon.hyteck.de/api/?q=${encodeURIComponent(query)}&limit=5`);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data && data.features) {
|
||||||
|
const locations = data.features.slice(0, 5); // Show only the first 5 results
|
||||||
|
resultsList.innerHTML = ''; // Clear previous results
|
||||||
|
|
||||||
|
locations.forEach(location => {
|
||||||
|
const listItem = document.createElement('li');
|
||||||
|
listItem.classList.add('result-item');
|
||||||
|
listItem.textContent = location.properties.name;
|
||||||
|
|
||||||
|
// Add event when user clicks on a result location
|
||||||
|
listItem.addEventListener('click', () => {
|
||||||
|
|
||||||
|
locationInput.value = location.properties.name; // Set input field to selected location
|
||||||
|
resultsList.innerHTML = ''; // Clear the results after selecting a location
|
||||||
|
});
|
||||||
|
|
||||||
|
resultsList.appendChild(listItem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching location data:', error);
|
||||||
|
resultsList.innerHTML = '<li class="result-item">Error fetching data. Please try again.</li>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -39,6 +39,8 @@ class Search:
|
|||||||
self.location = None # Can either be Location (DjangoModel) or LocationProxy
|
self.location = None # Can either be Location (DjangoModel) or LocationProxy
|
||||||
self.place_not_found = False # Indicates that a location was given but could not be geocoded
|
self.place_not_found = False # Indicates that a location was given but could not be geocoded
|
||||||
self.search_form = None
|
self.search_form = None
|
||||||
|
# Either place_id or location string must be set for area search
|
||||||
|
self.location_string = None
|
||||||
|
|
||||||
if request:
|
if request:
|
||||||
self.search_from_request(request)
|
self.search_from_request(request)
|
||||||
@ -106,6 +108,7 @@ class Search:
|
|||||||
self.search_form = AdoptionNoticeSearchForm(request.POST)
|
self.search_form = AdoptionNoticeSearchForm(request.POST)
|
||||||
self.search_form.is_valid()
|
self.search_form.is_valid()
|
||||||
self.sex = self.search_form.cleaned_data["sex"]
|
self.sex = self.search_form.cleaned_data["sex"]
|
||||||
|
|
||||||
if self.search_form.cleaned_data["location_string"] != "" and self.search_form.cleaned_data[
|
if self.search_form.cleaned_data["location_string"] != "" and self.search_form.cleaned_data[
|
||||||
"max_distance"] != "":
|
"max_distance"] != "":
|
||||||
self.area_search = True
|
self.area_search = True
|
||||||
|
Loading…
x
Reference in New Issue
Block a user