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 • 32 courses • 757,176 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

24:12:33 of on-demand video • Updated April 2021

  • 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] And this one, we are going to be dynamically adding forms to a form set view, that means that we will have a button much like the save in cancel button, but a button that says add new form. And now we'll just add an actual new form for us so we can add new data. So we already start with an empty or one extra 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 January. So we're actually going to skip the Jacquard 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 at a little bit different. I just added some styling, so I added some bootstrap styling as well as this cancel button, which this cancel button really just goes back to the 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 I 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. Querrey block here. And they also added this Shakeri color animation block as well. So all this code will be on GitHub. If you take a look at our GitHub for this particular project, you will actually be able to see all of this code as well, including this starting code. So we'll 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 are going to make some changes here. And 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 form set. We have our div class and we called it form ro and then form ASPE. Now, of course, if you weren't doing form Espie and you wanted to use Django Crispi forms, you can absolutely do that with Crispi here. But we're going to stick with Aspey just to not work with third party libraries just yet. So what we can do is we can actually create a 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 formed Ashboro and then I'll give it an idea of MTD Row as well. And we'll close off the d'Hiv well, actually, before I do 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 and do form set so forms that empty form. And as P so again, you can use Crispi here instead of as P if you want, but we're going to leave it as P so as paragraph's and we'll say this and we're going to render it back into chrome. So going into chrome, if we scroll to the bottom, we see two new forms here or so, two forms in general. And if I get rid of that empty form and save it, refresh in here. We no longer see that form. We still see the row, but we don't see that extra form in there. So let's bring it back in and let's see what happens if I try to input something. So I'll say ABC or whatever on the actual form or I'll put it on both of them and just kind of see which one stays. I hit save scroll down. The validation error happens only on one, 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, our CSF middleware token. So that input is rendered from that template tag that we used. We had the button group a break, and then we also have the management form. So it shows us 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 one. So whatever that value is, that's what we actually want to look for. That's the most important part as far as this form 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 the 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'm going to open up the ones on the other one. What we see here is we have ID form dash three dash user down here. We see in the empty form we see id underscore, form, Desh underscore, underscore, prefect's underscore, underscore user. So it's quite different. Right. So it 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 form dash three, the very first form is going to be zero, it's going to show zero and it does. And that's true for each field too. So what that means is we can use GE query to copy this, change the actual prefix to a number of form or the next number of 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, I'm to close out the inspect just for a second and we're going to come in here and I'm going add the ID of empty form back excuse me, empty row. We save that and we don't have to submit the form. But what 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 I'm going to copy and paste in this GAO 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 HTML and we're going to add a new button in here or a new Şeref. And I'll just put the dollar sign there and I'm going to give this a button class of add new form. So add 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'm going to put this down below as well, and I'm going to call it BTE 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 ad new form button, and now what we can do is use some jorquera to update it. So what we have here is we have this one says ad empty lecture. We're actually going to change that to being something different. We called it a new form, something to use that a 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 I'll do some stuff there and then we'll come through. So the first thing that you'll note is form ID. Who's to question mark. Question mark. So if I actually come back in here and inspect the element. Inside of the console, I get unexpected uncaught syntax error. So this form ID has to do with, well, hopefully you know what I'm talking about, but if you don't, we'll jump into the form again. And it's the management form. So I'd underscore forms, total forms. That is what we want to change it to. Somebody just come in here and change that into ID on score, 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 form ID. This might be different depending on what kind of form of 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 is we want to keep that form in there if we add one hundred 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 two of 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 passing the integer from the total number of forms. So we're getting this value and we're making sure it's an integer so we can use it in Junqueira. 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 that 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 the emails 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 a more practice with Junqueira 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 total on a number of forms and then just adding one to it. And then finally, we're going to animate some stuff for that new formula. OK, so the next thing what 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 form IDs here, it's taking 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 a replacement code to get the total number of forms or whatever numbers in there, and then we can replace current name with that. So we take the original name. We look 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 faurot, so if you think about it, if we copy this, this entire block here, let's say edit as HTML, basically what we're doing is we're copying and pasting a new one and I'm getting rid of this. So I'm just simulating what we're doing in the query 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. That's when we do this right, so we're changing the name and the ID and then we look for the nearest road so we can change the we're going to add the same I.D. or a similar ID onto the road. 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 classroom, 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, is going to change the parent idea 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 or return the newly created role, 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 Jaquie that well, to actually pass and understand all this information. But you might 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 that it's going to validate those forms. So let's actually try it. So I'm, I hit save and I scroll down and all those forms are still there, but there's nothing showing up. Right. So 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 hit save again. And now what we'll see is some validation errors showing up for all of that new stuff. Right. And if we looked at the clean data, it would show that stuff as well. These extra form, I 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 submit it, 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 are all dynamically added. But then we submitted it. So let'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 erase all of them. It's not really a eracism and it's not really cancelling. It's just redirecting to a different page. But if we add a new form and say A.B.C. again or whatever hit, save one more time and then we see that, you know, the slug's required, blah, blah, blah. And we say A.B.C. one, two, three, 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 when we saved it or and that's how it's actually showing up. So that new data is here. And then we have another empty form now at the bottom. And of course, when I click add new form, it's 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 Jaquie. Again, it's a little bit of 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. Jake, query specifically for this form said, OK, thanks for watching and we will see you in the next one.