How can I add a Flask/WTForms SelectField to my HTML? - python

I am building a form in my Flask app and want the users to be able to select an option from a <select> menu.
For example:
<select>
<option>Banana</option>
<option>Pineapple</option>
</select>
My current "HTML" for this is
<form action="{{ url_for('contact') }}" method=post>
{{ form.hidden_tag() }}
{{ form.name.label }}
{{ form.name }}
{{ form.company.label }}
{{ form.company }}
{{ form.email.label }}
{{ form.email }}
{{ form.phone.label }}
{{ form.phone }}
{{ form.message.label }}
{{ form.message }}
{{ form.submit }}
</form>
My Python Class for this form is:
class ContactForm(Form):
partner_type = SelectField(
u'Industry Type',
choices = [('Software', 'software'), ('Sales', 'sales')]
)
name = TextField("Name", [validators.Required("Please enter your full name.")])
email = TextField("Email", [validators.Required("Please enter a valid email i.e. you#yourdomain.com"), validators.Email()])
phone = TextField("Phone", [validators.Required("Please enter a valid phone number.")])
company = TextField("Company", [validators.Required("Please enter your company name.")])
message = TextAreaField("Message", [validators.Required("Please include a message regarding this submission.")])
submit = SubmitField("Send")
This all works great for text fields and submit button but I can't seem to figure out how to properly render the <select> options to the form. I tried following the syntax above by doing:
{{ form.industry_type.label }}
{{ form.industry_type }}
but that didn't work. It just added the label and no drop down selector. Is there a proper way to add this to the DOM? The options are static, preset options, so there's nothing dynamic or complex about the list I am trying to render.
Thanks for the help. I am very new to Python so I am still figuring a lot of things out.

You should be using:
{{ form.partner_type.label }}
{{ form.partner_type }}
instead of:
{{ form.industry_type.label }}
{{ form.industry_type }}
The field name in the form is the variable name it is assigned to, not the label in the constructor of the SelectField.

Related

Flask WTForms {{ form.input(value=something.something) }}

I'm trying to render an html form and pass in a table row with sqlalchemy. So then the form will show up with all it's input fields filled with the row data, with the purpose of editing and sending it back to the db. But somehow the form is displaying only two input fields, both of type text. Integer fields and radio fields are not showing the row's each corresponding value, although the values exist and are not none.
Here's the route:
#app.route('/editar/<string:id>')
def hotel_edit(id):
form = HotelForm()
viaje = arribos.query.get(id)
return render_template('edit_hotel.html', form=form, viaje=viaje)
Here's the html file displaying the wtform object + trying to get the object "viaje" to show the values with no luck:
{% block body %}
<div id="main_form">
<form action="/" method="post" id="ingresos">
{{ form.hidden_tag() }}
<fieldset>
<div class="checks" id="inout">
{{ form.check.label }}
{{ form.check(value=viaje.check) }}
</div>
<div class="horafecha">
{{ form.fecha.label }}
{{ form.fecha(value=viaje.fecha) }}
{{ form.hora.label }}
{{ form.hora(value=viaje.hora) }}
</div>
<div class="textbox">
{{ form.vuelo.label(class="inputtext") }}
{{ form.vuelo(class="inputtext", value=viaje.vuelo) }}
{{ form.habitacion.label(class="inputtext") }}
{{ form.habitacion(class="inputtext", value=viaje.habitacion) }}
{{ form.huespedes.label(class="inputtext") }}
{{ form.huespedes(class="inputtext", value=viaje.huespedes) }}
{{ form.valijas.label(class="inputtext") }}
{{ form.valijas(class="inputtext", value=viaje.valijas) }}
</div>
<div class="checks" id="puerto">
{{ form.puerto.label(class="puertos") }}
{{ form.puerto(class="puertos", value=viaje.puerto) }}
</div>
<div class="buttons">
{{ form.enviar }}
</div>
</fieldset>
</form>
</div>
{% endblock %}
And here's the form (not styled yet):
form
As you can see, most of the input fields are missing the value. Does anyone know how to fix this?
Also: I can show you the form.py file that has the class definition for the entire form, if that helps.
You can populate the form before it's sent to the jinja template from within your route. It would look something like this:
#app.route('/editar/<string:id>')
def hotel_edit(id):
form = HotelForm()
viaje = arribos.query.get(id)
form.check.data = viaje.check
form.fecha.data = viaje.fecha
form.hora.data = viaje.hora
...
return render_template('edit_hotel.html', form=form)
You can then just refer to the form field without passing the value arg.
{% block body %}
<div id="main_form">
<form action="/" method="post" id="ingresos">
{{ form.hidden_tag() }}
<fieldset>
<div class="checks" id="inout">
{{ form.check.label }}
{{ form.check() }}
</div>
<div class="horafecha">
{{ form.fecha.label }}
{{ form.fecha() }}
{{ form.hora.label }}
{{ form.hora() }}
</div>
<div class="textbox">
{{ form.vuelo.label(class="inputtext") }}
{{ form.vuelo(class="inputtext") }}
{{ form.habitacion.label(class="inputtext") }}
{{ form.habitacion(class="inputtext") }}
{{ form.huespedes.label(class="inputtext") }}
{{ form.huespedes(class="inputtext") }}
{{ form.valijas.label(class="inputtext") }}
{{ form.valijas(class="inputtext") }}
</div>
<div class="checks" id="puerto">
{{ form.puerto.label(class="puertos") }}
{{ form.puerto(class="puertos") }}
</div>
<div class="buttons">
{{ form.enviar }}
</div>
</fieldset>
</form>
</div>
{% endblock %}

Making a form display only for a certain value in a SelectField

i'm a beginner in working with flask.Trying to make a simple cash register app , and i need to make a form display on the page only for a certain value from a SelectField form. Im using wtforms and python !Thanks
#AlexisG I didn't actually tried anything , i just looked around the net for a solution.
#prabh i will put below part of the code to explain better
Blockquote
{{ form.tip.label }}
{{ form.tip }}
{{ form.modplata.label }}
{{ form.modplata }}
{{ form.suma.label }}
{{ form.suma(size=7) }}
{% if form.suma.errors %}
<span style="color:red">{{ form.suma.errors[1] }}</span>
{% endif %}
{{ form.nume.label }}
{{ form.nume(size=20) }}
{{ form.submit }}
form.tip is a SelectField form with 4 choices , i'm trying to make another SelectField form to display in html without refreshing the page for a certain choice in form.tip ! Hope i was clear . Thank you!

Flask-WTF form Validtaion failed

Jinja Template Code
<form method="POST">
{{ form.name.label }} {{ form.name() }}
{{ form.submit() }}
</form>
Form Class
class NameForm(FlaskForm):
name = StringField('What is your name?', validators=[Required()])
submit = SubmitField('Submit')
pdb> request.form
ImmutableMultiDict([('name', 'rohit'), ('submit', 'Submit')])
form.validate_on_submit() is returning False instead of True.
Fr the above to work you also need to add protection against cross-site referencing in the HTML code. Adding this line
{{ form.hidden_tag() }}
might solve the problem.

Jinja2 macros argument doesn't expand

I have a macro that's defined like this:
{% macro render_row (class_suffix, form, field) %}
<div class="form-{{ class_suffix }}__row">{{ form.field.label }} {{ form.field() }}</div>
{% endmacro %}
I want to pass a form object and a field parameter to render a specific row, like this:
{% import "macros.html" as macros %}
...
<div class="form-container">
<h2>Sign In</h2>
<form class="form-login" action="{{ url_for('signin') }}" method="post">
{{ macros.render_row ('login', form, email) }}
{{ macros.render_row ('login', form, password) }}
{{ macros.render_submit ('login', 'Sign In') }}
{{ form.csrf_token }}
</form>
</div>
For example, macros.render_row ('login', form, email) should be expanded to:
<div class="form-login__row">{{ form.email.label }} {{ form.email() }}</div>
Instead, I get this error:
jinja2.exceptions.UndefinedError: 'blog.forms.SignInForm object' has no attribute 'field'
Form's defined like this:
class SignInForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email(), Length(max=64)])
password = PasswordField('Password', validators=[DataRequired(), Length(min=8, max=64)])
I've also found a solution, but I'm curious why previous method doesn't work.
{% macro render_row (class_suffix, form_field) %}
<div class="form-{{ class_suffix }}__row">{{ form_field.label }} {{ form_field() }}</div>
{% endmacro %}
...
{{ macros.render_row ('login', form.email) }}
Is it possible to do? What am I doing wrong? Is it even a good practice to do something like this?
That's because Jinja2 tries to get the property named field from the form object passed, not the field which name equals to the variable field passed.
It tries to do
{{ foo.field }}
{{ foo['field'] }}
But for your case, it will work only using this syntax, of course.
{{ foo[field] }}
Where field param for the macros should be a string I believe, now I think that's None.
So it should be
{{ macros.render_row ('login', form, 'email') }}
and the definition of the macro like
{% macro render_row (class_suffix, form, field) %}
<div class="form-{{ class_suffix }}__row">{{ form[field].label }} {{ form[field]() }}</div>
{% endmacro %}
Check more details on the variable's syntax page https://jinja.palletsprojects.com/en/2.10.x/templates/#variables.
I haven't tested it in real files, not have Jinja2 installed in my hands. But it should be working like that.

Django label_tag required asterisk

I am currently working on some Django templates and would like to put an asterisk after the label of required fields.
First of all I have found this syntax which works just fine but it makes me type a lot of code that is not required without the required asterisk.
<div>
{{ field.errors }}
<label for="{{ field.auto_id }}">
{% if field.field.required %}<span class="required">{{ field.label }}</span>
{% else %}{{ field.label }}{% endif %}
</label>
{{ field }}
</div>
This is the code I currently have in my template:
<div>
{{ field.errors }}
{{ field.label_tag }}{{ field }}
</div>
This way it saves a lot of code to write, but I can't figure out how to get the asterisk after the label with a required field.
Could someone help me with this?
If you need some more info feel free to ask.
Have you tried setting the required_css_class = 'something' on the form (cf here) Then using css you could add a red asterisk on the label
Consider writing a template tag that takes in field and returns field.label suffixed with an asterisk if the field is required, and field.label if not. And you can use like so:
<div>
{{ field.errors }}
{{ field | append_ast_if_req }}
{{ field }}
</div>
Your template tag can be:
#register.filter
def append_ast_if_req (field):
if field.field.required:
return field.label + '*'
else:
return field.label

Categories

Resources