from django import forms from django.forms import ModelChoiceField from django.urls import reverse_lazy from .models import Ride, RideModel from parks.models import Park, ParkArea from manufacturers.models import Manufacturer from designers.models import Designer class RideForm(forms.ModelForm): park_search = forms.CharField( label="Park *", required=True, widget=forms.TextInput( attrs={ "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Search for a park...", "hx-get": "/parks/search/", "hx-trigger": "click, input delay:200ms", "hx-target": "#park-search-results", "name": "q", "autocomplete": "off", } ), ) manufacturer_search = forms.CharField( label="Manufacturer", required=False, widget=forms.TextInput( attrs={ "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Search for a manufacturer...", "hx-get": reverse_lazy("rides:search_manufacturers"), "hx-trigger": "click, input delay:200ms", "hx-target": "#manufacturer-search-results", "name": "q", "autocomplete": "off", } ), ) designer_search = forms.CharField( label="Designer", required=False, widget=forms.TextInput( attrs={ "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Search for a designer...", "hx-get": reverse_lazy("rides:search_designers"), "hx-trigger": "click, input delay:200ms", "hx-target": "#designer-search-results", "name": "q", "autocomplete": "off", } ), ) ride_model_search = forms.CharField( label="Ride Model", required=False, widget=forms.TextInput( attrs={ "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Search for a ride model...", "hx-get": reverse_lazy("rides:search_ride_models"), "hx-trigger": "click, input delay:200ms", "hx-target": "#ride-model-search-results", "hx-include": "[name='manufacturer']", "name": "q", "autocomplete": "off", } ), ) park = forms.ModelChoiceField( queryset=Park.objects.all(), required=True, label="", widget=forms.HiddenInput() ) manufacturer = forms.ModelChoiceField( queryset=Manufacturer.objects.all(), required=False, label="", widget=forms.HiddenInput() ) designer = forms.ModelChoiceField( queryset=Designer.objects.all(), required=False, label="", widget=forms.HiddenInput() ) ride_model = forms.ModelChoiceField( queryset=RideModel.objects.all(), required=False, label="", widget=forms.HiddenInput() ) park_area = ModelChoiceField( queryset=ParkArea.objects.none(), required=False, widget=forms.Select( attrs={ "class": "w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Select an area within the park..." } ), ) class Meta: model = Ride fields = [ "name", "category", "manufacturer", "designer", "ride_model", "status", "post_closing_status", "opening_date", "closing_date", "status_since", "min_height_in", "max_height_in", "capacity_per_hour", "ride_duration_seconds", "description", ] widgets = { "name": forms.TextInput( attrs={ "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Official name of the ride" } ), "category": forms.Select( attrs={ "class": "w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white", "hx-get": reverse_lazy("rides:coaster_fields"), "hx-target": "#coaster-fields", "hx-trigger": "change", "hx-include": "this", "hx-swap": "innerHTML" } ), "status": forms.Select( attrs={ "class": "w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Current operational status", "x-model": "status", "@change": "handleStatusChange" } ), "post_closing_status": forms.Select( attrs={ "class": "w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Status after closing", "x-show": "status === 'CLOSING'" } ), "opening_date": forms.DateInput( attrs={ "type": "date", "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Date when ride first opened" } ), "closing_date": forms.DateInput( attrs={ "type": "date", "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Date when ride will close", "x-show": "['CLOSING', 'SBNO', 'CLOSED_PERM', 'DEMOLISHED', 'RELOCATED'].includes(status)", ":required": "status === 'CLOSING'" } ), "status_since": forms.DateInput( attrs={ "type": "date", "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Date when current status took effect" } ), "min_height_in": forms.NumberInput( attrs={ "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "min": "0", "placeholder": "Minimum height requirement in inches" } ), "max_height_in": forms.NumberInput( attrs={ "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "min": "0", "placeholder": "Maximum height limit in inches (if applicable)" } ), "capacity_per_hour": forms.NumberInput( attrs={ "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "min": "0", "placeholder": "Theoretical hourly ride capacity" } ), "ride_duration_seconds": forms.NumberInput( attrs={ "class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white", "min": "0", "placeholder": "Total duration of one ride cycle in seconds" } ), "description": forms.Textarea( attrs={ "rows": 4, "class": "w-full border-gray-300 rounded-lg form-textarea dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "General description and notable features of the ride" } ), } def __init__(self, *args, **kwargs): park = kwargs.pop("park", None) super().__init__(*args, **kwargs) # Make category required self.fields['category'].required = True # Clear any default values for date fields self.fields["opening_date"].initial = None self.fields["closing_date"].initial = None self.fields["status_since"].initial = None # Move fields to the beginning in desired order field_order = [ "park_search", "park", "park_area", "name", "manufacturer_search", "manufacturer", "designer_search", "designer", "ride_model_search", "ride_model", "category", "status", "post_closing_status", "opening_date", "closing_date", "status_since", "min_height_in", "max_height_in", "capacity_per_hour", "ride_duration_seconds", "description" ] self.order_fields(field_order) if park: # If park is provided, set it as the initial value self.fields["park"].initial = park # Hide the park search field since we know the park del self.fields["park_search"] # Create new park_area field with park's areas self.fields["park_area"] = forms.ModelChoiceField( queryset=park.areas.all(), required=False, widget=forms.Select( attrs={ "class": "w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white", "placeholder": "Select an area within the park..." } ), ) else: # If no park provided, show park search and disable park_area until park is selected self.fields["park_area"].widget.attrs["disabled"] = True # Initialize park search with current park name if editing if self.instance and self.instance.pk and self.instance.park: self.fields["park_search"].initial = self.instance.park.name self.fields["park"].initial = self.instance.park # Initialize manufacturer, designer, and ride model search fields if editing if self.instance and self.instance.pk: if self.instance.manufacturer: self.fields["manufacturer_search"].initial = self.instance.manufacturer.name self.fields["manufacturer"].initial = self.instance.manufacturer if self.instance.designer: self.fields["designer_search"].initial = self.instance.designer.name self.fields["designer"].initial = self.instance.designer if self.instance.ride_model: self.fields["ride_model_search"].initial = self.instance.ride_model.name self.fields["ride_model"].initial = self.instance.ride_model