PHP & MySQL, Demos, Tutorials

When creating a form you don't always know how many form elements to give to the user, it depends on the purpose of the form, In these cases its better to let the user decide by letting them add new form elements with a click of a mouse. This tutorial will show you how to dynamically add form elements to a form using jQuery.

I'm going over input elements and select menu's to keep things simple but you could easily add checkboxes, radios, textareas etc.

First I'll go over the markup then the jQuery which will be placed at the bottom of the file as that's a best practice for working with javascript.

For input I have a div with an id of extender this div is a placeholder for jQuery to grab and place the input elements into. I also have a text link with an id of add, this id will be used by jQuery.

<div id="extender"></div>
<a id="add" href="#">Add</a>

I have almost the same setup for my select menu's only I have provided the div with an id of selextender. For the link I have given it an id of seladd its important to have a unique id for these as they will be calling a different handler in jQuery.

<div id="selextender"></div>
<a id="seladd" href="#">Add</a>

Inside javascript create a counter variable which will increment for each input that's created.

//set a counter
    var i = $('input').size() + 1;

Next a click handler listens for a click even from a text link with an id of add will append an input element to the div of extended adding fadeIn to fade the input in. Adding a class of remove to a link will allow any input to be removed.

 $('a#add').click(function() {
        $('
<input id="' + i + '" type="text" name="items[]" value="' + i + '" /><a class="remove" href="#">Remove</a>

').fadeIn("slow").appendTo('#extender');
        i++;
        return false;
    });

Another example for a select menu, in both examples the elements have a name with [] on the end this enables you to grab the array of items when the form is submitted. Also there can be no line breaks or the element won't be added to the form.

$('a#seladd').click(function() {
        $('
<select name="items[]"> <option value="1">One</option> <option value="2">Two</option> <option value="3">Three</option> </select>

<a class="remove" href="#">Remove</a>

').fadeIn("slow").appendTo('#selextender');
        return false;
    });

 To remove an item create a click function for the class remove when detected will run a fadeout function, making use of $(this) to captchure the current item and parent() no get not only the link put its parent in this case the input, before removing the item.

 $('.remove').live('click', function() {
        $(this).parent().fadeOut(300, function(){
            $(this).empty();
            return false;
        });
    });

Putting it all together:

<form action="" method="post">
<fieldset><legend>Inputs</legend>
<div id="extender"></div>
<a id="add" href="#">Add</a></fieldset>
<fieldset><legend>Select</legend>
<div id="selextender"></div>
<a id="seladd" href="#">Add</a></fieldset>
</form>
<pre lang="javascript"><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script><script type="text/javascript">// <![CDATA[
$(function() {

    //set a counter
    var i = $('input').size() + 1;

    //add input
    $('a#add').click(function() {
        $('<input type="text" name="items[]" id="' + i + '" value="' + i + '" /><a href="#" class="remove">Remove</a>').fadeIn("slow").appendTo('#extender');
        i++;
        return false;
    });

    //add select
    $('a#seladd').click(function() {
        $('
<select name="items[]">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>

<a href="#" class="remove">Remove</a>

').fadeIn("slow").appendTo('#selextender');
        return false;
    });

    //fadeout selected item and remove
    $('.remove').live('click', function() {
        $(this).parent().fadeOut(300, function(){
            $(this).empty();
            return false;
        });
    });

});
// ]]></script>