Section: Gérer un formulaire après soumission
« Affichage d'un formulaire | ^ jForms : des formulaires automatiques | Gérer un formulaire avec Xhr » |
− Table des matières
Une fois un formulaire créé, il faut, dans une action l'afficher, ce qui est expliqué dans un chapitre à part. Et dans une autre action, qui sera appelée quand l'utilisateur validera le formulaire, il faudra gérer les données saisies : récupération des données, vérification de leur contenu et enfin traitement (stockage par exemple).
Remplissage à partir des données saisies ¶
Vous l'avez déjà vu un peu plus haut, pour récupérer l'objet formulaire tout en
le remplissant à partir des données reçues du navigateur, il suffit d'appeler
jForms::fill()
:
$form = jForms::fill("main~contact");
Cela est en fait équivalent à
$form = jForms::get("main~contact");
$form->initFromRequest();
Vous pouvez aussi utiliser la méthode setData()
sur le formulaire pour remplir
vous même le contenu du formulaire :
$form = jForms::get("main~contact");
$form->setData('nom', $this->param('nom'));
Vérification des données ¶
Une fois le formulaire récupéré avec les bonnes données, il est souvent
préférable d'en vérifier exactement le contenu avant de traiter les données.
Vous avez à votre disposition la méthode check()
qui vérifie les données en
fonction de ce que vous avez indiqué dans le fichier xml (l'aspect obligatoire
de la saisie, le type de donnée pour les inputs etc...). La méthode check()
renvoi true si la vérification est bonne, ou false si il y a des erreurs dans le
formulaire.
En général, si la validation échoue, vous avez simplement à réafficher le formulaire : les erreurs s'afficheront automatiquement et l'utilisateur devra corriger.
$form = jForms::fill("main~contact");
if (!$form->check()) {
// invalide : on redirige vers l'action d'affichage
$rep = $this->getResponse('redirect');
$rep->action='module~default:show';
return $rep;
}
Vous pouvez, bien sûr, faire des vérifications approfondies. Vous pouvez alors utiliser la méthode getData pour récupérer la valeur d'un champ de saisie, et setErrorOn pour indiquer une erreur sur un champ.
$form = jForms::fill("main~contact");
if (!$form->check()) {
// invalide : on redirige vers l'action d'affichage
$rep = $this->getResponse('redirect');
$rep->action='module~default:show';
return $rep;
}
$ok = true;
$valeur = $form->getData('nom');
if( strpos($valeur, 'azerty') !== null) {
$ok = false;
$form->setErrorOn('nom', 'tu as un nom bizarre toi !');
}
// autres vérifications
//....
if (!$ok) {
// invalide : on redirige vers l'action d'affichage
$rep = $this->getResponse('redirect');
$rep->action='module~default:show';
return $rep;
}
Connaitre les valeurs qui ont été modifiées ¶
Quand un formulaire a été initialisé il peut être utile de savoir quelles valeurs ont été modifiées.
Pour cela, vous devez d'abord appeler la méthode initModifiedControlsList()
après avoir initialisé votre formulaire, de manière à indiquer que vous voulez
connaître les différences.
Ensuite, après un submit par exemple, vous pouvez appeler la méthode
getModifiedControls()
, qui renvoie un tableau dont les clés sont les noms des
contrôles modifiés, et les valeurs étant les anciennes valeurs.
// dans l'action d'initialisation
$form = jForms::create("main~contact");
$form->initFromDao(...);
$form->initModifiedControlsList();
// dans l'action du submit
$form = jForms::fill("main~contact");
if (!$form->check()) {
...
}
$liste = $form->getModifiedControls();
Stockage des données ¶
Une fois la vérification faite, vous pouvez extraire les données du formulaire
avec la méthode getData()
ou getAllData()
qui renvoie toutes les
données sous forme de tableau. Ensuite libre à vous d'en faire ce que vous
voulez : les stocker avec jDb ou jDao, les envoyer par mail etc...
Stockage via un dao ¶
Tout comme il y a initFromDao()
pour initialiser le formulaire, il y a
l'opération inverse saveToDao()
. Cette méthode permet donc d'enregistrer
plusieurs champs via un dao. Les valeurs des champs dont les noms correspondent
à des propriétés du dao indiqué seront utilisées pour renseigner les propriétés
du dao correspondantes, et le tout sera enregistré dans l'enregistrement dont la
clé est indiquée dans l'id du formulaire. Si l'id du formulaire est inexistant,
un nouvel enregistrement sera créé, plutôt qu'une mise à jour d'un
enregistrement existant.
$form->saveToDao('shop~products');
Si la clé primaire n'est pas auto incrémentale, alors il vous faudra indiquer la
valeur de cette clé, en deuxième argument à saveToDao
, dans le cas d'un
nouvel enregistrement. La méthode accepte aussi un nom de profil jDb en
troisième argument.
Dans certains cas il peut être utile de récupérer la clé primaire d'un
enregistrement créé à l'aide de la méthode saveToDao
.
$primaryKey = $form->saveToDao('shop~products');
saveToDao()
est très pratique, mais on pourrait vouloir juste pré-remplir un
dao avec le contenu du formulaire, manipuler ensuite ce dao pour initialiser
d'autres de ces propriétés "à la main", et faire les sauvegardes nous-mêmes.
Pour ce faire, il y a la méthode prepareDaoFromControls
, qui prend les
mêmes arguments que saveToDao
, mais renvoie un tableau contenant l'objet
record Dao ("daorec"), l'objet factory dao ("dao"), et un boolean ("toInsert")
indiquant s'il faut insérer ou mettre à jour l'enregistrement.
$result = $form->prepareDaoFromControls('shop~products');
$result['daorec']->autrechamps='bla';
if($result['toInsert'])
$result['dao']->insert($result['daorec']);
else
$result['dao']->update($result['daorec']);
Stockage des valeurs d'un champ à choix multiples ¶
Il y a la méthode saveControlToDao()
, qui est l'opération inverse de
initControlFromDao()
. Elle permet donc de sauvegarder les valeurs
sélectionnées d'un ensemble de cases à cocher ou d'une liste à choix multiples,
dans une table de jointure.
$form->saveControlToDao('categories', 'shop~products_categories');
Le premier paramètre est le nom du champ concerné, et le deuxième le dao utilisé pour le stockage.
Stockage des fichiers ¶
Si le formulaire contient des champs de téléchargement de fichiers, il vous faut
sauver les fichiers quelque part. Vous avez pour cela deux méthodes,
saveFile()
et saveAllFiles()
. La première pour sauvegarder un fichier
précis, et l'autre pour copier tous les fichiers reçus dans un répertoire.
Sachez que dans les données du formulaire, la valeur du champ (que l'on récupère
via getData) contient le nom du fichier original. Si vous avez besoin de stocker
un autre nom, faites un setData.
saveFile()
prend en argument le nom du champ contenant le fichier. Par
défaut, le fichier est alors stocké dans le répertoire
/var/uploads/nommodule~nomform/
. Vous pouvez indiquer un autre répertoire
en donnant son chemin en deuxième paramètre de saveFile()
. Et si vous voulez
stocker le fichier sous un nom différent, indiquez le en troisième paramètre.
Exemple :
$form->saveFile('photo');
$form->saveFile('photo', jApp::wwwPath('images/photos/'));
$form->saveFile('photo', jApp::wwwPath('images/photos/'), $id.'.png');
$form->saveFile('photo', '', $id.'.png');
saveAllFiles()
sauve tout les fichiers, sans distinction, dans un même
répertoire. Le répertoire par défaut est /var/uploads/nommodule~nomform/
,
mais vous pouvez le changer en l'indiquant en paramètre.
$form->saveAllFiles();
$form->saveAllFiles(jApp::wwwPath('images/photos/'));
Notez que si vous utilisez <upload2>
(ou jFormsControlUpload2
),
la suppression du fichier précédent, si il y en avait un, est automatique.
Ce n'est pas le cas avec <upload>
, où vous devez garder une référence à
l'ancien fichier quelque part, afin de le supprimer vous même après l'upload du
nouveau fichier.
Détruire une instance d'un formulaire ¶
Quand un formulaire n'est plus utilisé (la saisie est finie, les données
sauvegardées), il est préférable de faire le ménage pour ne pas encombrer
inutilement le cache des données de jForms. Il faut donc détruire le formulaire.
Pour cela on utilise jForms::destroy()
, à laquelle on indique le sélecteur
du formulaire, et éventuellement l'identifiant du formulaire concerné.
jForms::destroy("main~contact");
jForms::destroy('shop~products');
jForms::destroy('shop~products', $product_id);