Refactor ride form template to utilize Alpine.js for state management. Enhanced form submission handling and improved search result clearing functionality for better user experience.

This commit is contained in:
pacnpal
2025-09-26 14:27:47 -04:00
parent b9377ead37
commit 40e5cf3162
2 changed files with 107 additions and 68 deletions

View File

@@ -199,24 +199,31 @@
</div>
<script>
document.body.addEventListener('htmx:afterRequest', function(evt) {
if (evt.detail.successful) {
const path = evt.detail.requestConfig.path;
let event;
document.addEventListener('alpine:init', () => {
Alpine.data('moderationDashboard', () => ({
init() {
// Handle HTMX events using AlpineJS approach
document.body.addEventListener('htmx:afterRequest', (evt) => {
if (evt.detail.successful) {
const path = evt.detail.requestConfig.path;
let eventName;
if (path.includes('approve')) {
event = new CustomEvent('submission-approved');
} else if (path.includes('reject')) {
event = new CustomEvent('submission-rejected');
} else if (path.includes('escalate')) {
event = new CustomEvent('submission-escalated');
} else if (path.includes('edit')) {
event = new CustomEvent('submission-updated');
}
if (path.includes('approve')) {
eventName = 'submission-approved';
} else if (path.includes('reject')) {
eventName = 'submission-rejected';
} else if (path.includes('escalate')) {
eventName = 'submission-escalated';
} else if (path.includes('edit')) {
eventName = 'submission-updated';
}
if (event) {
window.dispatchEvent(event);
}
if (eventName) {
this.$dispatch(eventName);
}
}
});
}
});
}));
});
</script>

View File

@@ -1,59 +1,85 @@
{% load static %}
<script>
function selectManufacturer(id, name) {
document.getElementById('id_manufacturer').value = id;
document.getElementById('id_manufacturer_search').value = name;
document.getElementById('manufacturer-search-results').innerHTML = '';
document.addEventListener('alpine:init', () => {
Alpine.data('rideForm', () => ({
init() {
// Handle form submission cleanup
this.$el.addEventListener('submit', () => {
this.clearAllSearchResults();
});
},
// Update ride model search to include manufacturer
const rideModelSearch = document.getElementById('id_ride_model_search');
if (rideModelSearch) {
rideModelSearch.setAttribute('hx-include', '[name="manufacturer"]');
}
}
selectManufacturer(id, name) {
const manufacturerInput = document.getElementById('id_manufacturer');
const manufacturerSearch = document.getElementById('id_manufacturer_search');
const manufacturerResults = document.getElementById('manufacturer-search-results');
function selectDesigner(id, name) {
document.getElementById('id_designer').value = id;
document.getElementById('id_designer_search').value = name;
document.getElementById('designer-search-results').innerHTML = '';
}
if (manufacturerInput) manufacturerInput.value = id;
if (manufacturerSearch) manufacturerSearch.value = name;
if (manufacturerResults) manufacturerResults.innerHTML = '';
function selectRideModel(id, name) {
document.getElementById('id_ride_model').value = id;
document.getElementById('id_ride_model_search').value = name;
document.getElementById('ride-model-search-results').innerHTML = '';
}
// Update ride model search to include manufacturer
const rideModelSearch = document.getElementById('id_ride_model_search');
if (rideModelSearch) {
rideModelSearch.setAttribute('hx-include', '[name="manufacturer"]');
}
},
// Handle form submission
document.addEventListener('submit', function(e) {
if (e.target.id === 'ride-form') {
// Clear search results
document.getElementById('manufacturer-search-results').innerHTML = '';
document.getElementById('designer-search-results').innerHTML = '';
document.getElementById('ride-model-search-results').innerHTML = '';
}
});
selectDesigner(id, name) {
const designerInput = document.getElementById('id_designer');
const designerSearch = document.getElementById('id_designer_search');
const designerResults = document.getElementById('designer-search-results');
// Handle clicks outside search results
document.addEventListener('click', function(e) {
const manufacturerResults = document.getElementById('manufacturer-search-results');
const designerResults = document.getElementById('designer-search-results');
const rideModelResults = document.getElementById('ride-model-search-results');
if (designerInput) designerInput.value = id;
if (designerSearch) designerSearch.value = name;
if (designerResults) designerResults.innerHTML = '';
},
if (!e.target.closest('#manufacturer-search-container')) {
manufacturerResults.innerHTML = '';
}
if (!e.target.closest('#designer-search-container')) {
designerResults.innerHTML = '';
}
if (!e.target.closest('#ride-model-search-container')) {
rideModelResults.innerHTML = '';
}
selectRideModel(id, name) {
const rideModelInput = document.getElementById('id_ride_model');
const rideModelSearch = document.getElementById('id_ride_model_search');
const rideModelResults = document.getElementById('ride-model-search-results');
if (rideModelInput) rideModelInput.value = id;
if (rideModelSearch) rideModelSearch.value = name;
if (rideModelResults) rideModelResults.innerHTML = '';
},
clearAllSearchResults() {
const manufacturerResults = document.getElementById('manufacturer-search-results');
const designerResults = document.getElementById('designer-search-results');
const rideModelResults = document.getElementById('ride-model-search-results');
if (manufacturerResults) manufacturerResults.innerHTML = '';
if (designerResults) designerResults.innerHTML = '';
if (rideModelResults) rideModelResults.innerHTML = '';
},
clearManufacturerResults() {
const manufacturerResults = document.getElementById('manufacturer-search-results');
if (manufacturerResults) manufacturerResults.innerHTML = '';
},
clearDesignerResults() {
const designerResults = document.getElementById('designer-search-results');
if (designerResults) designerResults.innerHTML = '';
},
clearRideModelResults() {
const rideModelResults = document.getElementById('ride-model-search-results');
if (rideModelResults) rideModelResults.innerHTML = '';
}
}));
});
</script>
<form method="post" id="ride-form" class="space-y-6" enctype="multipart/form-data">
<form method="post"
id="ride-form"
class="space-y-6"
enctype="multipart/form-data"
x-data="rideForm"
x-init="init()">
{% csrf_token %}
<!-- Park Area -->
@@ -86,7 +112,9 @@ document.addEventListener('click', function(e) {
<!-- Manufacturer -->
<div class="space-y-2">
<div id="manufacturer-search-container" class="relative">
<div id="manufacturer-search-container"
class="relative"
@click.outside="clearManufacturerResults()">
<label for="{{ form.manufacturer_search.id_for_label }}" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Manufacturer
</label>
@@ -103,7 +131,9 @@ document.addEventListener('click', function(e) {
<!-- Designer -->
<div class="space-y-2">
<div id="designer-search-container" class="relative">
<div id="designer-search-container"
class="relative"
@click.outside="clearDesignerResults()">
<label for="{{ form.designer_search.id_for_label }}" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Designer
</label>
@@ -120,7 +150,9 @@ document.addEventListener('click', function(e) {
<!-- Ride Model -->
<div class="space-y-2">
<div id="ride-model-search-container" class="relative">
<div id="ride-model-search-container"
class="relative"
@click.outside="clearRideModelResults()">
<label for="{{ form.ride_model_search.id_for_label }}" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Ride Model
</label>