pythondjangodjango-formsdjango-templatesdjango-crispy-forms

Render Submit Button in Same Row as Form Field in Django Crispy Forms


I'm using Django Crispy Forms, and rather than have the Submit button render below the rest of the fields, I want to move it to the same row as another field. My current Form code follows:

class SetForm(forms.ModelForm):
    class Meta:
        model = Set
        fields = ['exercise', 'actual_weight', 'actual_reps', 'actual_difficulty']

    helper = FormHelper()
    helper.form_method = 'POST'

    helper.layout = Layout(
        Row(
            Column('exercise', css_class='form-group col-md-12 mb-0'),
            css_class='form-row'
        ),
        Row(
            Column('actual_weight', css_class='form-group col-6 mb-0'),
            Column('actual_reps', css_class='form-group col-6 mb-0'),
        ),
        Row(
            Column('actual_difficulty', css_class='form-group col-6 mb-0'),
            Column(helper.add_input(Submit('submit', 'Submit', css_class='form-group btn-primary col-6 mb-0'))),
        )
    )

This doesn't work though, the Submit button is still on its own row below the form, though the col-6 class does appear to be applied.

I tried looking at this question, but it neither has answers nor uses Django Crispy Forms, as well as this one, but that one is focused on prepended text and it's not straightforward to modify the answers for this use case. Help please!


Solution

  • Figured it out:

    class SetForm(forms.ModelForm):
        class Meta:
            model = Set
            fields = ['exercise', 'actual_weight', 'actual_reps', 'actual_difficulty']
    
        helper = FormHelper()
        helper.form_method = 'POST'
    
        helper.layout = Layout(
            Row(
                Column('exercise', css_class='form-group col-md-12 mb-0'),
                css_class='form-row'
            ),
            Row(
                Column('actual_weight', css_class='form-group col-6 mb-0'),
                Column('actual_reps', css_class='form-group col-6 mb-0'),
            ),
            Row(
                Column('actual_difficulty', css_class='form-group col-6 mb-0'),
                Column(Submit('submit', 'Submit', css_class='btn-primary col-6')),
            )
        )
    

    The trick was to remove to remove the helper.add_input clause. That works to add a submit button to a Form, but apparently it also makes it put the submit button after the form, rather than embedded using the layout.

    One note though: this solution is imperfect: the submit button is now on the same row as the 'actual_difficutly' field as desired, but it is not the same height as the actual_difficulty field. This is because the actual_difficulty field has enough height to accommodate the label as well as the input, whereas the submit button does not. For this solution to look ideal, it still needs some custom css applied to the submit button to make it the same height.