Multiplier un formulaire automatiquement

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Multiplier un formulaire automatiquement

par sadeq » 21 oct. 2008, 00:18

Voici une solution purement PHP (pas de javascript) pour comprendre le principe. En fait, c'est un jeu de tableaux HTML/PHP.

Le principe est le suivant :
  • 1. T'as un formulaire principal réservé pour l'identité des parents
    2. Et selon un nombre d'enfants donné, un ou plusieurs formulaires pour les identités des enfants sont insérés dans le formulaire principal.
La technique :
Pour conserver les données du formulaire principal selon les changements du nombre des enfants, les valeurs des zones sont réimprimées par PHP à chaque submit GET/POST.
Et pour stocker toutes les données des enfants, on utilisera des tableaux dont les valeurs sont toujours réimprimées par PHP à chaque submit GET/POST.

On aura donc 2 types de zones de données à gérer:
  • 1. La zone de données des parents (1 seule occurrence pour tout le formulaire)
    2. La zone de données des enfants (1 ou plusieurs occurrences pour tout le formulaire)
En tout on aura 2 submits et un seul formulaire principal (fiches enfants comprises).
Le premier submit conserne le changement du nombre d'enfants et le second déclenche l'enregistrement de toutes les données.

Voici l'exemple:

Modèle de la zone de données des parents : fiche_parents.htm

Code : Tout sélectionner

<p><b>Nom famille : </b><input type="text" name="nom_famille" value="<?php echo $_GET['nom_famille']; ?>" /></p> <p><b>Prénom du Père : </b><input type="text" name="prenom_pere" value="<?php echo $_GET['prenom_pere']; ?>" /></p> <p><b>Prénom de la mère : </b><input type="text" name="prenom_mere" value="<?php echo $_GET['prenom_mere']; ?>" /></p> <p><b>Nom de jeune fille de la mère : </b><input type="text" name="nom_jeune_fille_mere" value="<?php echo $_GET['nom_jeune_fille_mere']; ?>" /></p> <p><b>Nombre d'enfants :</b><input type="text" name="nombre_enfants" value="<?php echo ($_GET['nombre_enfants']?$_GET['nombre_enfants']:1); ?>" /> <input type="submit" value="Afficher formulaire enfants" /></p>
Remarque: PHP réimprime les valeurs du postage GET/POST

Modèle de la zone de données pour un enfant type : fiche_enfant.htm

Code : Tout sélectionner

<p><b>Prénom de l'enfant : </b><input type="text" name="prenom_enfant[]" value="<?php echo $_GET['prenom_enfant'][$i]; ?>" /></p> <p><b>Date de naissance : </b><input type="text" name="date_naissance_enfant[]" value="<?php echo $_GET['date_naissance_enfant'][$i]; ?>" /></p>
Remarque: les zones de données enfant sont nommées sous forme de tableau (se terminant par []) et PHP réimprime les valeurs du postage GET/POST

Et voici le corps du programme qui va gérer la construction et l'enregistrement du formulaire principal:
famille.php:
<form>
<?php 
//Afficher le modèle de la zone de données des parents
include("fiche_famille.htm");

//Selon le nombre d'enfants, afficher le(s) formulaire(s) de(s) enfant(s)
$_GET['nombre_enfants'] = $_GET['nombre_enfants']>0?$_GET['nombre_enfants']:1; //par défaut, afficher zone de données pour un enfant 
if ($_GET['nombre_enfants']>0){
	for($i = 0; $i<$_GET['nombre_enfants']; $i++) {//0 est l'index du premier enfant
               //Insérer le modèle de la zone de données enfant
		include("fiche_enfant.htm");
	}
}
?>
<p><input type="submit" name="enregistrer" value="Enregistrer" /></p>
</form>
L'algorithme est simple :
  • 1. Dans tout les cas, on affiche la zone de données des parents.
    2. On affiche les zones de données enfants selon le nombre d'enfants entré par l'utilisateur (mais, par défaut, on affiche une zone enfant)
Pour terminer le programme, on peut programmer l'enregistrement final en prenant en considération l'événement du bouton submit "enregistrer".

Exemple d'enregistrement dans une session:
<?php
//Enregistrement dans la Session
if ($_GET['enregistrer']){
	//enregistrer la famille
	$famille['nom_famille'] 		 = $_GET['nom_famille'];
	$famille['prenom_pere'] 		 = $_GET['prenom_pere'];
	$famille['prenom_mere'] 		 = $_GET['prenom_mere'];
	$famille['nom_jeune_fille_mere'] = $_GET['nom_jeune_fille_mere'];
	$famille['nombre_enfants'] 		 = $_GET['nombre_enfants'];
	for($i = 0; $i<$_GET['nombre_enfants']; $i++){
		$famille['enfants'][$i]['prenom_enfant'] 		 = $_GET['prenom_enfant'][$i];
		$famille['enfants'][$i]['date_naissance_enfant'] = $_GET['date_naissance_enfant'][$i];
	}
	$_SESSION['famille'] = $famille;
	//Message de confirmation d'enregistrement
	echo "<pre><b>Merci, votre enregistrement est pris en compte</b><ul>";
	print_r($famille);
	echo "</ul></pre>";
}
?>
ou bien, pour enregistrer les données dans un fichier :
<?php
//Enregistrement CSV
if ($_GET['enregistrer']){
	//enregistrer la famille
	$famille = array($_GET['nom_famille'], $_GET['prenom_pere'], $_GET['prenom_mere'], $_GET['nom_jeune_fille_mere'], $_GET['nombre_enfants']);
	for($i = 0; $i<$_GET['nombre_enfants']; $i++){
		$famille[] 	= $_GET['prenom_enfant'][$i];
		$famille[] 	= $_GET['date_naissance_enfant'][$i];
	}
	$f = fopen('familles.csv', 'a'); //ouvre le fichier de données CSV en mode Ajout
	fputcsv($f, $famille); //écrit les zones de données de la famille
	fclose($f);
	//Message de confirmation d'enregistrement
	echo "<pre><b>Merci, votre enregistrement est pris en compte</b><ul>";
	print_r($famille);
	echo "</ul></pre>";
}
?>
ou bien en enregistrant par SQL:
<?php
//SQL
if ($_GET['enregistrer']){
	//enregistrer la famille dans la table 'famille' clé primaire = 'nom_famille'
	$sql = sprintf("INSERT INTO famille (nom_famille, prenom_pere, prenom_mere, nom_jeune_fille_mere, nombre_enfants) VALUES ('%s', '%s', '%s', '%s', '%s')"
					, $_GET['nom_famille'], $_GET['prenom_pere'], $_GET['prenom_mere'], $_GET['nom_jeune_fille_mere'], $_GET['nombre_enfants']);
	mysql_db_query("bd_test", $sql, mysql_connect('localhost', 'root'));
	//
	for($i = 0; $i<$_GET['nombre_enfants']; $i++){
		//La table 'enfant' est liée à la table 'famille' par la clé étrangère 'nom_famille'
		$sql = sprintf("INSERT INTO enfant (nom_famille, prenom_enfant, date_naissance_enfant) VALUES ('%s', '%s', '%s')"
					, $_GET['nom_famille'], $_GET['prenom_enfant'][$i], $_GET['date_naissance_enfant'][$i]);
		mysql_db_query("bd_test", $sql, mysql_connect('localhost', 'root'));
	}
 	mysql_close();
 	//Message de confirmation d'enregistrement
	echo "<pre><b>Merci, votre enregistrement est pris en compte</b><ul>";
	print_r($_GET);
	echo "</ul></pre>";
}
?>

par dogmongo » 20 oct. 2008, 23:45

Bonsoir

C’est clair qu’AJAX est la bonne solution

Moi je mettrais un champ "nb_enfant" en mode "hidden" qui serait généré via AJAX pendant la régénération du formulaire, avec les nouveaux champs enfants, pour facilité le traitement, ca éviterai les tests de variable.

J’avais fais ca à l'époque en PHP, je me suis arraché les cheveux et quand j'ai découvert AJAX quelques années après, ils sont tombés tous seul :mrgreen: :mrgreen: :mrgreen:

Dog

par Mathieu Nisen » 20 oct. 2008, 23:11

Merci AB ;) je regarde ça demain :)

par AB » 20 oct. 2008, 22:24

Pour ceux qui seraient également intéressés par un formulaire à dupliquer, j'ai trouvé un site magnifique qui permet d'y parvenir à l'aide d'AJAX.

http://www.zapatec.com/website/main/pro ... tiple.html
:lol: C'est exactement le principe du code que je t'ai montré plus haut. Dans ce cas ajax est inutile et javascript suffit largement (à lui seul).

Teste le code que j'ai mis dans ce topic http://www.phpfrance.com/forums/voir_re ... php#263729 puis essaies de comprendre les explications dans mon message suivant.

par Mathieu Nisen » 20 oct. 2008, 21:36

Pour ceux qui seraient également intéressés par un formulaire à dupliquer, j'ai trouvé un site magnifique qui permet d'y parvenir à l'aide d'AJAX.

http://www.zapatec.com/website/main/pro ... tiple.html

par Mathieu Nisen » 20 oct. 2008, 16:13

Merci pour vos réponses, je vais regarder comment intégrer ça dans mon code. Ce sera pas si simple vu mon faible niveau :)

par AB » 20 oct. 2008, 15:30

Eventuellement tu pourrais aussi faire ça en javascript, ce qui permettrait au visiteur d'ajouter des champs à la volée, sans avoir besoin de ré afficher la page.

Dans ce cas faut voir du côté du DOM

Pour ajouter un ou plusieurs input la fonction js pourrait ressembler à ça

Code : Tout sélectionner

function addinput(idChamp) { var conteneur = document.getElementById(idChamp); var ligne = document.createElement('p'); var nom = document.createElement('input'); nom.setAttribute('type','text'); nom.setAttribute('name','nom[]'); //... ligne.appendChild(nom); conteneur.appendChild(ligne); //... }

par Patriboom » 20 oct. 2008, 15:25

Ce me semble plutôt simple:

En complétant le premier formulaire, tu y inclus un une case "Combien d'enfants" avec valeur par défaut=1; les usagers changeront au besoin. Le formulaire réfère à la même page (a lui-même) et dans la prog PHP, tu comptes à rebours le nombre d'enfants à ajouter. Tu fais remplir par PHP les valeurs des champs redondants au chargement de la page dans le style de:

Code : Tout sélectionner

<input name="Pere" value="<?php echo @_POST["Pere"]; ?>" size=20>
Ainsi de suite pour tous les champs redondants.

Avant d'arriver à ton formulaire (balise <form>) tu auras pris soin de vérifier la valeur de "NbEnfants" et de la réduire d'un:
$_POST["NbEnfants"] =  (isset($_POST["NbEnfants"]) ? $_POST["NbEnfants"]-1 : 1;
if ($_POST["NbEnfants"] == 0) { header("Location: page_de_renvoi_final.php"); }

par Mathieu Nisen » 20 oct. 2008, 14:37

Mmmmh ... ta remarque est judicieuse... mais les champs qui se répéteraient doivent normalement avoir des réponses spécifiques et dépendent totalement de l'enfant à inscrire. Si effectivement, on peut estimer que 2 frères ont en règle générale le même nom de famille, il n'en va pas de même pour la date de naissance (à moins que ce soit des jumeaux) ou du prénom par exemple... Je pense justement tenter de faciliter l'utilisateur en multipliant les champs selon le nombre d'enfants, plutôt que devoir refaire tout le formulaire de A à Z pour chaque enfant. Du moins c'est le but que je recherche :D

merci à Sadeq pour sa réponse !

par Berzemus » 20 oct. 2008, 14:28

Au fait, plutôt du côté conception, mais tu risques pas d'avoir des champs redondants ?

Je suis un peu dans un trip "facilitez le web!", ou plutôt "don't make me think!", mais moi ça m'outrecuide que de devoir saisir plusieurs fois les mêmes données dans un même formulaire. Si c'est la cas (ça peut ne pas l'être), tu peux alors penser diviser les champs entre les champs propres à l'enfant, et des champs aux informations plus générales (genre le n. de tel. des parents, l'adresse, etc..)

Mais j'imagine qu'il faut sans doute aussi considérer les cas ou les enfants n'habitent pas à la maison, dans les cas d'une séparation de fait, ou d'autres circonstances peu banales.

par sadeq » 20 oct. 2008, 14:20

Oui, je te dirai ça quand j'aurai le temps ce soir.

Multiplier un formulaire automatiquement

par Mathieu Nisen » 20 oct. 2008, 14:09

Bonjour,

Je ne suis pas un expert de PHP, mais je pense que mon problème a plus intérêt à se retrouver dans la partie avancée du forum. Je m'explique brièvement :

Je dois développer un fomulaire pour une école où les parents peuvent inscrire leur enfant pour l'année scolaire. Jusque là, il s'agit d'un formulaire classique avec age, sexe, nom, prénom, etc.
Le hic, c'est que ces mêmes parents doivent pouvoir inscrire plusieurs enfants dans l'école en n'utilisant qu'une fois le formulaire.
J'aimerais donc avoir un champ qui demanderait par exemple "combien d'enfants souhaitez-vous inscrire ?" et selon le chiffre qu'ils tapent, afficher un nombre de formulaires identiques.

Est-ce qu'il est possible de faire une boucle dans PHP sur un formulaire complet en ajoutant automatiquement un ID unique du style enfant001, enfant002, enfant003 etc ?

Un tout grand merci !

Mathieu