3

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.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
neelima
  • 461
  • 10
  • 25
  • Why don't you provide 'choices' to your SelectField definition? – Amin Alaee Jul 07 '16 at 07:25
  • Because of choices are dynamic. each team have different members, so each time choices are changed. – neelima Jul 07 '16 at 08:37
  • You can generate dynamic choices in your myview like this http://stackoverflow.com/questions/12850605/how-do-i-generate-dynamic-fields-in-wtforms – Amin Alaee Jul 07 '16 at 09:19
  • My issue is not for choices, my issue is every select field shows top option, but I need to display member of the team is a default option for select field. – neelima Jul 07 '16 at 10:21

2 Answers2

2

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>
    
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Malcriado415
  • 109
  • 1
  • 7
  • for example here 5 users are there. these 5 users are choices, but team 'A' having 3 members, those are 1,2,5. remaining users are not in the team. Now we have to display the three members of team 'A'. In- details select-field1---> shows--->1, select-field2--->shows--->2,select-field3--->shows--->5 like that. – neelima Jul 07 '16 at 09:15
  • Present I have show the users in dropdown, but my problems is "the three team members are the selected values of the select fields". Now you can understand my issue I think. Thanks. – neelima Jul 08 '16 at 04:35
  • Ok, I tried editing my suggested code. See what I did. Good luck! – Malcriado415 Jul 08 '16 at 08:57
0

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.

  • Please don't add answers unless you intend to use yours as the selected solution. If you don't then upvote and select the solution that answered the question. – the Tin Man Jan 18 '22 at 20:46
  • ok, but is a valid solution too, isn't? My idea is help others with similar problems :) – HenriqueBraz Jan 28 '22 at 21:10