Home > JQuery, MySQL, PHP > Adding Unlimited Form Fields With JQuery and Saving to a Database

Adding Unlimited Form Fields With JQuery and Saving to a Database

In this article I’ll discuss how to add an unlimited number of additional form elements to a form and then save to a database. The latter part is the key here as a variety of tutorials exist on adding form elements, but I have yet to see anywhere that actually explains how to manipulate these added form fields. For example, how to get values to store them in a MySQL datbase. In the example we’ll have a simple user signup form where the user can add multiple fields to describe their favourite websites.  The basic Form HTML is as follows (nothing amazing, just a simple html form):

<script src="js/jquery.js" type="text/javascript"></script>
<h1>New User Signup</h1>
<form action="index.php" method="post">

  <label for="name">Username:</label>
  <input id="name" name="name" type="text" />
  <label for="name">Password:</label>
  <input id="password" name="password" type="text" />

   <div id="container">
      <a href="#"><span>» Add your favourite links.....</span></a>
   </div>

   <input id="go" class="btn" name="btnSubmit" type="submit" value="Signup" />
</form>

The only part that isn’t standard is highlighted above. This is simply the link users click to add additional form fields on the fly. To make that happen we’ll need some JQuery:

var count = 0;
$(function(){
	$('p#add_field').click(function(){
		count += 1;
		$('#container').append('<strong>Link #' + count + '</strong>'+ '<input id="field_' + count + '" name="fields[]' + '" type="text" />' );
	});
});

Jquery makes it very easy to add for elements using the append method. As we need to assign a unique name to each additional input (as we are allowing the user to add an indefinite amount of inputs) I’ll use a variable to keep track of the number of inputs added. Whenever an input is added, the counter variable increments by one. Another thing to notice is how the fields are named using ‘txt[]‘. This creates an array of field names. So now when we click the ‘add_field’ link, a new input field is appended to the contianer div – view example.

The only other order of business is to save this information to a database. This would be easy if we had static field names for the whole form, but we don’t. We have the following:

<input id="name" name="name" type="text" />
<input id="password" name="password" type="text" />
<input id="field_1" name="fields[]" type="text" />
<input id="field_2" name="fields[]" type="text" />
<input id="field_3" name="fields[]" type="text" />
.
.
.
etc.

To capture this dynamic fields we’ll need to use a bit of PHP to loop through our posted array and saving the data using a many-many relationships using the following database structure – allowing a user to be associated with an unlimited number of websites:

Many-Many Data Structure For Users And Sites

Many-Many Data Structure For Users And Sites

The following PHP code will grab our static and dynamic form values and insert into the above data structure. We’ll be using a class for the database to minimise the amount of code written. Firstly we’ll check if the forma has actually been submitted, grab the static values (username and password) and insert these into our users table:

//If form was submitted
if (isset($_POST['btnSubmit'])) {

	//create instance of database class
	$db = new mysqldb();
	$db-&gt;select_db();

	//Insert static values into users table
	$sql_user = sprintf("INSERT INTO users (Username, Password) VALUES ('%s','%s')",
						mysql_real_escape_string($_POST['name']),
						mysql_real_escape_string($_POST['password']) );
	$result_user = $db-&gt;query($sql_user);

PHP’s sprintf function was used to format the sql query. I also escape input to prevent nasty things from happening. Now we need to check if the user has actually added any favourite websites in order to prevent a php error if we try to find non-existant values, if they have added a field we’ll need the user id number previously inserted into the users table, as we’ll need to insert this elsewhere later on:

//Check if user has actually added additional fields to prevent a php error
	if ($_POST['fields']) {

		//get last inserted userid
		$inserted_user_id = $db-&gt;last_insert_id();

Next we loop through the added form field values. This is where naming the field as in our append function as ‘txt[]‘ comes in, as all fields we added are submiited as an array called txt. Using a for each loop we can assign values to all dynamically added fields and save them to database. The $key is simply the fields name (field_1) and the $key is our actual value entered for that field. Now we know this, we can easily generate the sql statements within the loop. Firstly we add the website into the websites table, get the id of the inserted website and insert this into the the link table, using the userid from before. To finish, we display a confirmation message and disconnect from the database:

//Loop through added fields
		foreach ( $_POST['fields'] as $key=&gt;$value ) {

			//Insert into websites table
			$sql_website = sprintf("INSERT INTO websites (Website_URL) VALUES ('%s')",
						    	   mysql_real_escape_string($value) );
			$result_website = $db-&gt;query($sql_website);
			$inserted_website_id = $db-&gt;last_insert_id();

			//Insert into users_websites_link table
			$sql_users_website = sprintf("INSERT INTO users_websites_link (UserID, WebsiteID) VALUES ('%s','%s')",
						    	   mysql_real_escape_string($inserted_user_id),
								   mysql_real_escape_string($inserted_website_id) );
			$result_users_website = $db-&gt;query($sql_users_website);

		}

	} else {

		//No additional fields added by user

	}
	echo "
<h1>User Added, <strong>" . count($_POST['fields']) . "</strong> website(s) added for this user!</h1>
";

	//disconnect mysql connection
	$db-&gt;kill();

As a result, our database should be populated as follows (these are screenshots from phpmyadmin):

All our data tables are populated and the correct website and user id are inserted into the link table

All our data tables are populated and the correct website and user id are inserted into the link table

You can view the source of php file here or download the original source files (you’ll need to open classes/db.class.php and populate the sql variables with your own database details). The MySQL source to create the tables is also included in the source files.

  1. Drakar
    July 28th, 2009 at 10:44 | #1

    Nice idea, but you should be really using isset when checking if the more fields have been added. For example isset($_POST['fields']).

  2. Joseph
    July 30th, 2009 at 19:43 | #2

    How would i add multiple areas each time you add am input?

  3. July 30th, 2009 at 22:17 | #3

    Thanks for your comment.

    I recently discovered how to do that. It’s not actually that much extra work to say add (in relation to the examples used in this article) more fields each time the a’dd an input link’ is clicked E.g. a website name, a website url and website comment would be added, instead of just a single website field. I’ve found this is very useful for a lot of projects.

    I’ll post an article explaining how to do this shortly.

  4. July 30th, 2009 at 22:19 | #4

    @Drakar
    Yes I agree as it’s good practice and not using it causes warning to occur on some server setups. However, for simplicity I left it out (read: forgot :) ) to include it here – not that it would change whow the example works in any way.

  5. August 6th, 2009 at 06:49 | #5

    Rob – Thanks! Excellent example and very clearly and concisely written.

  6. August 18th, 2009 at 23:19 | #6
  7. October 8th, 2009 at 19:07 | #7

    Great work!
    How would you add the remove fields function to this example?

  8. October 8th, 2009 at 20:26 | #8

    @Lollodev

    All you’d need to do is add a delete icon/link next to each field – for this you’d simply append a little bit of extra html to what we have already, adding the ‘count’ variable to the field id. E.g id=”deletelink_’ + count”.

    You’d then need a function to capture the click event – again quite self explanatory. In this function you’d simply pass it the element name and use JQuery’s remove method – see http://docs.jquery.com/Manipulation/remove

    I’ll try to add a new post about this soon, as it’s quite useful to delete added items.

  9. gtenor
    January 11th, 2010 at 07:47 | #9

    Is there a way to remove the fields after adding it? Have you posted an example for that on your website?

  10. January 11th, 2010 at 20:24 | #10

    @gtenor

    If you look here I briefly explained it: http://www.web-design-talk.co.uk/58/adding-unlimited-form-fields-with-jquery-mysql/#comment-143 – should explain it if you know your way around JQuery.

    However, I’ll be explaining that feature in a new article as a lot of people (including yourself) have requested this and there are a few cross browser issues (mainly IE, who would have guessed? :) ).

  11. am17
    January 16th, 2010 at 23:35 | #11

    Hi Rob,

    I am also interested to see a clean way of removing fields..Thanks :) ..

  12. January 16th, 2010 at 23:47 | #12

    Have been meaning to add this feature to my example – loads of people have requested this by email too. Am just having trouble getting around to it as I’m so busy at the min :)

  13. gtenor
    January 17th, 2010 at 08:28 | #13

    I’ve finally implemented the add and remove form elements :) . They’re working superbly; yet I’ve done it in another way, not by the way you suggested in your comment :) .

  14. January 17th, 2010 at 10:46 | #14

    @gtenor

    Hi,

    Would be interested to see how you did that? The main culprit is IE6, does it work in that browser?

  15. am17
    January 18th, 2010 at 04:27 | #15

    @gtenor

    Could you please share your solution to remove form fields

  16. gtenor
    January 19th, 2010 at 01:41 | #16

    Certainly!!

    Altough I cannot give you my code because I’m using for commercial site that I’m building, I’ll give you a lead.

    I’ve got this useful piece of information from a forum:

    “For dynamic addition/removal, it’s easy enough to use the native DOM traversal keywords, rather than jQueries “$(this).parent().get(0)”

    Ex,:

    Hope that helps!! :)

  17. gtenor
    January 19th, 2010 at 01:42 | #17

    @gtenor
    Ex.:”"

  18. gtenor
    January 19th, 2010 at 01:43 | #18

    ugh, didn’t know you can’t stick a piece of html code on here. Here’s the link: http://www.ozzu.com/programming-forum/using-jquery-dynamically-add-remove-form-elements-t93694.html.

  19. am17
    January 19th, 2010 at 08:58 | #19

    Thanks guys.. I found this very interesting jQuery plugin to add/remove fields http://vipullimbachiya.com/

  20. January 19th, 2010 at 11:53 | #20

    @gtenor

    Yer that’s kind of the way I was thinking, as JQuery’s .remove() method doesn’t seem to work on all browsers for removing inputs. Nice find

  21. Cheebu
    January 19th, 2010 at 12:35 | #21
  22. billmce
    March 17th, 2010 at 18:22 | #22

    One big problem … you lose position on your form.
    To retain position add this line at the bottom.

    return false;

  23. March 17th, 2010 at 19:07 | #23

    @billmce

    I’ve not noticed this personally. What browser are you using?

  24. April 19th, 2010 at 12:15 | #24

    Hi. Have tried to implement the remove fields but can’t get it right. Could you explain how to do this?

  25. andrew
    April 19th, 2010 at 20:55 | #25

    Hello, do you have any idea how to make it run in WordPress?

  26. April 19th, 2010 at 21:18 | #26

    @Thomas

    This is on my list of things to do. I’ll a reply soon.

  27. April 19th, 2010 at 21:19 | #27

    @andrew

    Depends on what you mean really? Do you mean getting the JS or database stuff to work in WordPress?

    Saying that, my example doesn’t use anything amazingly complex so you should just be able to add the code to any wordpress site as it’s just simple JS and PHP.

  28. May 10th, 2010 at 11:33 | #28

    Excellent tutorial thanks for sharing

  29. August 1st, 2010 at 18:37 | #29

    People have asked for the code to remove an added input. I’d actually recommend putting your input and remove link in a paragraph tag. For the remove/link simply added the following attribute to your link – works in all the major browsers too:

    onClick=”$(this).parent().remove(); return false;”

  30. August 29th, 2010 at 07:42 | #30

    What is the advantage of creating a link table when you don’t know ahead of time the range of entries to the Website_URL field?

  31. August 30th, 2010 at 08:50 | #31

    @Kris

    As users can add many websites. E.g. in the example, the user has added 6 websites, all of which are referenced in the link table. The link table is needed because the amount of sites a user can add is unlimited (one of the reasons the field name are as an array E.g. field[]). The example wouldn’t work without the link table.

  32. August 30th, 2010 at 21:18 | #32

    @Rob
    If we knew ahead of time what the range of possible url’s were and we had our users select from them, then we could re-use our website fields and then we would have a true many to many relationship. Each website could be linked to multiple users and each user could be linked to multiple websites. That would be a many to many relationship.

    In this case, though we have a known user (singular) adding an unknown number of websites (probably plural), so we have a one to many relationship.

    Couldn’t we simply skip the link table and add a user_id as a foreign key to the websites table? The insert foreach loop would still work and we could simplify our sql to something like this:

    $sql_website = sprintf(“INSERT INTO websites (UserID, Website_URL) VALUES (‘%d’, ‘%s’)”,
    $inserted_user_id, mysql_real_escape_string($value) );

  33. September 2nd, 2010 at 19:16 | #33

    Ah, see what you mean now, misunderstood you beforehand :)

    Yes that’s definately another (abliet probably better) way of doing things as you loose a join in your SQL query, which is always good. The reason it ended up as it did is because I was working on a project at work that required that table structure.

  1. August 18th, 2009 at 22:38 | #1