I am using wtforms SelectMultipleField to render a form with a list of choices.
Using a plain vanilla SelectField renders the choices as a drop-down ( dropdown ).
However, I need to be able to select multiple entries in the list, hence want to use SelectMultipleField. This, however, displays as a listbox ( listbox ).
This is my code for the form entries: test = SelectMultipleField('test', choices=[(1, 'a'), (2, 'b'), (3, 'c')])
Code to render: <a class="test" id="test">{{ form.test }}</a>
How can I render my SelectMultipleField to display as a dropdown?
(I'm still looking for more 'vanilla' solutions, this one depends on some JQuery library (maybe this library exists because there are no vanilla ways))
main.py:
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms.fields import SelectMultipleField, SubmitField
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret_key'
choices = [
'apple',
'banana',
'carrot',
]
class Form(FlaskForm):
global choices
select_multiple_field = SelectMultipleField(choices=choices)
submit = SubmitField()
@app.route('/', methods=['GET', 'POST'])
def index():
form = Form()
if request.method == 'POST':
# Getting selected options
form_data = form.select_multiple_field.data
print(form_data)
return render_template(
'index.html',
form=form,
)
if __name__ == "__main__":
app.run(debug=True)
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://unpkg.com/multiple-select@1.5.2/dist/multiple-select.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
<script src="https://unpkg.com/multiple-select@1.5.2/dist/multiple-select.min.js"></script>
</head>
<body>
<style>
select {
width: 20%;
}
</style>
<form action="{{ url_for('index') }}" method="POST">
{{ form.hidden_tag() }}
{{ form.select_multiple_field(**{"multiple": "multiple"}) }}
{{ form.submit }}
</form>
<script>
$(function () {
$('select').multipleSelect({
multiple: true,
multipleWidth: 60
})
})
</script>
</body>
</html>
(feel free to contact me if this answer was not exactly what you are looking for and tell why so, I'll try to adjust it:D)
There is a solution but it is completely custom that doesn't depend on how wtf forms display the field, that's why it probably doesn't behave like normal wtf forms input. It is useful to customize each part in the field and how to display it
1- Create a custom macro to display the field [create a file named macros.html and place it inside the templates folder]
macros.html
{% macro multi_bootstrap_select_field(field, class="", options_classes="") %}
{% if field %}
{{ field.label }}: <select {% if field.id %}id="{{field.id}}"{% endif %} {% if field.name %}name="{{field.name}}"{% endif %} {% if class %} class="{{class}}"{% endif %} {% if field.placeholder %} placeholder="{{field.placeholder}}"{% endif %} {% if field.flags.required %}"required=required"{%endif%} {% if field.type|lower == 'selectmultiplefield' or field.type|lower == 'multicheckboxfield' %}multiple="multiple"{% endif %}>
{% if field.choices %}
{% for choice_index in range(field.choices|length) %}
{% if field.choices[choice_index]|length == 2 %}
<option {% if field.name %}name="{{field.name}}"{% endif %} value="{{field.choices[choice_index][0]}}">{{field.choices[choice_index][1]}}</option>
{% endif %}
{% endfor %}
{% endif %}
</select>
{% for error in field.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
{% endif %}
{% endmacro %}
2- Import "macros.html" into the page containing the field
index.html
{% from 'macros.html' multi_bootstrap_select_field %}
{{ multi_bootstrap_select_field(form.nums, class="form-control") }}
forms.py
from flask_wtf import FlaskForm
from wtforms import SubmitField, SelectMultipleField, widgets
from wtforms.validators import InputRequired
class MultiCheckboxField(SelectMultipleField):
widget = widgets.ListWidget(prefix_label=False)
option_widget = widgets.CheckboxInput()
class addLyrics(FlaskForm):
nums = MultiCheckboxField('Tags',
coerce=str,
choices=[(1, 'one'), (2, 'two'), (3, 'three')],
validators=[InputRequired()])
submit = SubmitField("Create")
If you are going to pass additional arguments, you need to define them in your custom macro function
for example
{% macro multi_bootstrap_select_field(field, class="", options_classes="", placeholder="") %}
{{ multi_bootstrap_select_field(form.nums, class="form-control", placeholder="something") }}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.