Flask & WTForms: DatePicker Widget to display a date

jjjayn picture jjjayn · Oct 6, 2015 · Viewed 16.7k times · Source

I have a small Flask app which has three fields (Destination, Start Time and End Time). I'd like to use DatePicker widget to display the calender when selecting start and end dates.

With my current scripts the date widget doesn't spawn at all. What am I missing here?

app.py:

# -*- coding: utf-8 -*- 

from flask.ext.wtf import Form
from wtforms import SubmitField, SelectField, DateField
from flask import Flask, render_template, request
from flask.ext.bootstrap import Bootstrap
from flask.ext.admin.form.widgets import DatePickerWidget

class GeneralForm(Form):
    destination = SelectField(choices = data)
    start_time = DateField('Start at', widget=DatePickerWidget())
    end_time = DateField('End at', widget=DatePickerWidget())
    submit = SubmitField('Submit')

@app.route("/", methods=['GET', 'POST'])
def index():
    form = GeneralForm(request.form)
    if request.method == 'POST':
        destination = form.destination.data
        start_time = form.start_time.data
        end_time = form.end_time.data
        return render_template('page.html', form=form)
    else:
        return render_template('index.html', form=form)

bootstrap = Bootstrap(app)
if __name__ == '__main__':
    app.run(debug=True)

index.html:

<link rel="stylesheet"
      href="{{url_for('.static', filename='mystyle.css')}}">
<link rel="stylesheet"
      href="{{url_for('.static', filename='datepicker.css')}}">
<link rel="javascript"
      href="{{url_for('.static', filename='main.js')}}">
<link rel="javascript"
      href="{{url_for('.static', filename='bootstrap-datepicker.js')}}"

<form action="#" method="post">
     {{ form.destination }}
     {{ form.start_time(class='datepicker') }}
     {{ form.end_time(class='datepicker') }}
     {{ form.submit }}
</form>

Answer

Dauros picture Dauros · Oct 15, 2015

Flask-Admin's DatePickerWidget() basically adds data-date-format="YYYY-MM-DD" data-role="datepicker" attributes to an input field. After that a custom JavaScript function located in flask_admin/static/admin/js/form.js activates the Bootstrap-Datepicker widget on these fields.

So you need to include this script in your template (or write your own). Add this line at the top of your template, which includes a helper macro:

{% import 'admin/static.html' as admin_static with context %}

and then you can include the form.js via adding these lines into your template (this script requires moment.js as well):

<script src="{{ admin_static.url(filename='vendor/moment.min.js') }}"></script>
<script src="{{ admin_static.url(filename='admin/js/form.js') }}"></script>

Note: You can also use the Bootstrap-Datepicker js and css files shipped with Flask-Admin. See the form_css() and form_js() macros in flask_admin/templates/bootstrap3/admin/lib.html and copy the corresponding lines into your template.