How do you use Javascript to duplicate form fields?
Solution 1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript">
(function($){
$countForms = 1;
$.fn.addForms = function(){
var myform = "<table>"+
" <tr>"+
" <td>Field A ("+$countForms+"):</td>"+
" <td><input type='text' name='fielda["+$countForms+"]'></td>"+
" <td>Field B ("+$countForms+"):</td>"+
" <td><textarea name='fieldb["+$countForms+"]'></textarea></td>"+
" <td><button>remove</button></td>"+
" </tr>"+
"</table>";
myform = $("<div>"+myform+"</div>");
$("button", $(myform)).click(function(){ $(this).parent().parent().remove(); });
$(this).append(myform);
$countForms++;
};
})(jQuery);
$(function(){
$("#mybutton").bind("click", function(){
$("#container").addForms();
});
});
</script>
</head>
<body>
<button id="mybutton">add form</button>
<div id="container"></div>
</body>
</html>
Solution 2
There's a technique called supplant that does this. I didn't write it, I think Douglas Crockford did. But I'll quote it:
Now that your JavaScript program has received the data, what can it do with it? One of the simplest things is client-side HTML generation.
var template = '<table border="{border}"><tr><th>Last</th><td>{last}</td></tr>' +
'<tr><th>First</th><td>{first}</td></tr></table>';
Notice that we have an HTML template with three variables in it. Then we'll obtain a JSON object containing members that match the variables.
var data = {
"first": "Carl",
"last": "Hollywood",
"border": 2
};
We can then use a supplant method to fill in the template with the data.
mydiv.innerHTML = template.supplant(data);
JavaScript strings do not come with a supplant method, but that is ok because JavaScript allows us to augment the built-in types, giving them the features we need.
String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g,
function (a, b) {
var r = o[b];
return typeof r === 'string' ?
r : a;
}
);
};
From http://www.json.org/fatfree.html
One technique I've seen to avoid that messy variable assignment of a template is to do:
<script id="rowTemplate" type="text/html">
<tr>
<td>Field A:</td>
<td><input type='text' name='fielda[{id}]'></td>
<td>Field B:</td>
<td><textarea name='fieldb[{id}]'></textarea></td>
</tr>
</script>
This will let your write much prettier code as you can reference it with getElementById.
So in your case, rather than populating it with a JSON object, you would just look over however many rows you need to add and replace the id's.
Solution 3
The example you are linking to, has a hidden version of the form that is used as a template. This template has an ID (readroot
), that allows it to be easily selected (getElementById
), then cloned (node.cloneNode()
) and injected into the DOM above (node.insertBefore()
) a second marker in the source (writeroot
).
The number of duplications is kept accounted for in the variable counter
. Its' contents are updated (incremented) on every cloning, and its' value is then appended to all the field names in the cloned node. (The original template-nodes' fields have no numeric suffix.)
It's all really very simple, just study the javascript in the head-portion of the webpage. Google the parts you can't understand, and you will achieve what you're looking for, and will learn some in the process. Profit!
Comments
-
Citizen almost 2 years
For instance, I want to have a html form that looks like this:
<table> <tr> <td>Field A:</td> <td><input type='text' name='fielda[1]'></td> <td>Field B:</td> <td><textarea name='fieldb[1]'></textarea></td> </tr> </table>
What I want is to add a button that duplicates my entire above form, but changes the 1 to a 2 for all of the fields. Not just one field, but the entire section of code, including the table.There will be more/different fields than the ones I posted as well.
I've already tried this solution, which does exactly what I need:
http://www.quirksmode.org/dom/domform.html
But for some reason, could not duplicate the functionality when copying the code examples to test. I even tried literally copying the entire page source to get it to work, with no avail.
-
Citizen over 14 yearsWow! Very simple. But wouldn't this require some includes for jquery? (i'm sorry, I really don't know much about jquery) What else is needed to complete the code?
-
Citizen over 14 yearsI totally understand what the code is trying to do, but I can't isolate where the bug is when I literally copypasta the code.
-
Amit Patil over 14 yearsYes, but you could do it pretty much as easily using innerHTML from plain JavaScript if you wanted to.
-
andres descalzo over 14 yearsinclude jquery on the page, you can put this code in a separate file as a list of plugins. wait a minute, and I complete with an example
-
nikc.org over 14 years@Ryan: can you paste your complete source into a pastebin somewhere? Psychic debugging is too hard this time of day. (CET+1)
-
Citizen over 14 yearsI tried first copying the code and editing it to do what I needed. When that didn't work (clicking the button did nothing), I tried copying the exact source for the entire page, and that did not work either.
-
Citizen over 14 yearsDo I just put this on a <input onclick button? What about removing the added form section?
-
Citizen over 14 yearsHow do you remove one of these created areas?
-
user919860 almost 12 yearsAndres, if you don't mind my asking, why do you have your initial function as "function(jQuery)" or "function($)"? I'm really new to jQuery, so I don't understand why you would pass jQuery as an argument. What does that even mean? Is that how you manage to get access to its library?
-
andres descalzo almost 12 years@user919860 all right, first looking to have a reference to the object for faster access, second if you use other libraries we have in our context, the variable "$" without replacing them in other like Mootools. Normally all plugins are made with a structure "closure" to maintain the privacy of the variables.