Nos clients ont toujours des demandes bien précises et il est normal que nous y répondions, à la fin c’est bien eux qui nous font vivre non ? La semaine dernière un client désirait que dans le formulaire de contact du site, apparaisse un champ additionnel: le nom de l’entreprise du visiteur.
J’avais dès lors deux solutions : utiliser le module webform ou faire un petit module pour ajouter le champ nécessaire.
Webform
Si la première solution parait la plus simple, n’oublions pas que le module webform (2 500 lignes de code au minimum) enregistre toutes les données qu’envoie chaque utilisateur au travers de ce formulaire dans des nodes de la base de données. Pour cela, Webform crée 5 tables dans notre DB :
Webform - webform_component - webform_roles - webform_submissions - webform_submitted_data
2500 lignes de code et cinq tables pour ajouter un seul champ? Le jeu en vaut-il la chandelle ? Même dans le cas ou nous voudrions enregistrer automatiquement les données des visiteurs qui utilisent le formulaire, cela me parait excessif et plus encore pour un site qui reçoit beaucoup de visiteurs.
Faire un module
Il nous reste cependant une deuxième solution assez simple, légère et rapide : faire un petit module (30 lignes de code) qui ajoute ce champ et le montre dans le body du mail que nous allons recevoir. Nous appellerons ce module : addcontact pour notre exemple.
Dans un premier temps, nous créons dans le répertoire sites/all/modules un répertoire : addcontact
Dans le repertoire sites/all/modules/addcontact/ nous créons deux fichiers : addcontact.info et addcontact.module
Voici le code du fichier addcontact.info
; $Id$
name = Addcontact
description = Ajouter un champs ‘Entreprise’ dans le formulaire de contact du site
core = 6.x
package = PERSONNELVoici le code du fichier addcontact.module
<?php
// $Id$
/**
* @file
* Module perso
* Ajouter un champ dans le formulaire de contact du site
*
*/
Implémentation de hook_FORM_ID_alter()
Pour ajouter un champ dans le formulaire de contact, nous allons utiliser le hook hook_FORM_ID_alter() qui nous permet de modifier un formulaire en particulier grâce a son ID.
L’ID du formulaire de contact du site est le suivant : contact-mail-page. Nous pouvons le voir dans le code source comme suit :
<form id="contact-mail-page" method="post" accept-charset="UTF-8" action="_PATH_">Attention : Nous devrons transformer l’ID pour pouvoir l’utiliser dans notre module en remplaçant les – pour des _ (underscore)
Donc au lieu d’utiliser l’ID contact-mail-page nous allons utiliser l’ID contact_mail_page
Nous allons alors implémenter le hook hook_FORM_ID_alter() comme addcontact_ form_contact_mail_page_alter(). Nous remplaçons hook par le nom du module, addcontact, nous remplaçons aussi FORM_ID par l'Id de notre formulaire: contact_mail_page.
Dans notre fichier addcontact.module nous ajoutons cette fonction
<?php
/**
* Implementation of hook_FORM_ID_alter().
*/
function addcontact_form_contact_mail_page_alter(&$form, &$form_state){
//ajouter le champ entreprise
$form['entreprise']=array(
'#type' => 'textfield',
'#title' => t('Entreprise'),
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
);
// classer les champs en ajoutant #weight
$order = array('contact_information', 'name', 'mail', 'entreprise', 'subject', 'cid', 'message', 'copy', 'submit');
foreach ($order as $key=>$value){
$form[$value]['#weight']=$key;
}
}
?>A présent si nous allons dans notre formulaire de contact nous voyons que nous avons un nouveau champ : Entreprise.
Mais si nous envoyons le formulaire, dans le mail reçu, nous ne voyons pas le champ entreprise.
Nous pour cela, implémenter le hook hook_mail_alter()
Implémentation de hook_mail_alter()
<?php
/**
* Implementation of hook_mail_alter().
*/
function addcontact_mail_alter(&$message) {
// Attention, nous devons changer seulement le formulaire contact_mail_page
// Car ce hook est utilisé pour chaque mail que le système envoie.
if ($message['id'] == 'contact_page_mail') {
$message['body'][1]=t("Message: ").$message['body'][1];
$message['body'][2]=t("Entreprise: ").$message['params']['entreprise'];
}
}
?>Voila, maintenant nous recevons le champ entreprise dans le corps du mail.
Comme nous l’avons vu, il nous a suffit de 30 lignes pour ajouter ce champ dans notre formulaire au lieu des 2500 lignes (et plus) du module webform sans compter les cinq tables additionnelles dans notre base de données.
En résumé
1. Créer le répertoire addcontact dans sites/all/modules/
2. Dans le répertoire sites/all/modules /addcontact/ créer le fichier addcontact.info
; $Id$
name = Addcontact
description = Ajouter un champs ‘Entreprise’ dans le formulaire de contact du site
core = 6.x
package = PERSONNEL3. Dans le répertoire sites/all/modules /addcontact/ créer le fichier addcontact.module avec les hook hook_form_FORM_ID_alter() et hook_mail_alter()
<?php
// $Id$
/**
* @file
* Module perso
* Ajouter un champ dans le formulaire de contact du site
*
*/
/**
* Implementation of hook_FORM_ID_alter().
*/
function addcontact_form_contact_mail_page_alter(&$form, &$form_state){
//ajouter le champ entreprise
$form['entreprise']=array(
'#type' => 'textfield',
'#title' => t('Entreprise'),
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
);
// classer les champs en ajoutant #weight
$order = array('contact_information', 'name', 'mail', 'entreprise', 'subject', 'cid', 'message', 'copy', 'submit');
foreach ($order as $key=>$value){
$form[$value]['#weight']=$key;
}
}
/**
* Implementation of hook_mail_alter().
*/
function addcontact_mail_alter(&$message) {
// Attention, nous devons changer seulement le formulaire contact_mail_page
// Car ce hook est utilisé pour chaque mail que le système envoie.
if ($message['id'] == 'contact_page_mail') {
$message['body'][1]=t("Message: ").$message['body'][1];
$message['body'][2]=t("Entreprise: ").$message['params']['entreprise'];
}
}
?>Des questions ? N’hésitez pas a poster un commentaire…
Pour en savoir plus :
Hook Form Alter: http://api.drupal.org/api/function/hook_form_alter
Hook Form ID Alter: http://api.drupal.org/api/function/hook_form_FORM_ID_alter/6
Hook Mail Alter: http://api.drupal.org/api/function/hook_mail_alter/6
Références sur la FormApi: http://api.drupal.org/api/drupal/developer--topics--forms_api_reference....
Un bon post de Lullabot sur les formulaires: http://www.lullabot.com/articles/modifying-forms-drupal-5-and-6
Module contact: http://drupal.org/handbook/modules/contact/
Form API Quickstart Guide: http://drupal.org/node/751826
Module Webform: http://drupal.org/project/webform



Commentaires
Et l'esthétique du code alors ?
Bonjour Karim,
Joli billet en effet, très clair, facilement exploitable par les autres. Je vois que beaucoup de lecteurs apprécient.
Je me permets de rajouter un commentaire sur le bout de code pour donner ordonner les champs du formulaire. L'astuce est d'une simplicité déconcertante, bravo ! C'est ça que j'appelle l'esthétique du code. On n'en parle jamais assez.
Cordialement
Merci
Merci @Jabberwooki !
avez vous une solution pareil
avez vous une solution pareil pour drupal 7 s'il vous plait?
Merci mais...
visiblement votre solution ne fonctionne pas sous Drupal 7... une idée peut-être ?
Encore merci
Ccile
Merci + précision
Merci, ça m'a fait gagner beaucoup de temps de recherche et de dump de tomber sur ton post.
Si vous ne voulez modifier qu'un seul formulaire bien spécifique (exemple le formulaire de contact "conseillers" et pas tous les autres du site), il faut se baser sur le "cid" (contact id).
exemple avec le formulaire ayant le cid = 1 :
<?php/**
* Ajout de champs spécifique au formulaire de contact lié au devis
* @author Webu (Dylann Cordel <[email protected]>)
* @param $form array Formulaire déjà défini
* @param $form_state array Formulaire avec les valeurs de l'utilisateur
*/
function intpreadhesion_form_contact_mail_page_alter(&$form, &$form_state){
if($form['cid']['#value'] != 1){
//on ne modifie que le formulaire de contact destiné aux conseillers
return ;
}
//votre traitement spécifique
} /**
* Prise en compte de champs spécifique au formulaire de contact lié au devis
* @author Webu (Dylann Cordel <[email protected]>)
* @param $message array Les données saisies par l'utilisateur
*/
function intpreadhesion_mail_alter(&$message){
if($message['params']['cid'] != 1){
//on ne modifie que le formulaire de contact destiné aux conseillers
return ;
}
//votre traitement spécifique
}
?>
Vous pouvez voir le "cid" dans les liens "éditer" de chaque formulaire de contact par exemple.
remerciement
Merci,enfin un exemple de hook bien détaillé, merci encore une fois
Merci, ça fait toujours
Merci, ça fait toujours plaisir. :)
Super !
Merci beaucoup, c'est très intéréssant !
Peut-être pourrais-tu préciser comment se fait la traduction du formulaire en aval ?
Traduction
Bonjour Ugo,
La traduction des champs se fait par la fonction t().
Je te recommande aussi la lecture de ce post: Translation for Drupal contact forms
Bonne lecture et à bientôt.
Amicalement,
vraiment génial votre post
vraiment génial votre post sur l'ajout d'un champ dans un formulaire.
pour la première fois, je comprend le principe d'un hook !
pour un formulaire dont le ID="toto" comment pourais-je ne pas l'afficher svp ? je ne parle pas d'un champ mais bien de l'ensemble d'un formulaire:
champs+bouton sumit.
En vous remerciant par avance.
Merci, ça fait toujours
Merci, ça fait toujours plaisir. :)
Ça fait un bout de temps que
Ça fait un bout de temps que je cherche cette solution. Merci de l’avoir mise en ligne. creation de sites e-commerce
Merci Alex
Merci, ça fait toujours plaisir. :)
ajouter un champ select
Bonjour
J'ai bien aimé votre solution qui marche à la perfection.
J'ai essayé d'ajouter un champ de sélection mais je n'arrive pas à récupérer les données dans le mail sous forme lisible (les tranches d'âge et non les numéros du tableau).
<?php$form['tranche_age'] = array(
'#type' => 'select',
'#title' => t('Tranche d’âge'),
'#options' => array(
1 => t('16-20'),
2 => t('21-30'),
3 => t('31-40'),
4 => t('41-50'),
5 => t('51 et plus')
),
);
?>
Merci de votre aide !
Bonjour Karim, Je vous prie
Bonjour Karim,
Je vous prie de bien vouloir m'excuser pour mon absence de réponse. En fait, cela fonctionne génialement bien!
J'aurais cependant une question: peut-on rajouter par cette méthode des boutons radio?
Merci encore pour l'aide apportée!
Rémy
Boutons Radio
Bonjour Rémy,
Oui, nous pouvons rajouter des boutons radio comme suit:
<?php$form['sujet'] = array(
'#type' => 'radios',
'#title' => t('Topics'),
'#options' => array('Movie'=>t('Movie'),'Songs'=>t('Songs'),'Ads'=>t('Ads'),'Tv Serials'=>t('Tv Serials'),'Others'=>t('Others')),
);
?>
Pour plus d'infos:
Form API Quickstart Guide
Form API Reference
Form generation
Voilà Rémy, j'espère avoir répondu à vos attentes.
Bien à vous.
Merci Karim
Merci beaucoup pour toutes ces informations!
J'ai une question, qui ne concerne en aucun cas un formulaire de contact:
Pour insérer mes images dans mon site, je me sert de la balise [inline]. Le seul souci, c'est que quand je fais afficher le contenu de la node dans une view, il me met tel quel le "[inline]", donc pas d'images!
Auriez-vous une solution à ce problème?
Encore merci pour vos réponses pertinentes.
Rémy
Images dans les nodes
Bonjour Rémy,
Une première solution serait d'utiliser Ckeditor qui vous permettra de mettre des images dans vos nodes.
Je vous recommanderais pourtant de mettre vos images dans des champs spécifiques avec CKK et Imagecache, ce qui vous donnera une plus grande liberté, surtout avec Views. Voyez ce guide sur Drupal.org.
A bientôt.
Cher Karim, votre formulaire
Cher Karim,
votre formulaire ainsi que votre ajout de champs ont l'air ma foi bien sympathique, sauf que les champs supplémentaires ne s'ajoutent pas chez moi.
C'est un petit problème quand même! ^^'
Amicalement
Rémy
Rémy
Bonjour Rémy,
Pour que je puisse vous aider, postez votre fonction:
function addcontact_form_contact_mail_page_alter(&$form, &$form_state) dans un commentaire.
J'essayerai de voir ce qui ne tourne pas rond.
A bientôt.
Karim,
Cool le tutoriel Karim. Je
Cool le tutoriel Karim.
Je cherchais qlq chose comme ca depuis une petite semaine.
:)
Heureux que cela puisse te
Heureux que cela puisse te servir.
Merci @FerDrp.
Hum... Pas mal. Je ne
Hum... Pas mal. Je ne connaissais pas ce truc la.
Moi je le fais en general avec Web form, ta solution semble plus légère. Je vais faire un test.
Merci Karim.
Test
@Julien,
Donne moi des nouvelles quand tu auras fini le test. D'accord?
Amicalement
Poster un nouveau commentaire