Creating a Dynamic Select Field With Flask-WTF and JavaScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone its Anthony from pretty printed here in today's video I'll be talking about how to create dependent dropdowns in flask WT forms or a flask WTF and flask sequel alchemy so what I mean by the pendant drop-down is simply that one drop-down controls the options and another drop-down so in the example that I'm going to create I'm gonna have a state drop-down so you'll be able to choose a state let's say California and then from there you'll have cities in California in the next drop-down so that's exactly what I'll be doing in this video so to begin I have a little bit of code ready I have the imports that I'll need for this I have my database configuration the secret key configuration I also have my database model so if I just go into the table that I have so tests dot DB and then look at the tables I see there's one table of the city table and if I select star from the city I see four cities Las Vegas in Reno which are both in the state of Nevada and then I have Los Angeles and San Diego in the state of California in a real example you'd probably have a table for the states as well but this is just a bare-bones example to get you started I don't want to build out a fully featured one but this should give you an idea of how to approach this and you should be able to apply it to any dependent drop-down that you want so this is going to involve using a little bit of JavaScript and fetch and we'll see how it works in just a moment so the first thing I want to do is I want to create a form so I will create a form and I'll just call this form so this form is going to have both the state select and the city slick so the dropdowns so I need to inherit from flask form and then I'll create two fields so state in City so city is going to be a select field and the choices already know so like I said this would probably be better in the database but since this is a simple example this first drop-down won't be from the database but the second one will so choices needs to be a list of tuples so in this case I want California as one of the options and then I want Nevada as the other so Envy for Nevada and see for California and with the tuples the first value is the value of the option and then the second is the actual text that you see and then the city is also going to be a select field but with a city I won't use any choices here and the reason why I won't use choices is because it's going to depend on whatever is a state so I'm going to initialize it to be the states or the cities from California but just know that the reason why I'm leaving it blank is because the whole point of it is it depends on whatever state is selected so I'll go ahead and create a route and this just will be on the index and I already know it's going to have the methods get in post because I'm going to be posting the form here and then what I'll do is out instantiate the form so form equals form and then what I want to do is I want to feel in the choices for the city so like I said I want to initialize this to be the cities in California because that's my first choice so what I'm going to do is I'm going to use form dot city dot choices so as you can see I'm basically just modifying directly the choices here and I need to have a list of tuples so what I'm going to do is I'm going to use a list comprehension and the first part I'll write is the query to get the data so it's going to be City that query da filter by and then I want to filter by the state equals CA so as you saw from my database I closed it already but as you start from my database I have the two letter code for the state column so it can either be C or in V in this case I'm using CA and I want to get all the results so this is the query that I'll be using and then what I want to do is I want to say for city in this so this is going to return all the cities that I have in this particular case I have four cities in the database and it's going to loop over those four and this is going to be the variable I use and since this is a list comprehension the final output is going to go all the way to the left and I remember I said it needs to be a list of tuples so for each city I'm going to create a tuple and the tuple is pretty simple so I'm going to have a city dot ID because I want to use the IB for the city from the model and then I'm going to have the display text be the name of the city so city dot name so this is just going to create a list of tuples with the city ID as the first part of the tuple and the city name is the second part of the tuple and you'll see that it kind of follows along the same style as this instead of letters though for the first part it's going to be numbers since I'm using the IDs from the database okay so now that I have that what I want to do is I want to render this template so render template and then I have an index.html template and I'll pass my form to that template and if I go to my index.html you see I don't have much so far so what I'll do is I will create the form method equals posts I don't need to put an action because it's going to be on the same endpoint and then I'll just use the form variables that I have so the cross-site request forgery token is one and then the state is another and then the city is the last one I'll put just a really simple submit button here and then that should in my form so everything looks good here so now what I'll do is I'll start up the app and I'll go to the page okay so we see let me zoom in a bit we see the drop down for California so this select I have California in Nevada and then I have Los Angeles and San Diego here and this Los Angeles and San Diego are generated by that query so if I go here and I change the states to you envy then I should see Las Vegas in Reno and that's exactly what I see so I'll change it back to California because that's what I wanted to start off as and then what I'll do is let's allow for the form to be submitted so requests stop method equals posts and what I'm going to do is I'm simply going to return some text for the state in the city so return I'll use a h1 tag so the state is going to be blank and then the city so city is going to be blank and then our format this with form state data since it's the only representation of a state that I have and for the second part here I'll create a new variable called city that's going to have the city name and I'm going to get that city name from the ID that is passed through the city drop-down so City equals City query filter by ID equals form City data and then give me the first result so let's see if that works as expected so California Los Angeles let's say I change this to San Diego and I hit submit query I see state CA city San Diego okay so that's almost well that's everything we need for the form itself but of course when I change States I don't have an updated list of cities so like Nevada and in Los Angeles as far as I know there is no Los Angeles in Nevada so the important part of this is how do I get the code for switching this up so there are two things that I need to do I need to write some JavaScript to request for the additional cities and then update that list with the new cities and I also need to create a route in flask to give me those cities so I'll start with our route first so I'll create a new route I'll call this city and I'll allow it to take a variable so the variable in this case is going to be a state so anytime you are passing a variable through the URL you have to use a parameter in the route function and what I want to do is I want to basically query the database for all the cities that I have for the particular state that's passed in and then I want to pass those cities back to whatever is calling this so I'm going to first query for the cities so I'll say cities equals city dot query filter by and then state is going to be equal to state and then I want all the results so if I pass in Nevada here it's going to give me all the cities in Nevada so Reno and Las Vegas I passed in California CA it's going to give me Los Angeles and San Diego again so now for each city I'm going to do a little bit processing and I'm going to append it to a master list so I'll call this masterless City array and it's going to be initialized some link and then what I'm going to do is loop over these cities that I got from the query so for city in cities what I want to do is to create a new city object for each city so I'll create a something called like City object like that is going to be a dictionary and then I'm going to add the ID and the name to that object so ID for the city is city ID and then the name for the city is going to be city dot name once again this is just from my city model and then I'm going to append this city object to my master city array so City array I'm calling it an array because I'll be using an in JavaScript and same for object so it's actually a list but I'm thinking JavaScript right now but you know they're equivalent a list and a array or equivalent so I'll pass in a city object just like that to append so for each city is just going to append on to this city array and then finally I'll return a sonna fight version of this I need to pass a dictionary and I want the dictionary to be cities and then I'll pass in that city all right just like that so now I'll go to this end point directly so slash city slash envy and I see I have two cities here the ID for Las Vegas is one the ID for Reno is two if I changed Nevada NV to CA for California I see I have Los Angeles and San Diego here so ID three for Los Angeles and ID 4 for San Diego so that's all I have to do on the flat side of things and the reason why I created that is because I need to basically call that route every time the Select for the state changes and to know that it changed I have to use some JavaScript to basically put a listener on that drop-down so I'll create script text here I'm just gonna put everything in one file and the first thing I want to do is I want to get the actual objects for the state select and the city select so I'll create two variables so States select it's going to be equal to document let's see get element by ID and then state and then I'll do the same for the city select and I just need to get these two because I need a way to modify them so like I said I want to trigger the change on the so I'll go back I want to trigger the change of these options whenever I change this option so whenever I change the state drop-down I want the cities to update so to do that I'm going to put an on change listener on the state select so state select that on change and I'll create a function to handle this and then inside the function what I'm going to do is I'm first going to get the value of the states so state equals state select value and what I'll do is I'll alert the state's so we can see that it appears correct so I'll refresh the page and then now that I have the on change event every time I change it I get the alert I see envy is here if I change it back to California I get ca so I know the on change is working and I know I can actually get the value of the select box so once I have the value of it so I know which state they just selected I want to fetch the city's for that state so to do that I'll use fetch and I just pass in the endpoint and so in this particular case it's City and then there's a variable parts to it so state so this is the same city that I just created here so city / state is a variable and here is just a JavaScript equivalent so then this is just getting the response for calling that particular endpoint and inside of here what I can do is I can convert the response so this is a response object so it's not the data that I want yet but I can transform that data into a JSON object so response dot JSON and then then again and then this anonymous function is going to take in the data and that's going to represent the JSON version of the response so what I'll do is I will alert the data so you can see it okay so object objects so it'd be better if I use the console so it's console dot table and then if I do that again I see down here it's a little hard to see but inside of cities I have Las Vegas as one and Reno s too so I switched it to Nevada I change it back to California then down here I see Los Angeles and San Diego there so now that I know that I have the data what I want to do is I want to loop through all of the the cities and the data so what I'll do is I'll say for let's see you let's city of data dot cities so I have an array of cities and the cities comes from the cities here from flask I'm going to loop over it and I want you to construct some new HTML for the drop-down list so what I'll do is before the loop here I'll create a variable called option HTML and it's going to start off as being nothing and what I'm going to do is I'm going to pin to this option HTML for every loop and basically the option HTML just has the option so if I look at the source for any drop-down we see that it's basically option value whether you want the user to see and then same thing for all of them and they go in between the select X so the option hTML is going to be so I'm going to append basically what I just said so I'm going to create an option and then a value and then I'm going to add in the city dot ID as the value and close this out and then I also need to add in the description for the city so the name of the city so city dot name and then close out the option here so even though I'm putting variables inside you can see that I have the option tax here I'm just using the variables because it's a pretty easy way to inject the data inside of here so I see option value I have the quotes for the value and it has the city ID and then the city name is going to be in between the option tags and the very last thing I need to do is I need to update that City select to use this new option HTML instead of the old so to do that I'm going to use City select inner HTML and it's just going to be set equal to option HTML so this is going to overwrite the OH innerhtml which is the options for the original see original cities and it's going to update it with whatever the data is that was returned from the fit recall so if I do this again if I changed Nevada I see it changes to Las Vegas in Reno if I change to California again Los Angeles San Diego back to Nevada Las Vegas and Reno so as you can see it's pretty easy and principled there are some things you can add to this of course you know you can check for error cases but I just want to keep this simple just to keep the video short but this is basically the process so finally let's just see if it's amidst the data so if I go to Nevada and then Reno hit submit query I see Nevada City Reno if I use Nevada in the Las Vegas cement I see Las Vegas if I go to Nevada and then come back to California and I go to San Diego hit submit I see everything is working correctly so that's all I wants to cover in this video I'll post a link to this code in the description below if you want to take a look at it for yourself and modify it if you have any questions about anything I didn't in this video feel free to ask and I will try to answer the best I can just reminding you that I have my website pretty pretty calm where I have various free and premium courses that you can check out and learn different thing is a more structured way instead of just watching random YouTube videos you can watch structured videos in a course so if you like this video please give me a thumbs up if you haven't subscribed to my channel already please subscribe and I will talk to you next time thanks for watching
Info
Channel: Pretty Printed
Views: 102,806
Rating: undefined out of 5
Keywords: dynamic select, dynamic dropdown, dependent dropdown, flask-wtf dynamic select, javascript dynamic select, javascript fetch, programming, tutorial, python, javascript, flask, flask-wtf
Id: I2dJuNwlIH0
Channel Id: undefined
Length: 19min 34sec (1174 seconds)
Published: Thu May 24 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.