0

I am using Crispy Forms with Bootstrap4. Currently, all the input fields are rendered with form-control class. I want to add form-control-lg to the input fields.

I have tried the following but it is not working

forms.py

class UserRegisterForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2', 'first_name', 'last_name']
        help_texts = {
            'username': None,
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['password1'].help_text = None
        self.fields['password2'].help_text = None
        self.fields['password2'].label = "Confirm Password"
        self.helper = FormHelper()
        self.helper.layout = Layout(
        Field(
            'username', css_class="form-control form-control-lg my-custom-class"
            )
        )

Template

<div class="content-section">
        <form method="POST" action="">
          <h3>Sign Up</h3>
          <hr>
          {% csrf_token %}
         {{ form | crispy }}  
          </br>
          <button type="submit" class="btn btn-primary">Sign Up</button>
        </form>
 </div>

Also, can I modify the class globally for all input fields?

sarbjit
  • 3,786
  • 9
  • 38
  • 60

1 Answers1

0

Following the pattern you already have. Let's start with this method:

1.

class UserRegisterForm(UserCreationForm):
    email = forms.EmailField(required=True)

class Meta:
    model = User
    fields = ['username', 'email', 'password1', 'password2', 'first_name', 'last_name']
    help_texts = {
        'username': None,
    }

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.fields['password1'].help_text = None
    self.fields['password2'].help_text = None
    self.fields['password2'].label = "Confirm Password"
    self.helper = FormHelper()
    # Attach to helper
    self.helper.form_class = 'form-control-lg'

FormHelper has a list of attributes that can be set, that affect mainly form attributes.

Let’s see how to render the form in a template. Supposing we have the form in the template context as example_form, we would render it doing:

{% load crispy_forms_tags %}
{% crispy example_form example_form.helper %}

Notice that the {% crispy %} tags expects two parameters: first the form variable and then the helper. In this case we use the FormHelper attached to the form, but you could also create a FormHelper instance and pass it as a context variable. Most of the time, you will want to use the helper attached. Note that if you name your FormHelper attribute helper you will only need to do:

{% crispy form %}

Inside project settings.py add this line

CRISPY_CLASS_CONVERTERS = {'textinput': "textinput inputtext"}

For example this setting would generate <input class"textinput inputtext" .... The key of the dictionary textinput is the Django’s default class, the value is what you want it to be substituted with, in this case we are keeping textinput.

So from above you could substitute this way:

CRISPY_CLASS_CONVERTERS = {'input-control': "input-control-lg inputtext"}

References and quotes from Django Crispy Form Doc

Edit

Check this answer

  • Thanks, I modified the code as per your suggestion. However, #1 did not work for me i.e. there was no change on setting the form helper class. #2 did work for me. I am just curious why #1 did not work. – sarbjit Feb 27 '22 at 23:04
  • Looking further, it seems self.helper.form_class is working but it is adding class name on the `form` element. I am looking for a way to add class on the form elements. – sarbjit Feb 27 '22 at 23:25