Form attributes duplicating in '.controls' div when using CheckboxSelectMultiple widget with Crispy Forms

87 Views Asked by At

I have a form that's meant to filter results in a list view. I'm using HTMX to submit a GET request whenever the form changes, and I'm using Crispy Forms to render the form (including the hx attributes on the <form> tag).

I've used this pattern multiple times before with no issues, but on this particular form I want to use the CheckboxSelectMultiple widget. When the form is rendered, the hx attributes that I'm applying to the <form> tag are getting duplicated on the <div class="controls"> tag that holds the checkboxes.

Form

class MyListFilterForm(forms.Form):
    status = forms.MultipleChoiceField(choices=MyModel.STATUS_CHOICES, required=False,
                                       widget=forms.CheckboxSelectMultiple)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.helper = FormHelper()
        self.helper.form_method = 'GET'
        self.helper.disable_csrf = True
        self.helper.attrs = {
            'hx_get': reverse('myapp:my_view'),
            'hx_trigger': 'change',
            'hx_target': '#my_table_body',
        }

Rendered HTML

<form hx-get="/path/to/view/" hx-target="#my_table_body" hx-trigger="change" method="get">

   <div id="div_id_status" class="control-group">

      <label for="" class="control-label ">
          Status
      </label> 

      <div class="controls" hx-get="/path/to/view/" hx-target="#my_table_body" hx-trigger="change"> 

         <label class="checkbox" for="id_status_0"><input type="checkbox" name="status" id="id_status_0" value="1">Choice 1</label> 
         <label class="checkbox" for="id_status_1"><input type="checkbox" name="status" id="id_status_1" value="2">Choice 2</label> 
         <label class="checkbox" for="id_status_2"><input type="checkbox" name="status" id="id_status_2" value="3">Choice 3</label> 

      </div>
   </div>
</form>

This duplication of the hx attributes is causing the HTMX request to fire twice whenever one of these checkboxes is clicked. Not only that, but the first request is firing without the form data, so it's also causing incorrect results.

If I remove the CheckboxSelectMultiple widget and let the default SelectMultiple widget be used, then there is no issue and everything works fine, but CheckboxSelectMultiple is the desired widget for this form.

I know I could render the form manually in the template, or maybe do some custom HTMX event handling to stop the first request from firing, but ideally I'd like to just figure out how to render the form through Crispy Forms without getting the duplicate attributes.

I'm using Django 3.2.7 and Crispy Forms 1.13.0

0

There are 0 best solutions below