Voici mon problème: dans un formulaire, je souhaite que l'utilisateur puisse créer autant de champs que nécessaire.
J'ai récupéré un script qui fait exactement ce que souhaite: en cliquant sur un bouton, ça me rajoute une ligne avec les champs voulus.
Dans le DOM, ces nouveaux champs apparaissent bien mais lorsque je veux valider mon formulaire avec une méthode POST, seule la 1ere ligne est prise en compte.
Voici mes morceaux de code:
le script multlifield.js
/**
* jQuery Multifield plugin
*
* https://github.com/maxkostinevich/jquery-multifield
*/
// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
;(function ( $, window, document, undefined ) {
/*
* Plugin Options
* section (string) - selector of the section which is located inside of the parent wrapper
* max (int) - Maximum sections
* btnAdd (string) - selector of the "Add section" button - can be located everywhere on the page
* btnRemove (string) - selector of the "Remove section" button - should be located INSIDE of the "section"
* locale (string) - language to use, default is english
*/
// our plugin constructor
var multiField = function( elem, options ){
this.elem = elem;
this.$elem = $(elem);
this.options = options;
// Localization
this.localize_i18n={
"multiField": {
"messages": {
"removeConfirmation": "Are you sure you want to remove this section?"
}
}
};
// This next line takes advantage of HTML5 data attributes
// to support customization of the plugin on a per-element
// basis. For example,
// <div class=item' data-mfield-options='{"section":".group"}'></div>
this.metadata = this.$elem.data( 'mfield-options' );
};
// the plugin prototype
multiField.prototype = {
defaults: {
max: 0,
locale: 'default'
},
init: function() {
var $this = this; //Plugin object
// Introduce defaults that can be extended either
// globally or using an object literal.
this.config = $.extend({}, this.defaults, this.options,
this.metadata);
// Load localization object
if(this.config.locale !== 'default'){
$this.localize_i18n = this.config.locale;
}
// Hide 'Remove' buttons if only one section exists
if(this.getSectionsCount()<2) {
$(this.config.btnRemove, this.$elem).hide();
}
// Add section
this.$elem.on('click',this.config.btnAdd,function(e){
e.preventDefault();
$this.cloneSection();
});
// Remove section
this.$elem.on('click',this.config.btnRemove,function(e){
e.preventDefault();
var currentSection=$(e.target.closest($this.config.section));
$this.removeSection(currentSection);
});
return this;
},
/*
* Add new section
*/
cloneSection : function() {
// Allow to add only allowed max count of sections
if((this.config.max!==0)&&(this.getSectionsCount()+1)>this.config.max){
return false;
}
// Clone last section
var newChild = $(this.config.section, this.$elem).last().clone().attr('style', '').attr('id', '').fadeIn('fast');
// Clear input values
$('input[type!="radio"],textarea', newChild).each(function () {
$(this).val('');
});
// Fix radio buttons: update name [i] to [i+1]
newChild.find('input[type="radio"]').each(function(){var name=$(this).attr('name');$(this).attr('name',name.replace(/([0-9]+)/g,1*(name.match(/([0-9]+)/g))+1));});
// Reset radio button selection
$('input[type=radio]',newChild).attr('checked', false);
// Clear images src with reset-image-src class
$('img.reset-image-src', newChild).each(function () {
$(this).attr('src', '');
});
// Append new section
this.$elem.append(newChild);
// Show 'remove' button
$(this.config.btnRemove, this.$elem).show();
},
/*
* Remove existing section
*/
removeSection : function(section){
if (confirm(this.localize_i18n.multiField.messages.removeConfirmation)){
var sectionsCount = this.getSectionsCount();
if(sectionsCount<=2){
$(this.config.btnRemove,this.$elem).hide();
}
section.slideUp('fast', function () {$(this).detach();});
}
},
/*
* Get sections count
*/
getSectionsCount: function(){
return this.$elem.children(this.config.section).length;
}
};
multiField.defaults = multiField.prototype.defaults;
$.fn.multifield = function(options) {
return this.each(function() {
new multiField(this, options).init();
});
};
})( jQuery, window, document );
$('#example-1').multifield({
// form group you want to duplicate
section: '.group',
// add button
btnAdd:'#btnAdd',
// remove button
btnRemove:'.btnRemove',
// maximum number of form groups to duplicate
max: 3,
// localization
locale:'default'
});
Je précise que je travail avec un WAMP en local.
Merci d'avance pour votre aide, la je sèche complètement.
- Edité par FabriceMichel7 7 décembre 2018 à 16:39:18
Bonjour. Utilises les outils de développement de ton navigateur qui te permettent d'afficher l'arbre du DOM au fur et à mesure de la création des éléments. Tu verras s'il sont placés comme il faut, si leur name correspond à ce que tu attends etc...
salut, est ce que tu peux creer une 2e section, copier coller le code source de ta page entre les balises form, et afficher le resultat de var_dump($_POST) ?
clique sur ajouter, ce qui rajoute une nouvelle section .group. Une fois que tu as cliqué, va voir dans les onglets du navigateur, cherches outils pour developpeur, et regarde le code source de ta page.
L'ajout des sections dans le div m'allait très bien, donc si je veux adapter le bouton supprimer par rapport a ton premier code, il faudrait faire ça ?
function supprimer(me) {
document.getElementById('sample').removeChild(me.parentNode)
}
Autre question, dans mon formulaire, j'ai 2 parties ou je dois utiliser la fonction utiliserSection.
J'ai biaisé le problème en duplicant cette fonction mais est-il possible d'en garder qu'une et en mettant en paramètre de celle-ci l'id de la div ?
« L'ajout des sections dans le div m'allait très bien »
Je n'ai pas en tête l'arborescence de ta page.
Pour que la section qu'on clone ne vienne pas perturber les données envoyées en post, il vaut mieux la sortir du formulaire. Quant au div en question (sample), il faut bien entendu qu'il soit dans le formulaire. Après, tu fais ce que tu veux. Enfin presque, car si je ne dis pas de bêtise, l'argument de la fonction removeChild() doit être un enfant direct (et non pas l'enfant d'un enfant) de celui auquel est appliqué la fonction.
Donc quand tu fais elt1.removeChild(elt2), elt2 doit être enfant direct de elt1.
« est-il possible d'en garder qu'une et en mettant en paramètre de celle-ci l'id de la div ? »
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Pas d'aide concernant le code par MP, le forum est là pour ça :)