About a year ago, Ray Camden posted an article on Using jQuery to add form fields - with validation, which he showed how to dynamically add form fields to a form. This proved to be very useful code.

One thing I found was that those darn users love to push buttons and many would add more form fields than needed. A way to remove the unwanted form fields would be necessary in some cases. Using Ray's code as a base to work from, with just a few modifications this is possible. The entire code page is listed below.

view plain print about
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2"http://www.w3.org/TR/html4/loose.dtd">

3<html>
4<head>
5<title>Simple cloning demo</title>
6<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
7<script type="text/javascript" src="/jquery/jquery.js"></script>
8<script type="text/javascript" src="/jquery/jquery.validate.js"></script>
9<script type="text/javascript">
10var current= 1;
11$(document).ready(function() {
12    $("#addPerson").click(function() {
13        current++;
14        /* GWF - Modified the line below */
15        $newPerson= $("#userTemplate").clone(true).removeAttr("id").attr("id", "fieldSet" + current).insertBefore("#userTemplate");
16        $newPerson.children("p").children("label").each(function(i) {
17            var $currentElem= $(this);
18            $currentElem.attr("for",$currentElem.attr("for")+current);
19        });
20        $newPerson.children("p").children("input").each(function(i) {
21            var $currentElem= $(this);
22            $currentElem.attr("name",$currentElem.attr("name")+current);
23            $currentElem.attr("id",$currentElem.attr("id")+current);
24        });
25        //Technically, you could update the attributes with one loop...
26        //
27        //        $newPerson.children("p").children("label,input").each...
28        //
29        // ...but you end up assigning "NaN" names and ids to the labels and other such wackiness.
30        /* GWF - Added the following two lines */
31        var f = $("#fieldSet"+current);
32        f.html(f.html().replace("fieldSetID", "fieldSet"+current));
33
34        $newPerson.appendTo("#mainField");
35        $newPerson.removeClass("hideElement");
36        //add validation
37        $("#firstname"+current).rules("add", { required:true,minlength:2 });
38        $("#lastname"+current).rules("add", { required:true,minlength:2 });
39        $("#email"+current).rules("add", { required:true,email:true });
40
41    });
42    /*
43    $("#demoForm").submit(function() {
44        alert("Yeah...this doesn't really submit any data anywhere...");
45        return false;
46    });
47    */

48    $("#demoForm").validate({
49        groups: {
50            fullname: "firstname1 lastname1"
51        },
52        errorPlacement: function(error, element) {
53             if (element.attr("name") == "firstname1"
54                         || element.attr("name") == "lastname1" )
55             error.insertAfter("#lastname1");
56             else
57             error.insertAfter(element);
58         },
59        rules: {
60            firstname1: {
61                required: true,
62                minlength: 2
63            }
64            ,lastname1: {
65                required: true,
66                minlength: 2
67            }
68            ,email1: {
69                required: true,
70                email: true
71            }
72        }
73 });
74});
75
76/* GWF - Add function to remove Person */
77function removePerson(id) {
78    $(id).remove();
79};
80</script>
81<style>
82.hideElement {display:none;}
83</style>
84</head>
85
86<body>
87<h2>jQuery Cloning Demo</h2>
88<!-- GWF - Moved the following div out of the form so it does not get sent on a post. Also add the link to remove the fieldset --->
89<div id="userTemplate" class="hideElement">
90<p>
91    <label for="firstname">Name</label> <em>*</em>
92    <input id="firstname" name="firstname" size="25" /> <input id="lastname" name="lastname" size="25" />
93</p>
94<p>
95    <label for="email">Email</label> <em>*</em><input id="email" name="email" size="25" />
96</p>
97<p>
98    <a href='#' onClick='removePerson("#fieldSetID"); return false;'>Remove</a>
99</p>
100</div>
101<form name="demoForm" id="demoForm" method="post" action="none.cfm">
102    <fieldset id="mainField">
103    <div>
104        <p>
105            <label for="firstname1">Name</label>
106            <em>*</em> <input id="firstname1" name="firstname1" size="25" /> <input id="lastname1" name="lastname1" size="25" />
107        </p>
108
109        <p>
110            <label for="email1">Email</label>
111            <em>*</em><input id="email1" name="email1" size="25" />
112        </p>
113    </div>
114    </fieldset>
115    <p>
116    <input type="button" id="addPerson" value="Add Another Person">
117    </p>
118    <input type="submit" value="Save">
119</form>
120</body>
121</html>