6

I am styling my django app but Iam having trouble styling the forms. I have a contact form, in my forms.py and then I have use it in a template.

<form class="form-contact" action="" method="POST">
{% csrf_token %} 
<input type="text" name="Name" id="id_name" value="{{form.name}}" />
<input type="submit" value="Submit"  class="btn btn-primary">
</form>

That isn't working. I have also tried this, but still no luck, it shows styled fields but doesn't retrieve the information ( I get a message under my {{form.errors}} .

<form class="form-contact" action="" method="POST">
{% csrf_token %} 
{% for field in form %}
<fieldset class="form-group">
    <label class="control-label" for="id_{{ field.name }}">{{ field.label }}</label>
         <div class="form-control">
        <input type="text" class="form-control"
            name="{{ field.label }}"
            id="{{ field.name }}"
            value="{{ field.name }}" >
         {{ field }} 
        <p class="help-text">{{ field.help_text }} </p>
       </div>
</fieldset>
{% endfor %}
   <input type="submit" value="Submit"  class="btn btn-primary">
</form>

Any hint would be apreciated. Regards.

EDIT: This second code, is actually showing 2 input fields for each form field. If I fill the second one, the form works but, this second input has no styling...

jesicadev18
  • 2,942
  • 5
  • 22
  • 39

3 Answers3

22

"EDIT: This second code, is actually showing 2 input fields for each form field."

The first input is being generated by the <input> tag that you've explicitly written:

<input type="text" class="form-control"
            name="{{ field.label }}"
            id="{{ field.name }}"
            value="{{ field.name }}" >

The second input is being generated by the {{ field }} variable:

 <div class="form-control">
        <input type="text" class="form-control"
            name="{{ field.label }}"
            id="{{ field.name }}"
            value="{{ field.name }}" >
         {{ field }} <-- this one
        <p class="help-text">{{ field.help_text }} </p>
       </div>

"If I fill the second one, the form works but, this second input has no styling..."

The styling isn't working because when the {{ field }} input is rendered, there's no css classes on it.

Additionally, you've switched some of the attributes of each field object (see "What changed" section below for more).

Try this code:

<form class="form-contact" action="" method="POST">
{% csrf_token %} 
{% for field in form %}
<fieldset class="form-group">
  <label class="control-label" for="id_{{ field.name }}">{{ field.label }}</label>
    <div class="form-control">
      <input type="text" class="form-control"
        name="{{ field.name }}"
        id="id_{{ field.name }}"
        value="{{ field.value }}" > 
        <p class="help-text">{{ field.help_text }} </p>
       </div>
</fieldset>
{% endfor %}
   <input type="submit" value="Submit"  class="btn btn-primary">
</form>

For more on how this works, check out the "Looping over a form's fields" section of the docs. You might also be interested in "Django Bootstrap Form", a third-party-package that allows for quick and easy form styling.

What changed:
1. Removed the {{ field }} variable within the loop
2. {{ field.label }} replaced with {{ field.name }} within the name attribute
3. {{ field.name }} replaced with {{ field.value }} within the value attribute

Brian Dant
  • 4,029
  • 6
  • 33
  • 47
  • One more thing, how do I change the input type ? I mean, I have a password field and that requires an input type="password".Thanks – jesicadev18 Sep 16 '13 at 20:23
  • You do it exactly how you wrote it there :) `` – Brian Dant Sep 16 '13 at 20:47
  • 3
    but in this case the form is rendered inside a loop, so I thought that it would be possible to assign the input type 'dynamically'. I've tried with field.widget but doesn't work. However I made it work by asking if the field.name was password.. (not an elegant solution) Thanks – jesicadev18 Sep 16 '13 at 21:05
  • Django floppyforms has a PasswordInput widget: http://django-floppyforms.readthedocs.org/en/latest/widgets-reference.html#floppyforms.widgets.PasswordInput – Brian Dant Sep 19 '13 at 18:51
2

Wrap the form in div's with container, row, and col. Also, add the input type.

<style>
    .help-text {
        font-style: italic;
        font-variant: all-small-caps;
    }
</style>
<div class="container">
  <form class="my-form" action="." method="POST">
  {% csrf_token %}
  {% for field in form %}
    <div class="form-group row">
      <label class="col-12 col-form-label" for="id_{{ field.name }}">{{ field.label }}</label>
      <div class="col-12">
        <input
          type="{{ field.field.widget.input_type }}"
          class="form-control"
          name="{{ field.name }}"
          id="id_{{ field.name }}"
          value="{{ field.value|default:'' }}"
        >
      </div>
      <div class="col-12 help-text">{{ field.help_text }} </div>
    </div>
  {% endfor %}
    <div class="row">
      <div class="col-12">
        <input type="submit" value="Submit"  class="btn btn-primary">
      </div>
    </div>
  </form>
</div>
Stefan Musarra
  • 1,429
  • 14
  • 16
0

Alternatively you can use, forms.py file for creating forms. And install django-bootstrap and work.. It will be very interesting.