mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 03:31:08 -05:00
Refactor park search results and search suggestions to utilize Alpine.js for improved state management. Enhanced event handling and user experience by replacing legacy JavaScript functions with Alpine.js reactive methods.
This commit is contained in:
@@ -1,9 +1,32 @@
|
|||||||
<div class="absolute z-50 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg dark:bg-gray-700 dark:border-gray-600" style="max-height: 240px; overflow-y: auto;">
|
<script>
|
||||||
|
document.addEventListener('alpine:init', () => {
|
||||||
|
Alpine.data('parkSearchResults', () => ({
|
||||||
|
selectPark(id, name) {
|
||||||
|
// Update park fields using AlpineJS reactive approach
|
||||||
|
const parkInput = this.$el.closest('form').querySelector('#id_park');
|
||||||
|
const searchInput = this.$el.closest('form').querySelector('#id_park_search');
|
||||||
|
const resultsDiv = this.$el.closest('form').querySelector('#park-search-results');
|
||||||
|
|
||||||
|
if (parkInput) parkInput.value = id;
|
||||||
|
if (searchInput) searchInput.value = name;
|
||||||
|
if (resultsDiv) resultsDiv.innerHTML = '';
|
||||||
|
|
||||||
|
// Dispatch custom event for parent component
|
||||||
|
this.$dispatch('park-selected', { id, name });
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div x-data="parkSearchResults()"
|
||||||
|
@click.outside="$el.innerHTML = ''"
|
||||||
|
class="absolute z-50 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg dark:bg-gray-700 dark:border-gray-600"
|
||||||
|
style="max-height: 240px; overflow-y: auto;">
|
||||||
{% if parks %}
|
{% if parks %}
|
||||||
{% for park in parks %}
|
{% for park in parks %}
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="w-full px-4 py-2 text-left text-gray-900 hover:bg-gray-100 dark:text-white dark:hover:bg-gray-600"
|
class="w-full px-4 py-2 text-left text-gray-900 hover:bg-gray-100 dark:text-white dark:hover:bg-gray-600"
|
||||||
onclick="selectPark('{{ park.id }}', '{{ park.name|escapejs }}')">
|
@click="selectPark('{{ park.id }}', '{{ park.name|escapejs }}')">
|
||||||
{{ park.name }}
|
{{ park.name }}
|
||||||
</button>
|
</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -17,11 +40,3 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
|
||||||
function selectPark(id, name) {
|
|
||||||
document.getElementById('id_park').value = id;
|
|
||||||
document.getElementById('id_park_search').value = name;
|
|
||||||
document.getElementById('park-search-results').innerHTML = '';
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -173,22 +173,39 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- Search Suggestions -->
|
<!-- Search Suggestions -->
|
||||||
<div class="flex flex-wrap gap-2 justify-center">
|
<script>
|
||||||
|
document.addEventListener('alpine:init', () => {
|
||||||
|
Alpine.data('searchSuggestions', () => ({
|
||||||
|
fillSearchInput(value) {
|
||||||
|
// Find the search input using AlpineJS approach
|
||||||
|
const searchInput = document.querySelector('input[type=text]');
|
||||||
|
if (searchInput) {
|
||||||
|
searchInput.value = value;
|
||||||
|
// Dispatch input event to trigger search
|
||||||
|
searchInput.dispatchEvent(new Event('input', { bubbles: true }));
|
||||||
|
searchInput.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div x-data="searchSuggestions()" class="flex flex-wrap gap-2 justify-center">
|
||||||
<span class="text-xs text-muted-foreground">Try:</span>
|
<span class="text-xs text-muted-foreground">Try:</span>
|
||||||
<button class="text-xs text-primary hover:text-primary/80 transition-colors"
|
<button class="text-xs text-primary hover:text-primary/80 transition-colors"
|
||||||
onclick="document.querySelector('input[type=text]').value='Disney'; document.querySelector('input[type=text]').dispatchEvent(new Event('input'));">
|
@click="fillSearchInput('Disney')">
|
||||||
Disney
|
Disney
|
||||||
</button>
|
</button>
|
||||||
<span class="text-xs text-muted-foreground">•</span>
|
<span class="text-xs text-muted-foreground">•</span>
|
||||||
<button class="text-xs text-primary hover:text-primary/80 transition-colors"
|
<button class="text-xs text-primary hover:text-primary/80 transition-colors"
|
||||||
onclick="document.querySelector('input[type=text]').value='roller coaster'; document.querySelector('input[type=text]').dispatchEvent(new Event('input'));">
|
@click="fillSearchInput('roller coaster')">
|
||||||
Roller Coaster
|
Roller Coaster
|
||||||
</button>
|
</button>
|
||||||
<span class="text-xs text-muted-foreground">•</span>
|
<span class="text-xs text-muted-foreground">•</span>
|
||||||
<button class="text-xs text-primary hover:text-primary/80 transition-colors"
|
<button class="text-xs text-primary hover:text-primary/80 transition-colors"
|
||||||
onclick="document.querySelector('input[type=text]').value='Cedar Point'; document.querySelector('input[type=text]').dispatchEvent(new Event('input'));">
|
@click="fillSearchInput('Cedar Point')">
|
||||||
Cedar Point
|
Cedar Point
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
Reference in New Issue
Block a user