neelima
neelima

Reputation: 471

How to set the default option for a select field using Jinja templates

I need to add default option value to a select field using Jinja templates.

form.py

class TeamForm(Form):
    user = SelectField(u'Team Member')

views.py

class myview(request,id):
    form = TeamForm(request.form)
    members =db.session.query(teams).filter_by(t_id = id).all()
    return render_template("members.html",form=form,members=members)

member.html

<table>
 {% for member in members%}
 <tr>
     <td>{{ form.user(class_="form-control",value=user.id) }}</td>
 </tr>
 {% endfor %}
</table>

The assigned option value is not shown in the output.

I have to loop the select fields depending upon the members in team. For example, if a team has 3 members, I will display the three select fields and auto select those three members.

Upvotes: 3

Views: 7188

Answers (3)

Hana Koubova
Hana Koubova

Reputation: 1

here is my solution:

.py file:

class CompanyForm(FlaskForm):
   name = StringField(u"Company Name", validators=[Length(max=100)])
   url = StringField(u"Company URL", validators=[Length(max=300)])
   industry = SelectField(u"Industry", validators=[DataRequired()], choices=company_industries, coerce=str)
   submit = SubmitField(label='Submit Information')

HTML:

<form class="edit_form" method="POST" action="{{ url_for('edit_company') }}">     
    
    {{ form.csrf_token }}
    {{ form.name.label(class="form-label") }}
    <br>
    {{ form.name(value=existing_company.name, class_="form-control") }}
    <br>
    {{ form.url.label(class="form-label") }}
    <br>
    {{ form.url(value=existing_company.url, class_="form-control") }}
    <br>

    <!--Custom drop down for industry with selected value-->

    <label for="industry" class="form-label">Industry</label>
    <br>
    <select name="industry" id="industry" class="form-control">
    {% for industry in industries %}
        {% if existing_company.industry == industry %}
            <option selected>{{ industry }}</option>
        {% else %}
            <option>{{ industry }}</option>
        {% endif %}

    {% endfor %}
    </select>
    <br>
    <!--End of custom select field-->

    {{ form.submit(class="btn btn-primary") }}
    
</form>

Upvotes: 0

HenriqueBraz
HenriqueBraz

Reputation: 1

I found a solution that worked perfectly for me.

If you look inside the form object of type SelectField, you will see that Jinja will render as selected the field that is by default.Ex:

type = SelectField('Company Type', choices=type_choices, default=1)

In the example above Jinja will render a select whose option will have a selected value where value=1.

Checking the form object instantiated in my views, I verified that there are three fields to fulfill this condition:

form.type.data = "1" # ---> string
form.type.default = 1 # ---> int
form.type.object_data = 1 # ---> int

So, replacing these three values with data brought from database, inside views, I was able to create a dynamic default select in Jinja, without having to make any changes to my HTML or forms:

form = EnterpriseForm()
result = "query to database"
form.type.data = str(result.id_enterprise_type)
form.type.default = result.id_enterprise_type
form.type.object_data = result.id_enterprise_type

I hope this information helps others.

Upvotes: 0

Malcriado415
Malcriado415

Reputation: 109

You have two questions in play here:

  1. To implement default values in your form, just use the default=(value, label) option for the SelectField class in form.py.

    Assume that you want to default to Johnny as your team member and the numerical value of that option is 0. Then you can do something like this using default=(value, label):

     class TeamForm(Form):
         user = SelectField(u'Team Member', default=(0, "Johnny"))
    

    Just pass in a tuple in the form (value,label). Your values can be int's, strings, whatever. (You're also missing a Submit button, which I assume is accidental.)

  2. I'm not sure what you're doing in your views. You say, "Here I have to loop the select fields depending upon the members in team. For example if team having 3 members, I will display the three select field with auto selected by those three members." Are you saying that you just need to show these to the user in a drop-down field when you render the form, or are you having trouble actually displaying query results to the user when the template is rendered?

    Because you have a form in play, I assume you will be submitting data to a server via a POST. A typical view pattern creates a blank form object and passes it to the user when the template is rendered via a GET request. When the user enters data and submits it, then it is sent via a POST request. I also noticed that you used a class for your views. I suggest using a decorator instead for your routing and have it call a function.

    If, say, you have three options in play in your form and you want to show them to your user in a drop-down, then you'll want to implement something like this:

    form.py:

     # Sample Form class; choices can be overridden later.
    
            class TeamForm(Form):
                 user = SelectField(u'Team Member', default=(0, "Johnny"), choices=[(0, "Johnny"), (1, "Sarah"), (2, "Bill")])
                 submit= SubmitField('Submit')
    

    view.py:

     @app.route('/team', methods=['GET','POST'])
     def team_view(id):
          user_selection = None
          form = TeamForm()
          #  This code block will only execute on POST
          if request.method == 'POST':
               if form.validate_on_submit():
                   user_selection = form.user.data
                   form.user.data = ''
                   return redirect(url_for(some-other-page.html))
          members =db.session.query(teams).filter_by(t_id = id).all()
    
          # This next line will override the default choices in your form.
          form.user.choices = [(member.id, member.name) for member in members]
    
          return render_template("members.html",form=form)
    

    member.html:

    Option 1:

        <!-- Assume you're using Flask-Bootstrap & WTForms -->
         {% import "bootstrap/wtf.html" as wtf %}
    
         <!-- Render your Team form; this is where you call to your form object -->
         {{ wtf.quick_form(form) }}
    

    Option 2:

         <!-- Manually construct your template --> 
     <form method="POST" action="/team">
         <div>{{ form.user }}</div>
         <div>{{ form.submit() }}</div>
     </form>
    

Upvotes: 2

Related Questions