├── .gitignore ├── README.md ├── bin └── runserver.py ├── fjae ├── __init__.py ├── assets │ └── vehicle.js ├── forms.py ├── settings.py ├── templates │ └── select_vehicle.html └── views.py ├── requirements.txt └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.egg-info 2 | *.pyc 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Flask jQuery AJAX Example (FJAE) 2 | ================================ 3 | 4 | Description 5 | ----------- 6 | When the user selects an item from the vehicle "Make" drop down menu, 7 | the vehicle "Model" drop down menu is populated by making an AJAX 8 | request for a list of models for the make selected. 9 | 10 | Install 11 | ------- 12 | 13 | $ virtualenv fjae 14 | $ source fjae/bin/activate 15 | $ pip install -r requirements.txt 16 | $ pip install -e ./ 17 | 18 | Run 19 | --- 20 | 21 | $ python bin/runserver.py 22 | 23 | Go to http://localhost:5000 in your browser 24 | 25 | Notes 26 | ----- 27 | 28 | - This was tested with Python 2.7.3 on Ubuntu 12.04. 29 | - I know Python better than I know JavaScript. 30 | 31 | Relevant Documentation 32 | ---------------------- 33 | 34 | - [Flask's "AJAX with jQuery"](http://flask.pocoo.org/docs/patterns/jquery/) 35 | - [Flask's MethodView class](http://flask.pocoo.org/docs/views/#method-based-dispatching) 36 | - [Flask's URL Routing](http://flask.pocoo.org/docs/api/#url-route-registrations) 37 | - [WTForms's Field class](http://wtforms.simplecodes.com/docs/1.0.2/fields.html#the-field-base-class) 38 | - [jQuery's .ajax() method](http://api.jquery.com/jQuery.ajax/) 39 | -------------------------------------------------------------------------------- /bin/runserver.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from fjae import run_dev_server 3 | 4 | 5 | run_dev_server() 6 | -------------------------------------------------------------------------------- /fjae/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | 3 | from fjae import views 4 | 5 | 6 | def create_app(): 7 | app = Flask( 8 | __name__, 9 | template_folder='templates', 10 | static_folder='assets', 11 | ) 12 | app.config.from_object('fjae.settings') 13 | app.debug = True 14 | app.add_url_rule( 15 | '/', view_func=views.select_vehicle, methods=['GET', 'POST']) 16 | app.add_url_rule( 17 | '/models//', view_func=views.ModelsAPI.as_view('models_api'), 18 | methods=['GET']) 19 | 20 | return app 21 | 22 | 23 | def run_dev_server(): 24 | app = create_app() 25 | app.run() 26 | -------------------------------------------------------------------------------- /fjae/assets/vehicle.js: -------------------------------------------------------------------------------- 1 | $("#make_select").change(function() { 2 | var make_id = $(this).find(":selected").val(); 3 | var request = $.ajax({ 4 | type: 'GET', 5 | url: '/models/' + make_id + '/', 6 | }); 7 | request.done(function(data){ 8 | var option_list = [["", "--- Select One ---"]].concat(data); 9 | 10 | $("#model_select").empty(); 11 | for (var i = 0; i < option_list.length; i++) { 12 | $("#model_select").append( 13 | $("").attr( 14 | "value", option_list[i][0]).text(option_list[i][1]) 15 | ); 16 | } 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /fjae/forms.py: -------------------------------------------------------------------------------- 1 | from flask.ext.wtf import Form, SelectField 2 | 3 | 4 | class VehicleForm(Form): 5 | make = SelectField(u'', choices=()) 6 | model = SelectField(u'', choices=()) 7 | -------------------------------------------------------------------------------- /fjae/settings.py: -------------------------------------------------------------------------------- 1 | # secret key, needed for csrf protection; generated with import os; os.urandom(24) 2 | SECRET_KEY = "\x94\xa9\xef\x8d\xc8\x18g\x1c\xb5x\xd8\x11\x88'\xf4r\xa5\xbcw\x99\xe0\xda\xb7\x10" 3 | -------------------------------------------------------------------------------- /fjae/templates/select_vehicle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flask Jquery AJAX Drop Down Menu Example 6 | 7 | 8 |

Select Vehicle

9 |
10 | {{ form.hidden_tag() }} 11 | 15 | 16 |
17 | 18 | {% if chosen_make %} 19 |

You selected:

20 | 24 | {% endif %} 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /fjae/views.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from flask import request, render_template, make_response 4 | from flask.views import MethodView 5 | 6 | from fjae.forms import VehicleForm 7 | 8 | 9 | MAKE_LIST = ( 10 | {'make_id': 1, 'name': 'Honda'}, 11 | {'make_id': 2, 'name': 'Ford'}, 12 | {'make_id': 3, 'name': 'BMW'}, 13 | ) 14 | MODEL_LIST = ( 15 | {'model_id': 1, 'make_id': 1, 'name': 'Fit'}, 16 | {'model_id': 2, 'make_id': 1, 'name': 'Civic'}, 17 | {'model_id': 3, 'make_id': 1, 'name': 'Accord'}, 18 | {'model_id': 4, 'make_id': 1, 'name': 'Pilot'}, 19 | {'model_id': 5, 'make_id': 2, 'name': 'Mustang'}, 20 | {'model_id': 6, 'make_id': 2, 'name': 'F-150'}, 21 | {'model_id': 7, 'make_id': 2, 'name': 'Focus'}, 22 | {'model_id': 8, 'make_id': 2, 'name': 'Escape'}, 23 | {'model_id': 9, 'make_id': 3, 'name': '1-Series'}, 24 | {'model_id': 10, 'make_id': 3, 'name': '3-Series'}, 25 | {'model_id': 11, 'make_id': 3, 'name': '5-Series'}, 26 | {'model_id': 12, 'make_id': 3, 'name': '7-Series'}, 27 | ) 28 | 29 | 30 | def select_vehicle(): 31 | """ 32 | Render a vehicle selection form and handle form submission 33 | """ 34 | form = VehicleForm(request.form) 35 | form.make.choices = [('', '--- Select One ---')] + [ 36 | (x['make_id'], x['name']) for x in MAKE_LIST] 37 | chosen_make = None 38 | chosen_model = None 39 | 40 | if request.method == 'POST': 41 | chosen_make = form.make.data 42 | chosen_model = form.model.data 43 | 44 | context = { 45 | 'form': form, 46 | 'chosen_make': chosen_make, 47 | 'chosen_model': chosen_model, 48 | } 49 | return render_template('select_vehicle.html', **context) 50 | 51 | 52 | class ModelsAPI(MethodView): 53 | def get(self, make_id): 54 | """ 55 | Handle a GET request at /models// 56 | Return a list of 2-tuples (, ) 57 | """ 58 | data = [ 59 | (x['model_id'], x['name']) for x in MODEL_LIST 60 | if x['make_id'] == make_id] 61 | response = make_response(json.dumps(data)) 62 | response.content_type = 'application/json' 63 | return response 64 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==0.9 2 | Flask-WTF==0.8.2 3 | Jinja2==2.6 4 | WTForms==1.0.2 5 | Werkzeug==0.8.3 6 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | 4 | setup( 5 | name="flask-jquery-ajax-example", 6 | version="0.1.0", 7 | packages=find_packages(), 8 | author="Eliot", 9 | author_email="saltycrane@gmail.com", 10 | ) 11 | --------------------------------------------------------------------------------