Dynamic New Form in Formsets with jQuery

Justin Mitchel
A free video tutorial from Justin Mitchel
Coding Entrepreneur & Teacher - 568,000+ Students
4.3 instructor rating • 30 courses • 678,663 students

Lecture description

Create new Forms in a Django formset by using jQuery

Learn more from the full course

Django Core | A Reference Guide to Core Django Concepts

Dive in deep to the core concepts behind the power Django framework written in Python. Using Django 1.10 with Python 3

18:44:20 of on-demand video • Updated January 2017

  • Django Models
  • Model Instance Methods & Properties
  • Model-level field validation
  • Django Forms and Formsets
  • Form validation
  • Model Form
  • Function Based Views (FBVs)
  • Class Based Views (CBVs)
  • CRUD in Django Views (Create Retrieve Update Delete List)
  • Django Templates
  • Django translation
  • Deploying Django on a Live Server| Heroku, Webfaction, Linode, Digital Ocean
  • Celery + Redis for asynchronous tasks and scheduled tasks
  • and much more!
  • Requirements are Python 2.7 or 3.3 and Django 1.8 & up
  • We use Python 3 and Django 1.10 in this one
English [Auto] This one we're going to be dynamically adding forms to a form said view. That means that we will have a button much like the save and cancel button but a button that says add new form and that will just add an actual new form for us so we can add new data. So we already start with an empty or one actua empty form. But what if we wanted to add like 10 things before we actually save it. That's what we're going to be doing and it's going to be using a lot of Jey query. So we're actually going to skip the J query code. We will talk about it but we're not going to go step by step with it. We will talk about each individual function itself but the main thing here is to actually look at the code as it is. Now you might be wondering why things look a little bit different. I just added some styling so I added a bootstraps sailing as well as this cancel button which this cancel button really just goes back to the home page. It doesn't really cancel anything you just you know changes the page. You could use it as a refresh button as well. That's essentially what it's doing without actually saving anything is just going to a new page. So that little bit of styling and then also added some new styles as well using the template inheritance of course. So block styles here and then another thing that we added was the J query block here and they were also added this query color animation block as well. So all this code will be an get hub if you take a look at our get help for this particular project you will actually be able to see all of this code as well including this starting code so we will have something for this lecture to be the start code. So now we're going to jump back into our form set view and we're going to make some changes here we're going to introduce this concept of an empty form inside of our form set. Now of course this is how your form is going to want to look right so we have our actual forms that management form we have form in forms that we have our div class and we called it form row and then form as P.. Now of course if you weren't doing formas and you wanted to use Gengel crispy forms you can absolutely do that with Chris be here. But we're going to stick with as P.. Just to not work with third party libraries just yet. So what we can do is we can actually create a empty form or render an empty form that has really no bearing on the actual form set. So let's actually take a look at that I'm going to put it into a new div class and I'm also going to give it as form dash row and then I'll give it an idea of empty dash row as well. And close off the div Well actually before you empty row I'm going to leave that out and I'll explain why in just a moment. But we're going to come in here into form set. So form set empty form. And as P.. So again you can use crispy here instead of as P. If you want but we're going to leave it as P. So as paragraphed and we'll say this and we're going to render it back into crome. So go to any Crome if we scroll to the bottom we see two new forms here are sort of two forms in general. And if I get rid of that empty form and save it refresh and here we no longer see that form we still see the robot we don't see that essure form in there. So let's bring it back in and see what happens if I try to input something. So I'll say ABC or whatever on the actual form or I'll put on both of them and just kind of see which one stays I hit save. Scroll down the validation error happens only on one and not the other. And that's what empty forms do is they actually don't have validation because it's really just an empty raw form. So we can do what we're about to do and that is if we look into the inspect element we can see this even further. Now first of all inside of the form we all look at the code here a little bit is we have our form. SRF middleware tokin so that input is rendered from that template tag that we used with the button group a break and then we also have the management form. So it shows that total forms initial forms minimum number of forms maximum number of forms and it has several different values here. Now the main value for us is of concern is the total forms 1 so whatever that value is that's what we actually want to look for. That's the most important part as far as this forum is concerned. And right now it says four if we count the forms we got one two three four five there's actually five forms but that very last form the empty form is ignored. Right. So if we look at the empty form like any of the inputs in there by opening up all the little tags I to open up the ones on the other one. What we see here is we have I.D. form dasht three dash user down here we see the empty form we see ID underscore form Desch underscore underscore Prefect's underscore underscore Desch user. So it's quite different. Right. So that actually is not giving us a number there and these numbers correlate the position that that form actually exists so the Fourth Form is actually Id underscore forment dash 3. The very first form is going to be 0 0 0 and it does. And that's true for each field too. So what that means is we can use J query to copy this change the actual prefix to a number of form or the next number or form and then we can also change the total number of forms as well. So that's what we have to do and we're going to do this in a few ways so the close up the inspect. Just for a second and we're going to come in here and add the ID of empty form back excuse me empty row. We save that and we don't have to submit the form but we see now is just that one extra form in there and then all the other ones. All right cool. So now what I want to do is get a copy and paste in this Jay query that we've already kind of created for you guys. So we're going to cut it out of our notes and paste it in here. OK. So we're going to go line by line with this in just a second but we want to add a few more things to our aged hymnal and we're going to add a new button in here or a new breath and I'll just put the dollar sign there and I'm to give this a button class add new form. So a new form is really going to be handling it for us and we'll say add new form and I'll put a plus sign in front of it and I want to put this down below as well and I'm going to call it bt and link. So this is bootstrap stuff. You don't actually have to style it necessarily but we're going to leave it like that. All right so now we have this added new form button. And now what we can do is use some Jey query to update it. So what we have here is we have this one says add empty lecture row we're actually going to change that to mean something different. We called it add new form. Somebody use that new form class. The reason I'm showing you to do this is just so you check these things. If you ever copy and paste and use this code elsewhere. All right. So now we've got this new form so if I click on it it will look for this empty row and then do some stuff there and then will come through. So the first thing you note is form id has to question mark question mark so if I actually come back in here and inspect the element inside of the con. I get an expat or uncut syntax error. So this form id has to do with. Well hopefully you know what I'm talking about but if you don't will jump into the form again and it's the management form. So Id underscore forms total forms. That is what we want to change it to suddenly just come in here and change that into ID underscore form total forms. And now everything else will actually update accordingly. Inside of this code. So what's happening here is when we click on this new form it's going to look for that for ID. This might be different depending on what kind of form you're using or all types of things that might actually change. Even more reason to make note of it then we're going to copy the existing empty form. There's a reason we're copying it instead of just replacing it or changing it as we want to keep that empty form in there if we add 100 new forms. So then we're going to remove with our new empty row we're going to remove the ID so we're going to remove that original empty row because we made a copy and we don't want to have the same ID especially not empty row because we have display on none there. And then we also want to get the total number of forms here. So we're parsing the integer from the total number of form so we're getting this value and we're making sure it's an integer so we can use it. And Jay Querrey then we have this new form variable we're just declaring that and then we're doing some stuff to the actual form itself which we'll talk about in a second. But this actual form has to do with an empty row. And then after we do all that stuff we append this to the very end. So the last row form which if we scroll down a little bit it's going to be after this empty form set. Right. So it's going to be after the empty row itself as far as I'm concerned. But realistically if you didn't have that class on there and you added it later you would be able to just have it after that. Hopefully that's not too confusing. It might be. But that's something that you might need more practice with. Jay query if it is finally what we want to do is update the form count to include the new row so we're going to grab that original form ID. So what we did up here and then we're going to update that new value to including the original totals on a number of forms and then just adding 1 to it. And then finally we're going to animate some stuff for that new form roll. OK. So the the next thing we want to talk about is what's happening inside of the form so we're updating the empty form IDs. So if I scroll up a little bit and I see this up this function for updating for IDS here it's taken in an element and then it's looking for name of that element so that current element name. So if we look at the rendered code inside of any given form we're going to come in here and it's looking for a specific element for the name here. And as far as the name is concerned we are going to want to replace that name and then we're also going to eventually want to replace the ID. But notice the name itself and ID are not necessarily the same and the name is really the important one not the other part. So with the empty form if we look at that the name again is has that prefix in there so we want to change that prefix to follow the form numbers. So what we do here is we use some replacement code to get the total number of forms or whatever number is in there. And then we can replace the current name with that. So we take the original name we looked for this string of prefix right here and then we do some substitution change the the total number into that prefix and then we update the input accordingly. Now you see element it is coming off of any of these inputs so input select or text area. So those are the ones that are are actually being able to be changed. And then we set that input to those new names. So we remove the old names basically and put the new ones in there and then we create a new form. So we're looking for the closest form row and that has to do with the empty form. So it's going to jump up and look for it. So in the rendered code let's take a look here. We see that it's looking for this form row. So if you think about it if we copy this this entire block here let's say it as Tim L.. Basically what we're doing is we're copying this and we're paste in a new one and I'm getting rid of this. So I'm just simulating what we're doing in the J queery itself. We're looking inside of each not label yet but each name. And we're changing it to being like five. So for each one that's what we're doing and what we do here is that's when we do this right. So we're changing the name and the ID. And then we look for the nearest row so we can change the we are going to add the same ID or a similar ID onto the row. We don't necessarily need to do those two things but it is something that's nice to have and then we're going to add this new class to that rose a new parent class row which we'll see once we do it. And then what we're going to do is grab the elements parent which is going to be whatever element it is. So in this case the select element would grab the parent which is P and then it's going to change the label. So then we would want to change. Or excuse me can change the parent Id first and then it's going to change the label ID. And again we'll see this stuff in just a second. And then finally all return the newly created Roe which is what we append to the very end. OK. So that's a lot of stuff going on and it's going to take some time if you don't know Jay query that well to actually parse and understand all this information. But you also have to watch what I just said. But again playing around with this is something that you also might want to do. OK so now if we click add new form. Notice what happens is it actually adds it. So if I click on Add new form a lot of times it's going to add it through here. So it's adding another form but it doesn't necessarily mean it's going to validate those forms so let's actually try it. So I can save and I scroll down and all those forms are still there. But there's nothing showing up right so I didn't actually try to save any sort of data. So there's no validation. So I do let's just add some more stuff in here and I'll just say those and that and then I'll say it again. And now what we'll see is some validation errors showing up for all of that new stuff. And if we looked at the clean data it would show that stuff as well. These extra form are still coming through and they're still there because when we go to air inspect element our form now has a new value for total forms. Right so it's not it didn't change the value of total form so when we submitted it's still going to stick with that same value. And then as far as actually looking at the new forms as we see here all of these forms are coming through. So these are all these We're all dynamically added but then we submitted it. So it's actually add a few more dynamically added ones. And what we'll see is some changes as we now have these are all the dynamically added ones and it's giving us a form idea of 11 12 and 13 and so on. So this is actually working it's showing us exactly how we want it to be. The only challenge here is actually having too many extra forms but that's where you could hit cancel and it would replace all of them. It's not really a race you know and it's not really canceling it it's just redirecting to a different page. But if we add a new form and say ABC again or whatever hit save one more time and then we see that you know the slug's required blah blah and we say ABC 1 2 3 and then some other slug and we hit save. Now that data is in there or at least it should be. So let's go ahead and refresh. And the data is brought to the top because. Because that's where we saved it or and that's how it's actually showing up. So the new data is here and then we have another empty form now at the bottom. And of course my click and new form it's doing a little animation. So that's what that animation is. It's scrolling to the top of that form element. So the actual row itself and then it is. So that's the animation scroll and then it's animating a new background color because by default the background color is right here in the style and then. So that's it that's dynamically adding new forms with Jay Querrey. Again it's a little bit of a complicated topic. That's why it's so long if you have a lot of comments or questions about this let us know because it might be worth actually doing more step by step. Jay query specifically for this form set. OK. Thanks for watching. And we will see you in the next one.