Removing dynamically added form fields
Jan 19 2010
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.
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>
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>









