riggedCoinflip
riggedCoinflip

Reputation: 485

form field inline with label using django-crispy-forms

I am using crispy to render my forms, but I got problems rendering a single field inline without affecting the other fields.

This form:

class SettingsUpdateForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('about_text', 'github_name')
        labels = {
            'about_text': '',
            'github_name': 'github.com/'  # TODO make inline with field
        }
        widgets = {
            'about_text': forms.Textarea(attrs={'placeholder': 'Describe yourself!💯'}),
            'github_name': forms.TextInput(attrs={'placeholder': 'your_github_name'})
        }
        help_texts = {
            'github_name': 'Showcase a project instead: <em>/username/fav_project</em>',
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self)  # this is required to display the help_texts

renders like this: A submit form with a label "github/". The input field is on the next line

I want to have the github/ label on the same line with the input field. How do I do that?

Horizontal Forms would make all labels be part of bootstraps grid model - which I do not want.
I tried to use Inline Forms as well which did not work either.

Upvotes: 0

Views: 1601

Answers (3)

Jacek
Jacek

Reputation: 73

I found another solution. This is not exactly what the author wanted to achieve but can be useful in many cases. I used the PrependText attribute for the input field.

self.helper.form_show_labels = False
self.helper.layout = Layout(
    Div(
        Div(PrependedText('date_from', "from:"), css_class='col-md-5'),
        Div(PrependedText('date_to', "to:"), css_class='col-md-5'),
        Div(Submit('submit', 'Filter'), css_class='col-md-2'),
        css_class='row',
        )
)

The form looks like this: form

This works with crispy-bootstrap5

Upvotes: 2

riggedCoinflip
riggedCoinflip

Reputation: 485

I was able to solve it myself with a hack. This is the solution I came up with:

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.helper = FormHelper(self)
    '''
    hacky solution - replace the standard label with a fake label. 
    Wrap those 2 as columns of a Row - use col-auto on first to not have whitespace between.
    Use g-0 to not have gutters between columns - padding and margin would else create whitespace
    '''
    self.helper.layout = Layout(
        Div('about_text'),
        Row(
            # create a "fake" label with a HTML Column
            Column(HTML('<em class="fab fa-github fa-2x"></em> github.com/'), css_class='col-auto'),
            Column('github_name', css_class='col'),
            css_class='row g-0'
        )
    )

I had to remove the label of github_name as well. But it looks good now: Label is on same line with the field.

Upvotes: 1

periwinkle
periwinkle

Reputation: 416

In your widgets you need to include the attribute that will let crispyforms know how to render it. Try this:

'github_name': forms.TextInput(attrs={'class': 'form-control', 
                                      'placeholder': 'your_github_name'})

Let me know if it works

Upvotes: 0

Related Questions