Form Cloning jQuery Plugin
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.
Démonstration
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.
/** jQuery Inclusion **/ <script type="text/javascript" src="Chemin_vers/jQuery.js"></script> /** Plugin Inclusion **/ <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:
<form id="cloningdemo" action="/resources/formclone" method="post"> <fieldset class="clonable"> //Add the class clonable to the element to be cloned <legend>User Details</legend> //Then add your elements <div class="regrow"> <label>First Name:</label> <input type="text" name="fname_1" />//Each input must have a starting number </div> <div> <label>Last Name:</label> <input type="text" name="lname_1" />//Each input must have a starting number </div> </fieldset> <div id="formbuttons" class="regrow"> <input type="button" class="button" id="clonetrigger" value="Clone" /> <input type="submit" class="button" id="clonesubmit" value="Submit" /> </div> </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.
<script type="text/javascript"> //The jQuery Setup $(document).ready(function(){ $("#clonetrigger").click(function(){ var yourclass=".clonable"; //The class you have used in your form var clonecount = $(yourclass).length; //how many clones do we already have? var newid = Number(clonecount) + 1; //Id of the new clone $(yourclass+":first").fieldclone({//Clone the original elelement newid_: newid, //Id of the new clone, (you can pass your own if you want) target_: $("#formbuttons"), //where do we insert the clone? (target element) insert_: "before", //where do we insert the clone? (after/before/append/prepend...) limit_: 4 //Maximum Number of Clones }); return false; }); }); </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:
//Original Fieldset <fieldset class="clonable"> <legend>User Details</legend> <div class="regrow"> <div class="regrow"> <label class="inside">First Name:</label> <input class="text" name="fname_1" type="text"> </div> <div class="regrow"> <label class="inside">Last Name:</label> <input class="text" name="lname_1" type="text"> </div> <div class="regrow"> <label class="inside">Email:</label> <input class="text" name="email_1" type="text"> </div> </div> </fieldset> //Cloned Fieldset <fieldset class="clonable"> <legend>User Details</legend> <div class="regrow"> <div class="regrow"> <label class="inside">First Name:</label> <input class="text" name="fname_2" type="text"> </div> <div class="regrow"> <label class="inside">Last Name:</label> <input class="text" name="lname_2" type="text"> </div> <div class="regrow"> <label class="inside">Email:</label> <input class="text" name="email_2" type="text"> </div> </div> </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:
foreach($_POST as $key=>$val){ //For every posted values $id = $frags[1]; //That is the id $attr = $frags[0]; //And that is the attribute name //We then store the value of this attribute for this element. } } } //In our demonstration, the array elements would now contain the following structured data: ( [fname] => Jeremy [lname] => Desvaux [email] => jeremy@jdmweb.com ), ( [fname] => Steve [lname] => Jobs [email] => steve@apple.com ) )
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.

















This page seems to be dependant on jquery-1.js, general.js, jquery_002.js and formclone_setup.js, am I missing something
?
Thanks!
The events should be bound by jQuery.live() method - is is a great solution. Also we can bind DELETE button behavior through this.
Second. Does your plugin also clone event listeners, connected to cloned elements?
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