Rohan
Rohan

Reputation: 455

Set default value for select html element in Jinja template?

I'm using flask/jinja in order to make a simple web application. I have a table of records which is taken from a db table, and is called by a webpage which loads the list of records. On each row there is a dropdown list (done using the select HTML tag) on a column.

I realize the below code doesn't do what its supposed to, currently the last option (fourth) is automatically selected because of the selected tag. I've left it in to try show what I'm trying to implement.

Ideally I'd want it to check the current record's status (rec.status in the code below) and depending on that, select the appropriate item in the dropdown.

HTML:

     <tbody>
            {% for rec in records %}
        <tr>
          <td>{{ rec.task }}</td>
          <td>
            <select>
              <option value ="zero" selected={{rec.status==0}}>Zero</option>
              <option value ="first" selected={{rec.status==1}}>First</option>
              <option value ="second" selected={{rec.status==2}}>Second</option>
              <option value ="third" selected={{rec.status==3}}>Third</option>
            </select>
          </td>
          <td><a href={{ "/update_status/"~rec.id}}>Update</a></td>
      </tr>
      {% endfor %}
      </tbody>

Thanks!

Upvotes: 24

Views: 35378

Answers (5)

half of a glazier
half of a glazier

Reputation: 2076

Here's another way of setting the selected value dynamically from a passed variable:

route.py

def route():

    roles = ['admin', 'user', 'guest']
    user = get_user('John Doe')
    return render_template('template.html', user=user, roles=roles)

template.html

<!-- more code -->
<div class="form-group">
    <label for="user-role">Role</label>
    <select id="user-role" class="custom-select custom-dropdown custom-form-input">
        {% for role in roles %}
            {% if role == user.role %}
                <option value="{{ role.id }}" selected>{{ role }}</option>
            {% else %}
                <option value="{{ role.id }}">{{ role }}</option>
            {% endif %}
        {% endfor %}
    </select>
</div>
<!-- more code -->

Upvotes: 1

JKoblitz
JKoblitz

Reputation: 91

Just a small addition to the other answers: you can keep it short by using inline conditions:

<option value="zero" {{'selected' if rec.status==0}}>Zero</option>

And if you are using WTForms like mentioned in another answer, you can set the default value in your route function (but don't forget to process the form as described in the wtforms docs):

form = PreviouslyDefinedFlaskForm()
form.task.default = "third"
form.process()

Upvotes: 8

slevin886
slevin886

Reputation: 301

FYI- for HTML 5, selected="selected" becomes just selected like this:

<option value="zero"{% if rec.status==0 %} selected{% endif %}>Zero</option>

Upvotes: 4

Mike Davlantes
Mike Davlantes

Reputation: 1035

For the future Googlers:

If you're using WTForms and want to set the default selection in Jinja, you might dream that something like this could work:

{{ form.gender(class='form-control', value='male') }}

but it doesn't. Neither does default='male' nor selected='male' (at least not for me in Jinja 2.8 and WTForms 2.1).

If you're desperate and don't want to set it in your forms.py and don't mind getting a little hacky, you can do this:

{{ form.gender(class='form-control hacky', value=data['gender']) }}

<script>
    var els = document.getElementsByClassName("hacky");
    for (i = 0; i < els.length; i++) {
        els[i].value = els[i].getAttribute('value');
    }
</script>

This sets it on page load using JavaScript and lets you pass the default selection in the SelectField without having to mess with your forms.py. There's probably a better way of doing this in Jinja, but I haven't found it yet.

Upvotes: 5

Matt Healy
Matt Healy

Reputation: 18531

You're on the right track - but currently, you're printing selected in all the options in your select box. You can try something like this to only print selected on the correct option:

    <select>
      <option value="zero"{% if rec.status==0 %} selected="selected"{% endif %}>Zero</option>
      <option value="first"{% if rec.status==1 %} selected="selected"{% endif %}>First</option>
      <option value="second"{% if rec.status==2 %} selected="selected"{% endif %}>Second</option>
      <option value="third"{% if rec.status==3 %} selected="selected"{% endif %}>Third</option>
    </select>

Upvotes: 34

Related Questions