Form Cloning jQuery Plugin

Construire des formulaires dynamiques est une tâche que nombre de développeurs web auront à réaliser durant certains projets. Par dynamique, je fais référence aux formulaires qui s'adaptent et changent selon les actions de l'utilisateur.

Un exemple simple de formulaire dynamique sont ceux qui permettent à l'utilisateur d'ajouter le même groupe d'information plusieurs fois, par exemple, une réservation où vous pouvez ajouter plusieurs billets, un formulaire d'adhérent avec plusieurs personnes, une page de media où l'on peut ajouter plusieurs photos en même temps etc etc, les possibilités sont nombreuses et variées.

Afin de faciliter le développement de ce type de formulaire, voici un petit plugin qui vous permettra de cloner dynamiquement un ensemble précis d'informations qui seront répétées. Si vous avez déjà cherché une solution de ce type afin de cloner des formulaires, des fieldsets ou quelques inputs, vous allez probablement trouver ce petit script utile.
  • Ressource Précédente
  • Télécharger
  • Ressource Suivante

Démonstration

User Details

Implémentation

Inclure le plugin

Afin d'utiliser le plugin, vous aurez tout d'abord besoin d'inclure la librairie jQuery, puis le script du plugin. Etant donné que ce script est plutôt petit, vous préférerez peut être copier coller le code dans un de vos fichiers JavaScript existant.

  1. /** jQuery Inclusion **/
  2. <script type="text/javascript" src="Chemin_vers/jQuery.js"></script>
  3. /** Plugin Inclusion **/
  4. <script type="text/javascript" src="Chemin_vers/jquery.formclone.js"></script>

Le code du formulaire

L'étape suivante consiste à préparer votre formulaire. Il n'y a que deux petites choses à prendre en compte afin de faire marcher le plugin.

Premièrement, assurez vous que les éléments que vous voulez cloner sont à l'intérieur d'un conteneur, (div, span, fieldset, ou ce que vous voulez), et ajouter une classe spécifique à ce conteneur, par exemple clonable. Cette classe sera plus tard utilisée afin de faire le lien entre le formulaire et le plugin.

Deuxièmement, ajoutez le numéro 1 après chaque nom d'input que vous voulez cloner, par exemple, prenom_1, nom_1, email_1 etc etc. Le plugin incrémentera ce numéro à chaque fois que vous ajouterez un nouveau clone.

Il ne vous manque maintenant plus qu'un bouton 'clonez moi', qui ajoutera un clone à chaque fois que vous le cliquez. Vous pouvez le voir ligne 16 du code suivant:

  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. </fieldset>
  14.  
  15. <div id="formbuttons" class="regrow">
  16. <input type="button" class="button" id="clonetrigger" value="Clone" />
  17. <input type="submit" class="button" id="clonesubmit" value="Submit" />
  18. </div>
  19.  
  20. </form>

Le code jQuery

Comme nous venons de le spécifier, le clonage est déclenché quand l'utilisateur clique un bouton ou un lien spécifique, (dans notre cas le bouton #clonetrigger). On associe donc le clonage à l'événement clic de ce bouton ligne 5.

Ligne 6, écrivez juste le nom de la classe que vous avez utilisé dans votre formulaire, (ici .clonable).

Lignes 7 et 8, le plugin calcule quel sera le numéro du clone suivant. Vous pouvez spécifier votre propre numéro si vous le désirez.

Ligne 10, on spécifie que le premier élément qui possède votre classe, est l'élément à cloner.

Lignes 12 et 13, vous pouvez customiser quelques paramètres afin de contrôler où le nouveau clone sera inséré dans votre page. La première option vous permet de cibler un élément spécifique, cela peut donc être l'id d'un div par exemple. Le deuxième paramètre vous permet de préciser où vous voulez insérer votre clone par rapport à cet élément (avant, après, à l'intérieur...), cela peut donc être un méthode de manipulation standard de jQuery (after, before, append, prepend, replaceWith etc).

Et finalement, ligne 14, vous pouvez passer une limite. Si cette limite est supérieure à 0, le plugin ne génèrera pas plus de clone que le nombre spécifié. Si cette limite est 0, elle est ignorée.

  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>

Pour approfondir: Le code généré

Si vous vous demandez ce à quoi peut bien ressembler le code que le plugin génère, et bien rassurez vous c'est très simple. En se basant sur vos éléments à cloner et leur numéro de départ, le plugin génère exactement le même code pour chaque clone, la seule différence étant le numéro, qui est incrémenté à chaque fois.

Par exemple, après un premier clonage, le code de la démonstration ressemble à cela:

  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. </fieldset>
  19.  
  20. //Cloned Fieldset
  21. <fieldset class="clonable">
  22. <legend>User Details</legend>
  23. <div class="regrow">
  24. <div class="regrow">
  25. <label class="inside">First Name:</label>
  26. <input class="text" name="fname_2" type="text">
  27. </div>
  28. <div class="regrow">
  29. <label class="inside">Last Name:</label>
  30. <input class="text" name="lname_2" type="text">
  31. </div>
  32. <div class="regrow">
  33. <label class="inside">Email:</label>
  34. <input class="text" name="email_2" type="text">
  35. </div>
  36. </div>
  37. </fieldset>

Comme vous pouvez le voir, les noms de chaque input on été incrémenté dynamiquement. Nous allons maintenant voir comment récupérer les données une fois qu'elles ont été postées.

Pour approfondir: Comment retrouver les données côté serveur?

Toutes les données qui seront postées, auront un nom, qui sera basé sur la même paterne (du fait qu'elles on été clonées à partir du même code). Il suffit donc d'utiliser une boucle très simple côté serveur afin de restructurer les données dans une forme qui sera plus pratique à travailler:

  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); returns:
  16. [1] => Array
  17. (
  18. [fname] => Jeremy
  19. [lname] => Desvaux
  20. [email] => jeremy@jdmweb.com
  21. ),
  22. [2] => Array
  23. (
  24. [fname] => Steve
  25. [lname] => Jobs
  26. [email] => steve@apple.com
  27. )
  28. )

Conclusion

Ce petit plugin s'occupe des difficultés que vous pouvez rencontrez quand vous avez à implémenter une solution de ce type, afin de vous permettre de vous concentrer sur autre chose. Son approche dynamique ne le rend du coup pas dépendant d'un code spécifique, il peut donc marcher avec tout type de formulaire.

Qu'en pensez vous? Avez vous des suggestions qui pourrait rendre ce plugin encore meilleur? Le trouvez vous utiles? Partagez vos pensées via les commentaires.

Partager:

  • Tweet this
  • Buy the author a coffee
  • Bump this
  • Digg this
  • Post this on Del.icio.us
  • Post this on StumbleUpon
  • Post this on Reddit
  • Post this on Technorati
  • Post this on Google
  • Post this on Facebook
  • Email this to a friend

Vous seriez peut être aussi intéressé par::

  • jQuery FancyBox Plugin
  • Wordpress SchmancyBox Plugin
  • How to make SEO friendly urls
  • jQuery jCarousel Plugin
  • How to easily integrate a PayPal Checkout with PHP
  • jQuery Form Validation Plugin

Commentaires récents

adrigen
@adrigen. Downward arrow. Got it.
De adrigen à 01:10 14/12/10 { Répondre }
adrigen
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
?
De adrigen à 01:09 14/12/10 { Répondre }
adrian
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!
De adrian à 14:04 19/11/10 { Répondre }
lamurse
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.
De lamurse à 11:53 05/11/10 { Répondre }
nixmrak
By hands, helmus27, by hands...
De nixmrak à 22:04 19/09/10 { Répondre }
nixmrak
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.
De nixmrak à 22:03 19/09/10 { Répondre }
helmus27
think you for this script, but how i can recuparate the total number of clone that i have choice, thx
De helmus27 à 19:09 17/09/10 { Répondre }
nixmrak
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?
De nixmrak à 11:08 10/09/10 { Répondre }
jdmweb
@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:
$(yourclass+":last input[name=yourinput]").val(yourjson.yourval)

Regards.
Jeremy
De jdmweb à 11:28 11/05/10 { Répondre }
Jas
@jdmweb. Does this support dynamic populating of values perhaps from a json object?
De Jas à 16:40 10/05/10 { Répondre }