Form Cloning jQuery Plugin

Building dynamic forms is a task that a lot of web developers will have to do at some point. By dynamic I mean forms that change based on what the user inputs.

A basic example of dynamic forms, are those that allow the user to add the same group of information several times. For example, an attendance form, where you can add several persons, a booking form where you can add several tickets, a membership with several users, a media page with several pictures or videos and so on, the possibilities are countless.

In order to facilitate the development of such forms, I created a little plugin, that allows you to dynamically clone a specific set of information that will be repeated. So if you ever searched a way of cloning forms, fieldsets or groups of input, this could really be helpful.

Thank You for Downloading

I'm glad that you found my work useful. If you did, it might help some other people too. So why not helping me spread the word with a tweet? You could also buy me a coffee to thank me for my code and explanations if you prefer ;).
I hope you'll enjoy your download. Regards. Jeremy.

How to setup

Plugin Inclusion

In order to use the plugin, you'll need to include the jQuery library, and the plugin file. This plugin being very small, you might prefer to copy its code inside one of your existing js file (it will save you the need to load an external file). Otherwise, just include the files as shown:
  1. /** jQuery Inclusion **/
  2. <script type="text/javascript" src="Path_to/jQuery.js"></script>
  3. /** Plugin Inclusion **/
  4. <script type="text/javascript" src="Path_to/jquery.formclone.js"></script>

The Form Markup

Then you can prepare your form markup. There are only two simple thing to check in order to make the plugin work. First, you need to make sure that the elements you want to clone are inside a container (a div, a span, a fieldset or whatever you want), and add to this container a specific class, for example clonable. This class will later on be used to setup the plugin with your form. The second thing to do is to add a starting number to the name of every element that is going to be cloned, for example, name='firstname_1', name='lastname_1' and so on. By doing so, the plugin will automatically increment every name counter as you add more elements. After you have done those two things, the form markup is ready to be connected to the plugin. The only thing you are missing by then is a 'clone me' button, that will generate a new clone when clicked. It has been added on line 16 of the following code:
  1. <form id="cloningdemo" action="/resources/formclone" method="post">
  2.  
  3. <fieldset class="clonable"> //Add the class clonable to the element to be cloned
  4. <legend>User Details</legend> //Then add your elements
  5. <div class="regrow">
  6. <label>First Name:</label>
  7. <input type="text" name="fname_1" />//Each input must have a starting number
  8. </div>
  9. <div>
  10. <label>Last Name:</label>
  11. <input type="text" name="lname_1" />//Each input must have a starting number
  12. </div>
  13.  
  14. <div id="formbuttons" class="regrow">
  15. <input type="button" class="button" id="clonetrigger" value="Clone" />
  16. <input type="submit" class="button" id="clonesubmit" value="Submit" />
  17. </div>
  18.  
  19. </form>

The jQuery Setup

As we have just said, we want to clone our form when the user hits a specific button or link, which in our case, is the button #clonetrigger. We therefore bind the cloning to the click event of this button, as you can see line 5 of the following code. On line 6, just write the name of the class you have used in your form (here .clonable). Line 7 and 8, the plugin works out what the number of the next clone is going to be, you can specify your own if you want. On line 10, we specify that the first element which has your class, is the element to be cloned. Lines 12 and 13, you can specify two options in order to customize where you want to insert the newly generated clone in your DOM. The first option allows you to target a specific element on the page, it could be the id of a specific div for example. The second element allows to specify where you would like to insert your new clone compared to this element, (before it, after it, within it...) It could therefore be any jQuery manipulation method you want (after, before, append, prepend, replaceWith and so on). And finally, line 14, you can pass a limit. If this limit is set, the plugin will not generate more clones than this number. If it's set to 0, it is ignored.
  1. <script type="text/javascript">
  2. //The jQuery Setup
  3. $(document).ready(function(){
  4.  
  5. $("#clonetrigger").click(function(){
  6. var yourclass=".clonable"; //The class you have used in your form
  7. var clonecount = $(yourclass).length; //how many clones do we already have?
  8. var newid = Number(clonecount) + 1; //Id of the new clone
  9.  
  10. $(yourclass+":first").fieldclone({//Clone the original elelement
  11. newid_: newid, //Id of the new clone, (you can pass your own if you want)
  12. target_: $("#formbuttons"), //where do we insert the clone? (target element)
  13. insert_: "before", //where do we insert the clone? (after/before/append/prepend...)
  14. limit_: 4 //Maximum Number of Clones
  15. });
  16. return false;
  17. });
  18.  
  19. });
  20. </script>

Extra: Generated Code

If you are wondering what the code the plugin generates looks like then you should know that it is really simple. Based on your form markup composed of the elements you want clone and each of them having a number, the plugin will generate exactly the same markup for each clone, the only difference being the number, which is incremented with every clone. For example, after one clone, the generated clone for the demonstration looks like this:
  1. //Original Fieldset
  2. <fieldset class="clonable">
  3. <legend>User Details</legend>
  4. <div class="regrow">
  5. <div class="regrow">
  6. <label class="inside">First Name:</label>
  7. <input class="text" name="fname_1" type="text">
  8. </div>
  9. <div class="regrow">
  10. <label class="inside">Last Name:</label>
  11. <input class="text" name="lname_1" type="text">
  12. </div>
  13. <div class="regrow">
  14. <label class="inside">Email:</label>
  15. <input class="text" name="email_1" type="text">
  16. </div>
  17. </div>
  18.  
  19. //Cloned Fieldset
  20. <fieldset class="clonable">
  21. <legend>User Details</legend>
  22. <div class="regrow">
  23. <div class="regrow">
  24. <label class="inside">First Name:</label>
  25. <input class="text" name="fname_2" type="text">
  26. </div>
  27. <div class="regrow">
  28. <label class="inside">Last Name:</label>
  29. <input class="text" name="lname_2" type="text">
  30. </div>
  31. <div class="regrow">
  32. <label class="inside">Email:</label>
  33. <input class="text" name="email_2" type="text">
  34. </div>
  35. </div>
As you can see it automatically increments the number of every input name. We'll now see how to get the data back easily on the server side once you submit your form.

Extra: How to get the data on the server side?

All the posted values have a name, which is based on the same pattern (as it has been cloned from the same source). We can then use a very simple loop on the server side to structure our data under a form that will be handy to work with:
  1. if (!empty($_POST)) { //The values have been posted
  2. $elements = array();
  3. foreach ($_POST as $key => $val) { //For every posted values
  4. $frags = explode("_", $key); //we separate the attribute name from the number
  5. $id = $frags[1]; //That is the id
  6. $attr = $frags[0]; //And that is the attribute name
  7. if (!empty($val)) {
  8. //We then store the value of this attribute for this element.
  9. $elements[$id][$attr] = htmlentities($val);
  10. }
  11. }
  12. }
  13.  
  14. //In our demonstration, the array elements would now contain the following structured data:
  15. print_r($elements);
  16. returns:
  17. [1] => Array (
  18. [fname] => Jeremy
  19. [lname] => Desvaux
  20. [email] => jeremy@jdmweb.com
  21. ),
  22. [2] => Array (
  23. [fname] => Steve
  24. [lname] => Jobs
  25. [email] => steve@apple.com
  26. )
  27. )

Conclusion

This very simple plugin completely removes all the headaches that are involved when you are looking at designing a similar solution. Its dynamic approach doesn't make it too markup dependent so it can work with any form. What do you think of it? Can you think about a way of improving it in any way? Do you find it useful? Let me know your thoughts via the comments.

12 Responses to Form Cloning jQuery Plugin

  1. @jdmweb. Does this support dynamic populating of values perhaps from a json object?

  2. @Jas.

    The plugin doesn't support it as such, but once the clone has beem created, you can populate it from the javascript event, (cf the javascript setup right after line 15, before return false ).

    Right here, you can load your json object, and load its values inside the clone, with something like:
    <code>$(yourclass+":last input[name=yourinput]").val(yourjson.yourval)</code>

    Regards.
    Jeremy

  3. First. I think it would be a great idea to be able to automatically add Delete button to each clone.
    Second. Does your plugin also clone event listeners, connected to cloned elements?

  4. think you for this script, but how i can recuparate the total number of clone that i have choice, thx

  5. Replying to myself. One should add DELETE button by hands.
    The events should be bound by jQuery.live() method - is is a great solution. Also we can bind DELETE button behavior through this.

  6. By hands, helmus27, by hands...

  7. Bonjour, j'essaie d'utiliser ce plugin sur un formulaire contenant des boutons radio à cloner mais sur internet explorer, malgré le changement d'attribut name de ces boutons radio à chaque clonage, ils restent liés. Quand on en sélectionne un, tous ceux des clones précédents se décochent aussi comme s'ils avaient tous le même attribut name. Merci d'avance pour ton aide.

  8. hi. just wondering if there is a way to select the number of fieldsets to be cloned from a value in a drop down list?

    Thanks!

  9. Where is jquery.formclone.js?
    This page seems to be dependant on jquery-1.js, general.js, jquery_002.js and formclone_setup.js, am I missing something
    ?

  10. @adrigen. Downward arrow. Got it.

  11. Hi, Hi have an error when I hit the button for clone. The error is this:

    Uncaught TypeError: Cannot read property 'length' of undefined jquery.cloneform.js:51
    $.fn.fieldclone jquery.cloneform.js:51
    (anonymous function) main.js:18
    x.event.dispatch jquery-2.0.3.min.js:5
    y.handle

    Thank you!

  12. Just wanted to thank you for your plugin. For others looking to add a delete button for their newly cloned elements you might want to try this:

    $('#clonetrigger').prev().append('');

    where #clonetrigger is the target_ used to insert_ the clone before.

    Then simply add your additional script to remove the clone.

Leave a Reply

Your email address will not be published. Required fields are marked *

Other Useful Resources

jQuery FancyBox plugin illustration

The FancyBox is one of the plugin that I like the most. It's so easy to use and renders really nicely, especially with images. It's a Mac like zooming tool that you can customize quite well and really looks amazing. Source and © Janis Skarnelis

Read more
Scroll to Top jQuery plugin illustration

If you happen to have on your site some pages that are a bit long, and therefore will lead your users to scroll down quite a bit to read your content, they may not have the patience to scroll again to get back up to the top. That's where this little plugin, hand made by NOE interactive comes in handy. Just put it on your website, and it will help your users get back to the top of pages with a single click, and with a small smooth animation (how nice is that :) ).

In this article featured on NOE interactive, you'll learn how you can install the jQuery plugin on your website. There's a complete step by step guide as well as a demonstration. If you wish to download the plugin, it's also hosted on Github.

Read more
How to easily integrate a PayPal Checkout with PHP illustration

PayPal is a renowned payment platform that allows you to accept online payments on your site, by taking care of all the money transactions for you. This transparency really is an appreciated quality that allows developers to integrate checkout solutions on merchant sites, by completely outsourcing the banking operations to PayPal.

Another good thing for developers is that the PayPal API is very versatile. It can be very simple if your needs are simple, or it can be very well customized to meet some more advanced needs such as complete shopping carts handling. On the other hand, I sometimes find this API not really user friendly as it works with forms, which fields are not always very intuitive. In other words, depending on the form you are building, you get a different service from PayPal.

In order to get a friendlier and also more generic solution, I wrote a PayPal manager in PHP. This tutorial will show you how you can benefit from this PHP class to integrate PayPal checkouts faster and in a much simpler way.

Read more