Home > database >  How to preserve values from multiple select objects on one form using Django HTMX
How to preserve values from multiple select objects on one form using Django HTMX

Time:04-17

Picture a todo list with multiple columns that include Priority, Status, AssignedTo, Due Date. Now I have a form below this list that has a ChoiceBox (and in one case ModelChoiceBox) for each of these conditions. So set Priority to 2, and the list refreshes to just 2's. Now select Status = 3 for example, and the two filters should be combined. In my View however, they are not. The value of the most recent Select comes over, but he previous value is reset to None. Here is a slimmed down example with just 2 Selects.


class FilterForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.attrs = {"novalidate": '', }

    priority = forms.ChoiceField(
        choices=PRIORITY_CHOICES,
        widget=forms.Select(attrs={
            'hx-get': reverse_lazy('change-priority'),
            'hx-target': '#tasklist',
            'hx-trigger': 'change'
        })
    )

    status = forms.ModelChoiceField(queryset=TaskStatus.objects.all(),
             widget=forms.Select(attrs={
              'hx-get': reverse_lazy('change-priority'),
              'hx-target': '#tasklist',
               'hx-trigger': 'change'
              })
          )

Here is a scaled down View:

def change_priority(request):
    filtform = FilterForm(request.POST)

   
    fpriority = filtform["priority"].value()

    fstatus = filtform["status"].value()
    tasklist = get_object_or_404(TaskList, owner=request.user)
    if tasklist:
        tasks = Task.objects.filter(priority=fpriority, status=fstatus)

        context = {
            "tasks": tasks,
            "filtform": filtform,
            
        }

        return render(request, "planner/partials/tasklist.html", context)
    return HttpResponse("Error - No Valid Task List")

So changing Priority sends the correct Selected value to View and Status is None. Then Select Status and hope to preserve Priority, but no. Now I get correct value for Status but Priority is None.

So you see I am trying to build a series of List filters that update the list dynamically and are cumulative. Any idea how I can do this?

CodePudding user response:

Since you are not submitting the whole form via HTMX, you need to explicitly include additional form elements in a HTMX request using hx-include attribute.

class FilterForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.attrs = {"novalidate": '', }

    priority = forms.ChoiceField(
        choices=PRIORITY_CHOICES,
        widget=forms.Select(attrs={
            'hx-get': reverse_lazy('change-priority'),
            'hx-include': '[name="status"]',
            'hx-target': '#tasklist',
            'hx-trigger': 'change'
        })
    )

    status = forms.ModelChoiceField(
        queryset=TaskStatus.objects.all(),
        widget=forms.Select(attrs={
           'hx-get': reverse_lazy('change-priority'),
           'hx-include': '[name="priority"]',
           'hx-target': '#tasklist',
           'hx-trigger': 'change'
        })
     )

You can also place it on common parent element, since it is inherited.

  • Related