-
Notifications
You must be signed in to change notification settings - Fork 0
/
jquery.doydoyclone.js
361 lines (325 loc) · 16.5 KB
/
jquery.doydoyclone.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
/**
* Doydoy Clone
*
* @brief JQuery plugin to clone a group of elements with the management of ids
*
* @author doydoy44
* @version 1.1
*
*/
(function ($) {
"use strict";
/////////////////////////////////////////////////////
// Variables globales au plugin mais privée //
// (non accessible en dehors du plugin) //
/////////////////////////////////////////////////////
var
// nbre de clonage pour éviter d'avoir les mêmes ids
doydoy_counter = 0,
// nouvel id du conteneur(parent) créé
doydoy_new_id = null,
// préfix d'un nouvel id au cas où l'id n'existerait pas
glob_prefix_new_elt = "id_doydoy_clone_",
// Liste de tous les éléments cloner depuis le début
doydoy_all_clones = [],
// Liste de tous les éléments cloner lors du dernier clonage
doydoy_last_clones = [];
//////////////////////////////////////////////////////////
// LISTE DES FONCTIONS DISPONIBLES EN DEHORS DU CLONAGE //
//////////////////////////////////////////////////////////
// Récupération du nombre de clonage effectué
$.fn.doydoyGetCounter = function () {
return doydoy_counter;
};
// Récupération de la liste de tous les éléments cloner depuis le début
$.fn.doydoyGetAllClones = function () {
return doydoy_all_clones;
};
// Récupération de la liste de tous les éléments cloner lors du dernier clonage
$.fn.doydoyGetLastClones = function () {
return doydoy_last_clones;
};
// Récupération de l'id du dernier conteneur (parent) créé
$.fn.doydoyGetLastNewId = function () {
return doydoy_new_id;
};
// Affectation du préfix pour un nouvel id au cas où l'id n'existerait pas
$.fn.doydoySetPrefixNewId = function (prefix_new_elt) {
glob_prefix_new_elt = prefix_new_elt;
return this;
};
// Réinitialisation de la liste de tous les éléments cloner depuis le début
$.fn.initAllClonesList = function () {
doydoy_all_clones = [];
return this;
};
/////////////////////////////////////////////////////
// LISTE DES METHODES RACCOURCIES //
/////////////////////////////////////////////////////
// Méthode after pour le clonage
$.fn.doydoyCloneAfter = function (params) {
params = $.extend(params, {method : "after"});
return this.doydoyClone(params);
};
// Méthode before pour le clonage
$.fn.doydoyCloneBefore = function (params) {
params = $.extend(params, {method : "before"});
return this.doydoyClone(params);
};
// Méthode append pour le clonage
$.fn.doydoyCloneAppend = function (params) {
params = $.extend(params, {method : "append"});
return this.doydoyClone(params);
};
// Méthode prepend pour le clonage
$.fn.doydoyClonePrepend = function (params) {
params = $.extend(params, {method : "prepend"});
return this.doydoyClone(params);
};
/////////////////////////////////////////////////////
// Plugin de clonage //
/////////////////////////////////////////////////////
$.fn.doydoyClone = function (params) {
// type de traitement pour la fonction eval (after par défaut)
var function_plugin_name = 'after';
// Fusionner les paramètres par défaut et ceux de l'utilisateur
params = $.extend({
method : "",
target : "",
impact_name : true,
impact_for : true,
new_name : false,
new_all_name : false,
new_all_id : false,
prefix_new_elt : glob_prefix_new_elt
}, params);
if (params.new_all_name) {
params.new_name = true;
}
// Incrémentation du compter pour commencer à avoir des id à partir de 1 (idfoo_1) et supérieur au dernier clonage
doydoy_counter += 1;
// Récupération du type de traitement pour la fonction eval (after par défaut)
switch (params.method) {
case "after":
case "before":
case "append":
case "prepend":
function_plugin_name = params.method;
break;
default:
function_plugin_name = 'after';
break;
}
// Traverser tous les nœuds.
this.each(function () {
var
// id sans le numéro d'incrémentation du futur conteneur (parent)
id_elt,
// élément à cloner
elt_a_cloner = this,
// numéro d'incrémentation du futur conteneur (parent)
doydoy_counter_clone = doydoy_counter,
// Récupération de l'élément à qui rajouter les éléments
dernier_element = "",
// Numéro de l'enfant par rapport à son parent
cpt_child = 0,
// id d'origine de l'enfant avant son nouvel id
id_before = "",
// nouvel id de l'enfant
new_id = "",
// nouveau nom de l'enfant
new_name = "",
// compteur for
cpt_for = "";
// Initialisation des derniers éléments clonés
doydoy_last_clones = [];
// Initialisation du nouvel id
doydoy_new_id = null;
// Définition de l'id (sans le numéro d'incrémentation) du futur conteneur (parent)
if ($(this).attr('id') === undefined) {
if ($(this).attr('name') !== undefined) {
id_elt = params.prefix_new_elt + $(this).attr('name');
} else {
id_elt = params.prefix_new_elt + $(this).prop('tagName');
}
} else {
id_elt = $(this).attr('id');
}
// Récupération de l'élément à qui rajouter les éléments clonés et y affecter la méthode after, before, ...
// si non renseigné, on prend l'élément à cloner
if (params.target !== "") {
dernier_element = params.target;
} else {
dernier_element = $(this);
}
// Clonage de l'ensemble des éléments
function function_clone() {
// retour de l'ensemble des élements clonés
return $(elt_a_cloner).clone(true).each(function () {
// Détermination de l'd du parent cloné
doydoy_new_id = id_elt + "_" + doydoy_counter_clone;
$(this).attr('id', doydoy_new_id);
// Détermination du nouveau nom du parent cloné si on a choisi l'option
var new_name_parent = "";
if ($(this).attr('name') !== undefined) {
new_name_parent = $(this).attr('name');
if (params.new_name || params.impact_name) {
new_name_parent += "_" + doydoy_counter_clone;
$(this).attr('name', new_name_parent);
}
} else {
if (params.new_name) {
new_name_parent = doydoy_new_id;
$(this).attr('name', new_name_parent);
}
}
// Changement de l'attribut for qui fait référence à l'ancien id d'un input + "_" + numéro de clonage
if ($(this).attr('for') !== undefined) {
if (params.impact_for) {
$(this).attr('for', $(this).attr('for') + "_" + doydoy_counter_clone);
}
}
// Sauvegarde de ce nouveau parent dans la liste de tous les éléments clonés depuis le début
if (doydoy_all_clones['"' + doydoy_counter_clone + '"'] === undefined) {
doydoy_all_clones['"' + doydoy_counter_clone + '"'] = [];
}
doydoy_all_clones['"' + doydoy_counter_clone + '"'].parent = {id : doydoy_new_id,
id_before : id_elt,
num_clone : doydoy_counter_clone,
name : new_name_parent,
elt : $(this)};
// Sauvegarde de ce nouveau parent dans la liste de tous les éléments clonés lors du dernier clonage
doydoy_last_clones.parent = {id : doydoy_new_id,
id_before : id_elt,
num_clone : doydoy_counter_clone,
name : new_name_parent,
elt : $(this)};
// incrémentation du numéro de clonage pour éviter d'avoir les mêmes ids
doydoy_counter_clone += 1;
});
}
// parcourt de tous les enfants du conteneur cpt_for
function each_child(cpt_for) {
cpt_child = 0;
$("#" + id_elt + "_" + cpt_for + " *").each(function () {
// Détermination du nouvel id de l'enfant en cours
if ($(this).attr('id') !== undefined) {
// récupération de l'id d'origine de l'enfant
id_before = $(this).attr('id');
new_id = id_before + "_" + cpt_for;
// changement de l'id
$(this).attr('id', new_id);
} else {
// Initialisation de l'id d'origine et du nouvel id (car il n'en avait pas forcément)
id_before = "";
if (params.new_all_id) {
if ($(this).attr('name') !== undefined) {
new_id = params.prefix_new_elt + $(this).attr('name') + "_" + cpt_for;
} else {
new_id = params.prefix_new_elt + $(this).prop('tagName') + "_" + cpt_for;
}
// Changement de l'id
$(this).attr('id', new_id);
} else {
new_id = "";
}
}
// Changement du nom si on l'a demandé (params.new_name : true)
if ($(this).attr('name') !== undefined) {
new_name = $(this).attr('name');
if (params.new_all_name || params.impact_name) {
new_name += "_" + cpt_for;
$(this).attr('name', new_name);
}
} else {
if (params.new_all_name) {
if (new_id !== "") {
new_name = new_id;
} else {
new_name = params.prefix_new_elt + $(this).prop('tagName') + "_" + cpt_for;
}
$(this).attr('name', new_name);
} else {
new_name = "";
}
}
// nouvel référence pour l'attribut "for" d'un label qui fait référence à l'ancien id d'un input + "_" + numéro de clonage
if ($(this).attr('for') !== undefined) {
if (params.impact_for) {
$(this).attr('for', $(this).attr('for') + "_" + cpt_for);
}
}
// Sauvegarde de ce nouvel enfant dans la liste de tous les éléments clonés depuis le début
if (doydoy_all_clones['"' + cpt_for + '"'].child === undefined) {
doydoy_all_clones['"' + cpt_for + '"'].child = [];
}
doydoy_all_clones['"' + cpt_for + '"'].child[cpt_child] = {id : new_id,
id_before : id_before,
num_clone : cpt_for,
name : new_name,
elt : $(this)};
// Sauvegarde de ce nouvel enfant dans la liste de tous les éléments clonés lors du dernier clonage
if (cpt_for === (doydoy_counter_clone - 1)) {
doydoy_last_clones.child[cpt_child] = {id : new_id,
id_before : id_before,
num_clone : cpt_for,
name : new_name,
elt : $(this)};
/*
// fonction appelée après la création d'un nouvel enfant du dernier conteneur
if (params.each_last_child_callback != undefined){
params.each_last_child_callback('"' + cpt_for + '"', id_elt + "_" + cpt_for, cpt_child, new_id);
}
*/
}
// fonction appelée après la création d'un nouveau conteneur
if (params.each_child_callback !== undefined) {
// paramètre 1 : "cpt_for" correspond à l'index du conteneur -> doydoy_all_clones[cpt_for] -> commence à 1 => Numéro du clonage
// paramètre 2 : id_elt + "_" + cpt_for correspond à l'id du conteneur cloné
// paramètre 3 : cpt_child correspond à l'index de l'enfant -> doydoy_all_clones[cpt_for]['child'][cpt_child] -> commence à 0
// paramètre 4 : new_id correspond à l'id de l'enfant cloné
params.each_child_callback('"' + cpt_for + '"', id_elt + "_" + cpt_for, cpt_child, new_id);
}
// Incrémentation de l'enfant pour passer au suivant
cpt_child += 1;
});
// fonction appelée après la création d'un nouveau conteneur
if (params.each_callback !== undefined) {
// paramètre 1 : "cpt_for" correspond à l'index du conteneur -> doydoy_all_clones[cpt_for] -> commence à 1 => Numéro du clonage
// paramètre 2 : id_elt + "_" + cpt_for correspond à l'id du conteneur cloné
params.each_callback('"' + cpt_for + '"', id_elt + "_" + cpt_for);
}
}
// Ajout de l'ensemble cloné à l'élément choisi avec la méthode choisie (after, begin, prepend, append)
//
switch (function_plugin_name) {
case "after":
$(dernier_element).each(function () { $(this).after(function_clone()); });
break;
case "before":
$(dernier_element).each(function () { $(this).before(function_clone()); });
break;
case "append":
$(dernier_element).each(function () { $(this).append(function_clone()); });
break;
case "prepend":
$(dernier_element).each(function () { $(this).prepend(function_clone()); });
break;
}
// Initialisation de la liste des derniers enfants créés
doydoy_last_clones.child = [];
// Ré-attribution des ids des élements des conteneurs qui ont été créés
for (cpt_for = doydoy_counter; cpt_for < doydoy_counter_clone; cpt_for += 1) {
each_child(cpt_for);
}
// Ré-initialisation du compteur de conteneurs (parents) créés
doydoy_counter = doydoy_counter_clone - 1;
});
// fonction appelée après la création de tous les nouveaux conteneurs
if (params.callback !== undefined) {
params.callback();
}
// Permettre le chaînage par jQuery
return this;
};
})(jQuery);