Unfortunately, the stock Drupal contact module does not satisfy everyone's functional requirements. I decided to weigh alternative solutions, but since all I wanted to do was add an additional field to the form and email, I decided to add a few lines of module code instead. This solution consists of adding a form_alter hook to modify the contact form and submit handler, and an additional submit handler function:
<?php
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
// check for contact form
if ($form_id == 'contact_mail_page') {
// prefix another submit handler
array_unshift($form['#submit'], '_MYMODULE_mail_page_submit');
// NOTE: since I want to insert the form element at a certain point,
// I have to create a new $form object
$newForm = array();
// define insertion point
$ip = 'message';
// lop through $form object and duplicate the values
foreach ($form as $k => $v) {
// check for insertion point and add new form element
if ($k == $ip) {
// add phone number
$newForm['phone'] = array(
'#type' => 'textfield',
'#required' => true,
'#title' => 'Phone',
);
}
$newForm[$k] = $v;
}
// replace $form object with new form
$form = $newForm;
}
}
function _MYMODULE_mail_page_submit($form, &$form_state) {
// Since message is required by default,
// I can concatenate the new form field onto the message variable
if (!empty($form_state['values']['phone'])) {
$form_state['values']['message'] .= "\n\nPhone: " . $form_state['values']['phone'];
}
}
?>Now, if I browse to the contact form, there is a new field (phone number in this example) inserted right above the message textarea. When I submit the form, the email sent contains the phone number as well.










Are you getting an error? If
Are you getting an error? If you take a peak at contact.module, in the menu_hook(), you'll see that the $items['contact'] menu item has a "file" property of "contact.pages.inc".
Nice article thanks!
very helpful article.
You a one of the best drupaler's )
thx a lot, it works perfect
Nice this works!
check out:
http://api.drupal.org/api/drupal/developer--topics--forms_api.html
for other form types! I've used some checkfields & radio buttons, which work fine.
Language issues need to be seen for!
Ok next project ;-)
Some of us live in multilanguage area's guys...
Greetz,
Chris Devriese
www.100it.be
t()
Hi Chris,
Sorry for not using t(), sometimes we forget :)
Cheers,
E
How to make the new fields not required
Great code and thank you so much for this!
How would I go making the new fields NOT be required?
#required
you can remove the "#required" property of the form element, or set it to FALSE
Adding the now altered contact form to a 2 col panel
I want to add the now altered contact form to a panel (I'm using Panels version 3) on the right side and have location information on the left. I made a block and put the location information and added it to the panel no problem but I can't add the contact form. I tried using drupal_get_form('contact_mail_page') but this doesn't work. Any ideas?
I also would love to know if there's a way to add the contact form to a panel column and have a parameter passed to it. So arg(1) would be read from the url myproject/contact/catalog_request. I'm doing this since I have a contact form and a catalog request form that are almost exactly the same I thought I'd just reuse the form and hide two fields for catalog requests.
Thanks
Martin
includes
Hi Martin,
Are you getting an error? If you take a peak at contact.module, in the menu_hook(), you'll see that the $items['contact'] menu item has a "file" property of "contact.pages.inc". Did you include this file in your code before attempting the drupal_get_form('contact_mail_page')?
Regards,
Eric
Passing an extra parameter into _alter_form
I have two forms that are the same, one is a contact form, another is a catalog request form. I'd like them all to email out like the contact form does and just alter the contact form like you do above (change the cid of the form myself programmatically since they are on different pages so like to make that field hidden, later there will be field changes). With this tutorial that's not a problem for one form but I don't know how to choose which version of the form I want output (catalog or contact with there slight default value tweeks). This is probably due to my only just starting to work with Drupal so you'll have to bare with me if this is a dumb question.
I originally made the two modules to build and display my forms and then loaded the content into a page-panel using php drupal_get_form('my_catalog_request_form'). This works to display but now I have two modules that do the same thing. I'd rather have it set up like you do above and be able to pass a parameter in to say which form to render or something along those lines or a better way if you know of one. I'm trying hard to get up to speed on the hooks that drupal seem to be getting there but with some difficulty. I'm using drupal 6.
conditional statement
I would simply add a conditional statement in your form creation function, and modify the structure of the form as necessary. Without viewing your code and setup, I would suggest checking $_REQUEST['q'] (for the page url), or print_r() on all the function arguments to see if there is something better suited to work with.
hy, i put these functions in
hy,
i put these functions in my template.php file in my theme folder. But this don't work. can you help me plz ?
sure
Sure thing, you'll have to supply more details though. Also, two things first: 1) did you flush your cache; and 2) did you rename the functions?
-Eric
form_alter hook is awesome
Just started to learn about this yesterday. In which file would you paste these functions into?
Thanks again for sharing,
ttamniwdoog
module
form_alter hooks go in custom modules. You can create one pretty quickly:
- create a new folder in your sites/all/modules directory
- create a basic MODULE.info file
- create a MODULE.module file
- add the MODULE_form_alter function in MODULE.module
- enable the module
Hi!
I follow your instructions above: I created a folder "phone_number" and I put inside a file "phone_number.module with your code and a fle phone_number.info with the following:
; $Id$name = "Phone Number Module"
description = "This simple module add a phone box area in the contact form."
core = 6.x
package = Organic groups
dependencies[] = contact
I can see the new module at the module list, I can activate it, but there is not any difference on my contact form. Which is the fault? Would you help me? I have no experience on creating modules...
I just have a litle knowlege of PHP, JavaScript, SQL ,CSS and very well html.
Great Idea
This looks like the perfect solution to what I want to do, and it doesn't hack core which is nice. But I follow your instructions here but it doesn't work. I setup basic custom module, and am able to install it. It has the info file and module file, but when I go to the Contact page, it is still the same default setting as usual, no new phone field. ??
folder: contact_fields
contactfields.info:
; $Id$name = "Contact Fields"
description = "Adds additional fields to contact module."
core = 6.x
dependencies[] = contact
contactfields.module:
<?php
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
// check for contact form
if ($form_id == 'contact_mail_page') {
// prefix another submit handler
array_unshift($form['#submit'], '_MYMODULE_mail_page_submit');
// NOTE: since I want to insert the form element at a certain point,
// I have to create a new $form object
$newForm = array();
// define insertion point
$ip = 'message';
// lop through $form object and duplicate the values
foreach ($form as $k => $v) {
// check for insertion point and add new form element
if ($k == $ip) {
// add phone number
$newForm['phone'] = array(
'#type' => 'textfield',
'#required' => true,
'#title' => 'Phone',
);
}
$newForm[$k] = $v;
}
// replace $form object with new form
$form = $newForm;
}
}
function _MYMODULE_mail_page_submit($form, &$form_state) {
// Since message is required by default,
// I can concatenate the new form field onto the message variable
if (!empty($form_state['values']['phone'])) {
$form_state['values']['message'] .= "\n\nPhone: " . $form_state['values']['phone'];
}
}
?>
Thanks
Worked like a charm.
MYMODULE
Like many of my code snippets, you'll need to replace "MYMODULE" with your module name. Hope this helps.
Drupal 7
How would I be able to port this over to Drupal 7?
REplace
int this case by "contactfields", thank you for this code! Helped me a lot!