Skip to content

Instantly share code, notes, and snippets.

@arthuralvim
Forked from imwilsonxu/app.py
Created January 3, 2020 13:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arthuralvim/95df5624d5246bdb8dde47ac055484ad to your computer and use it in GitHub Desktop.
Save arthuralvim/95df5624d5246bdb8dde47ac055484ad to your computer and use it in GitHub Desktop.
[Flask + Wtforms + Select2] #flask
# -*- coding: utf-8 -*-
from flask import Flask, request, render_template, current_app
from flask_wtf import Form
from wtforms.validators import DataRequired
from wtforms import SelectField, SelectMultipleField, SubmitField
app = Flask(__name__)
app.config.update(dict(
SECRET_KEY = 'your_secret_key',
CSRF_ENABLED = True,
))
class Select2MultipleField(SelectMultipleField):
def pre_validate(self, form):
# Prevent "not a valid choice" error
pass
def process_formdata(self, valuelist):
if valuelist:
self.data = ",".join(valuelist)
else:
self.data = ""
class DemoForm(Form):
single_select = SelectField(u"单选", [DataRequired()],
choices=[("py", "python"), ("rb", "ruby"), ("js", "javascript")],
description=u"有限选项。无效化。",
render_kw={"disabled": "true"})
single_dynamic_select = SelectField(u"单选", [DataRequired()],
choices=[("0", "")],
description=u"动态加载选项。",
render_kw={})
multi_select = Select2MultipleField(u"选择框", [],
choices=[("py", "python"), ("rb", "ruby"), ("js", "javascript")],
description=u"多选。有限选项。",
render_kw={"multiple": "multiple"})
tags = Select2MultipleField(u'标签', [],
choices=[("py", "python"), ("rb", "ruby"), ("js", "javascript")],
description=u"多选。无限选项。",
render_kw={"multiple": "multiple", "data-tags": "1"})
submit = SubmitField()
@app.route("/demo", methods=["GET", "POST"])
def demo():
form = DemoForm(request.form)
if form.validate_on_submit():
current_app.logger.debug(form.data)
return render_template("demo.html", form=form)
if __name__ == "__main__":
app.run(debug=True)
<!DOCTYPE html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Demo: Flask + Wtforms + Select2</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/css/bootstrap-select.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet">
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1>Demo: Flask + Wtforms + Select2</h1>
<hr>
<form action="{{ url_for('demo') }}" method="post">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.single_select.label }}
<small class="text-muted">{{ form.single_select.description }}</small>
{{ form.single_select(class_="form-control") }}
{% for error in form.single_select.errors %}
<span class="label label-danger">{{ error }}</span>
{% endfor %}
</div>
<div class="form-group">
{{ form.single_dynamic_select.label }}
<small class="text-muted">{{ form.single_dynamic_select.description }}</small>
{{ form.single_dynamic_select(class_="form-control") }}
{% for error in form.single_dynamic_select.errors %}
<span class="label label-danger">{{ error }}</span>
{% endfor %}
</div>
<div class="form-group">
{{ form.multi_select.label }}
<small class="text-muted">{{ form.multi_select.description }}</small>
{{ form.multi_select(class_="form-control") }}
{% for error in form.multi_select.errors %}
<span class="label label-danger">{{ error }}</span>
{% endfor %}
</div>
<div class="form-group">
{{ form.tags.label }}
<small class="text-muted">{{ form.tags.description }}</small>
{{ form.tags(class_="form-control") }}
{% for error in form.tags.errors %}
<span class="label label-danger">{{ error }}</span>
{% endfor %}
</div>
{{ form.submit(class_="btn btn-primary") }}
</form>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/js/bootstrap-select.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// https://select2.github.io/examples.html
$("select").select2({});
function formatRepo (repo) {
if (repo.loading) return repo.text;
var markup = "<div class='select2-result-repository clearfix'>" +
"<div class='select2-result-repository__avatar'><img src='" + repo.owner.avatar_url + "' /></div>" +
"<div class='select2-result-repository__meta'>" +
"<div class='select2-result-repository__title'>" + repo.full_name + "</div>";
if (repo.description) {
markup += "<div class='select2-result-repository__description'>" + repo.description + "</div>";
}
markup += "<div class='select2-result-repository__statistics'>" +
"<div class='select2-result-repository__forks'><i class='fa fa-flash'></i> " + repo.forks_count + " Forks</div>" +
"<div class='select2-result-repository__stargazers'><i class='fa fa-star'></i> " + repo.stargazers_count + " Stars</div>" +
"<div class='select2-result-repository__watchers'><i class='fa fa-eye'></i> " + repo.watchers_count + " Watchers</div>" +
"</div>" +
"</div></div>";
return markup;
}
function formatRepoSelection (repo) {
return repo.full_name || repo.text;
}
$("#single_dynamic_select").select2({
ajax: {
url: "https://api.github.com/search/repositories",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {
// parse the results into the format expected by Select2
// since we are using custom formatting functions we do not need to
// alter the remote JSON data, except to indicate that infinite
// scrolling can be used
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
minimumInputLength: 1,
templateResult: formatRepo, // omitted for brevity, see the source of this page
templateSelection: formatRepoSelection // omitted for brevity, see the source of this page
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment