Créer des lignes vides dynamiquement dans vos formulaires avec Prototype
Si vous souhaitez créer un formulaire qui vous permette de créer autant de ligne de données que vous le souhaitez, cet article vous présente un code javascript générique qui vous permet de type de comportement. Ce code utilise Prototype, mais peut être adapté pour utiliser CssQuery.
Attention : Ce code nécessite le fichier node-utilities.js disponible sur la page Outils Javascripts
Ce code est un peu frustre est peut sans doute être largement amélioré, mais il marche bien et est générique.
Code HTML
En premier lieu, créez le code HTML permettant d'utiliser ce code :
<div id="incrementing-contents">
<div id="incrementing-content-template" class="last-increment incrementing-content">
<div class="field">
<?php echo select_tag('value-id-0',
options_for_select(
$select_values,
null,
array(
'include_blank' => true,
)), array(
'title' => __('Example select'),
'onchange' => 'addIncrementingContent()',
'id' => null,
)) ?>
</div>
<div class="field">
<?php echo textarea_tag('value-description-0', '', array (
'title' => __('Example description'),
'onchange' => 'addIncrementingContent()',
'id' => null,
)) ?>
</div>
</div>
</div>
Que fait ce code, et quelles sont ses spécificités ? C'est relativement simple.
- L'élément ayant pour id incrementing-contents est le contenant des lignes vides créées dynamiquement. Chaque nouvelle ligne vide est créée à la fin de cet élément, cela peut être un <div> comme dans cet exemple, mais aussi un <tbody>.
- L'élément ayant pour id incrementing-content-template est le modèle des lignes vides créées. Il est dupliqué pour créé chaque nouvelle ligne. Ses champs sont remis à zéro. Cet élément peut être un <div>, comme dans cet exemple, mais aussi un <tr>.
- Les éléments ayant pour classe incrementing-content sont les éléments créés dynamiquement. Cette classe permet d'établir un décompte des lignes déjà créées.
- La classe last-increment signale la dernière ligne du contenant incrementing-contents. Lorsqu'une nouvelle ligne est créée, les champs de la ligne ayant cette classe voient leur valeur onchange réinitialisée.
- Tous les champs dont la modification doit déclencher l'ajout d'une ligne doivent avoir pour valeur du déclencheur onchange la fonction : addIncrementingContent.
Attention : veillez à ce que les noms des champs de la ligne incrementing-content-template finisse par '0' car cela vous permet de gérer plus facilement leur récupération en PHP.
Code Javascript
Voici la fonction Javascript addIncrementingContent qui permet de faire fonctionner l'ajout dynamique de nouveaux champs :
function addIncrementingContent()
{
var incrementing_contents = document.getElementById('incrementing-contents');
var incrementing_content_template = document.getElementById('incrementing-content-template');
if(! (incrementing_contents && incrementing_content_template))
{
return true;
}
var previous_last_incrementings = $$('.last-increment');
var existing_incrementings = $$('.incrementing-content');
for(var i = 0; i < previous_last_incrementings.length; i++)
{
var previous_last_incrementing = previous_last_incrementings[i];
var form_fieldss = previous_last_incrementing.getElementsBySelector('input', 'select', 'textarea');
for(var j = 0; j < form_fieldss.length; j++)
{
form_fieldss[j].onchange = function() {};
}
removeClassName(previous_last_incrementing, 'last-increment');
}
var new_last_incrementing = incrementing_content_template.cloneNode(true);
addClassName(new_last_incrementing, 'last-increment');
new_last_incrementing.removeAttribute('id');
var form_fieldss = new_last_incrementing.getElementsBySelector('input', 'select', 'textarea');
for(var j = 0; j < form_fieldss.length; j++)
{
form_fieldss[j].value = '';
form_fieldss[j].onchange = function() { return addIncrementingContent() };
form_fieldss[j].name = form_fieldss[j].name + existing_incrementings.length;
}
incrementing_contents.appendChild(new_last_incrementing);
return true;
}
Code PHP
Pour récupérer en PHP les valeurs généré par un tel code, vous pouvez vous reporter à mon article Gérer les valeurs multiples avec Symfony et les formulaires AJAX.