Refactor ride filters and forms to use AlpineJS for state management and HTMX for AJAX interactions

- Enhanced filter sidebar with AlpineJS for collapsible sections and localStorage persistence.
- Removed custom JavaScript in favor of AlpineJS for managing filter states and interactions.
- Updated ride form to utilize AlpineJS for handling manufacturer, designer, and ride model selections.
- Simplified search script to leverage AlpineJS for managing search input and suggestions.
- Improved error handling for HTMX requests with minimal JavaScript.
- Refactored ride form data handling to encapsulate logic within an AlpineJS component.
This commit is contained in:
pacnpal
2025-09-26 15:25:12 -04:00
parent c437ddbf28
commit de8b6f67a3
8 changed files with 706 additions and 1172 deletions

View File

@@ -15,26 +15,7 @@
{% endif %}
</h1>
<form method="post" enctype="multipart/form-data" class="space-y-6" x-data="{
status: '{{ form.instance.status|default:'OPERATING' }}',
clearResults(containerId) {
const container = document.getElementById(containerId);
if (container && !container.contains(event.target)) {
container.querySelector('[id$=search-results]').innerHTML = '';
}
},
handleStatusChange(event) {
this.status = event.target.value;
if (this.status === 'CLOSING') {
document.getElementById('id_closing_date').required = true;
} else {
document.getElementById('id_closing_date').required = false;
}
},
showClosingDate() {
return ['CLOSING', 'SBNO', 'CLOSED_PERM', 'DEMOLISHED', 'RELOCATED'].includes(this.status);
}
}">
<form method="post" enctype="multipart/form-data" class="space-y-6" x-data="rideFormData()">
{% csrf_token %}
{% if not park %}
@@ -242,4 +223,41 @@
</form>
</div>
</div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('rideFormData', () => ({
status: '{{ form.instance.status|default:"OPERATING" }}',
init() {
// Watch for status changes on the status select element
this.$watch('status', (value) => {
const closingDateField = this.$el.querySelector('#id_closing_date');
if (closingDateField) {
closingDateField.required = value === 'CLOSING';
}
});
},
clearResults(containerId) {
// Use AlpineJS $el to find container within component scope
const container = this.$el.querySelector(`#${containerId}`);
if (container) {
const resultsDiv = container.querySelector('[id$="search-results"]');
if (resultsDiv) {
resultsDiv.innerHTML = '';
}
}
},
handleStatusChange(event) {
this.status = event.target.value;
},
showClosingDate() {
return ['CLOSING', 'SBNO', 'CLOSED_PERM', 'DEMOLISHED', 'RELOCATED'].includes(this.status);
}
}));
});
</script>
{% endblock %}