Using jQuery to add form fields - with validation

This post is more than 2 years old.

A few days back I posted a blog entry on using jQuery to dynamically add form fields to a form. The example I gave was a form that asked you to enter information about a person and then had a simple way to add new people to the form. I asked for - and got - a lot of feedback on other (better!) ways to write the code. I've taken one of the suggestions from Brian Swartzfager (see his demo here) and used it for my next task - adding validation to the form, including validation on the new fields. Definitely view source on his demo as I'll be assuming you have read it.

Alright - so the first thing I wanted to do was add validation to the form fields that showed up by default. I am a big believer in 'baby steps' so before I even try to make the validation dynamic, I'll work with the static form fields first. Brian's code already had a (document).ready block, so I simply added the following:

rules: {
	firstname1: {
		required: true,
		minlength: 2
	,lastname1: {
		required: true,
		minlength: 2
	,email1: {
		required: true,
		email: true

If you have read my entries on form validation with jQuery than the above shouldn't be anything new. I verified this worked before going on.

It is a bit off topic for this entry, but notice how my form uses one label for first and last name? Notice how since both are required, if you forget both, the error message displays by each field? It would be nice if there was a way to say "Yes, firstname and lastname are required, but I want to treat them as a group and just one error message." Turns out - the plugin supports this out of the box. You can create a group of form fields using the groups value in the constructor. This will group the fields in terms of messaging. We still need a way to specify where the error should go. This can be done with yet another constructor value - errorPlacement. Consider:

groups: { fullname: "firstname1 lastname1" }, errorPlacement: function(error, element) { if (element.attr("name") == "firstname1" || element.attr("name") == "lastname1" ) error.insertAfter("#lastname1"); else error.insertAfter(element); },

I've created an arbitrary group name called fullname and linked it to my two name fields. The errorPlacement value is a function that can dynamically handle putting the message in the right place for my name 'set'. FYI, I think this is a bit overly complex. I can see needing custom error placement about 100% of the time for groups. I've filed an enhancement request for the plugin to make this a bit easier.

Okay - sorry for the diversion there. So given that we can now validate the form fields built in, and we have an easy way to add more fields, how do we also add validation for the new rules? The Validation plugin makes this simple. For each new field we add, we can do: X.rules("add", rule) where X is our selector the rule is the logic to add. Taking Brian's code he wrote for the addPerson logic, I just added:

//add validation $("#firstname"+current).rules("add", { required:true,minlength:2 }); $("#lastname"+current).rules("add", { required:true,minlength:2 }); $("#email"+current).rules("add", { required:true,email:true });

Remember that current was a number that kept track of how many people we had in the form.

You can see this in action here: View source to see the complete modification to Brian's code.

This leaves us with one small little issue. While grouping nicely handles our default firstname/lastname pair, you can't add new groups after the form has been validated. (You know, I wonder what happens if you just run validate() again?) So the error display isn't terribly nice, but that could probably be worked on a bit more.

Anyway - I hope this is helpful to folks.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA

Archived Comments

Comment 1 by Matt Williams posted on 2/24/2009 at 8:09 PM

In the interest of encapsulation and DRY, I'd consider putting validation into its own function that can be called in the $(document).ready() function and also within the addPerson click function. It may have to be made a bit more dynamic to handle this, but as the form grows, it would be easier to maintain.

Also along the lines of DRY, in the initial html I would suggest not hardcoding the firstname1, etc. block in the html. Take the meat of that $("#addPerson").click function and put it into a separate function. Set var current = 0. Then document.ready could call that function to clone the first set of inputs.

One more note concerning submitting empty hidden fields (the template fields). Josh N commented in the original blog post about putting that userTemplate div outside of the form itself so they don't get submitted. Seems like a good way to go to me.

Comment 2 by Ziglet posted on 9/18/2009 at 6:04 AM

Hey Raymond,

Thanks a lot for this post. Your discussion on groups and errorPlacement helped me A TON!

Comment 3 by Gary Funk posted on 10/19/2009 at 1:00 AM

Ray, this is a great example. Easy to follow and use.

So, one last item. How do you delete the last 'add' in case the user click on 'Add Another Person' one time too many?

Comment 4 by Gary Funk posted on 10/19/2009 at 2:55 AM

Better yet, how would you delete any added set?

Comment 5 by Raymond Camden posted on 10/19/2009 at 7:19 AM

You can, I believe, just use the remove() operator in jQuery.

Comment 6 by Gary Funk posted on 10/20/2009 at 7:58 PM

Thanks Ray,

I have it working. I will make the changes to your code and send it up to you.

Comment 7 by Gary Funk posted on 10/20/2009 at 9:01 PM

I have modified Ray's code to add a 'remove' link for each new added person.

You may find the code at :

Comment 8 by JFJ posted on 3/11/2010 at 11:48 PM

Gary your changes break the validation.

Comment 9 by Chap posted on 10/21/2010 at 12:39 AM

@jfj: what browser did you see the break in? I'm not seeing anything broken.

Comment 10 by Carlos posted on 1/13/2012 at 12:51 AM

Thanks!! I was looking for this and landed right in the good spot! :)