Get selected text from a form using wtforms SelectField
Asked Answered
L

5

12

This is a question upon the use of wtforms SelectField.

Once the form submitted, I wish to extract selected text.

I have the following form:

from wtforms import Form, SelectField
class TestForm(Form):
     hour = SelectField(u'Hour', choices=[('1', '8am'), ('2', '10am') ])

Here's the view:

@app.route('/', methods=['GET', 'POST'])
def test_create():
form =TestForm(request.form)
if request.method == 'POST' and form.validate():
    test = Test()
    form.populate_obj(test)
    test.hour=form.hour.name
    db.session.add(test)
    db.session.commit()
    return redirect(url_for('test_create'))
return render_template('test/edit.html', form=form)

With test.hour=form.hour.name I obtain the attribute name (no surprise...), whilst I need the text (let's say 8am if the first option is chosen).

How should this be possible ? Thanks for any hint.

Levin answered 19/1, 2014 at 13:39 Comment(0)
S
21

Define choices global in forms:

HOUR_CHOICES = [('1', '8am'), ('2', '10am')]

class TestForm(Form):
     hour = SelectField(u'Hour', choices=HOUR_CHOICES)

import it from forms, convert it to dict:

from .forms import HOUR_CHOICES

hour_display = dict(HOUR_CHOICES).get(form.hour.data)
Savarin answered 19/1, 2014 at 13:49 Comment(1)
It doesn't work if the key is an integer! WeirdPhlegmy
L
7

It was answered as a comment, so I'm writing here.

Use form.hour.data to get the value instead of the name.

Lessee answered 19/1, 2014 at 20:59 Comment(0)
M
4

If you don't need the choice indexes, is much more simpler:

class TestForm(Form):
  hour = SelectField(u'Hour', choices=[('8am', '8am'), ('10am', '10am') ])
Merganser answered 20/1, 2014 at 11:3 Comment(1)
Yes, but those choice indexes are almost never important. The indexes are implicit in a list.Covet
S
3

When you set your choices, the list looks like [(index, value),...] so you don't need to import it, and probably shouldn't if setting dynamically

value = dict(form.hour.choices).get(form.hour.data)

Substitute self for form if inside form class

In general, I often zip the choices so index and value are the same. However, sometimes I want to present a displayed selection that's shorter than the value of interest. In that case, I think of it like [(value, display),...] and then the data variable is the value of interest. For example, [(abspath, basename), ...]

Solution answered 21/2, 2017 at 19:58 Comment(0)
A
2

Another option is to get the index from form.hour.data and call it like this:

index = int(form.hour.data)
form.hour.choices[index][1]
Allista answered 19/11, 2017 at 3:53 Comment(1)
More general solution would be to find the element itself: [c for c in form.hour.choices if c[0] == form.hour.data][0] and get the index then: c[1].Stravinsky

© 2022 - 2024 — McMap. All rights reserved.