Drupal Alters and Overrides: hook_form_alter
Submitted by Brenda Boggs on
One of the first rules most people coming into the world of Drupal learn, hopefully, is to not hack core. I certainly didn't know about this when I first started out and hacked to pieces a lovely Drupal 4.6 site which, amusingly enough, still exists today. Since then, though, I've become more accustomed to the various ways of altering and overriding things in both Drupal core and contrib "the Drupal way".
Because Drupal is built modular with a strong hook API system, it gives us a lot of power in terms of changing things through our own custom modules. You can read more about creating a custom module at http://drupal.org/developing/modules -- there is also a useful module with some good examples you can download from http://drupal.org/project/examples
I'm going to go through a few different ways you can alter and override content in my next series of blog posts. This first one will cover one of the most popular.
hook_form_alter
One of the most common hooks used to override or alter things in Drupal is hook_form_alter. Drupal is driven by forms-- administration settings forms, content creation forms, contact forms, menu forms, user registration forms, etc., that I don't think I've ever worked on a Drupal site where this hook wasn't used.
Let's say, for example, you've got yourself a View with some exposed filters. By default the submit button says "Apply", but you've been asked to change that to "Submit".

My custom module is called demo. If I take a look at the link above from api.drupal.org, it tells me the parameters my function should have:
hook_form_alter(&$form, &$form_state, $form_id)
This is how it would appear in my module:
function demo_form_alter(&$form, &$form_state, $form_id) {
}
I need to find the $form_id in order to make sure I'm altering only that specific form and not the others. I usually do this just by printing out $form_id. For Views exposed filters, they all have the same $form_id which is 'views_exposed_form'. In order to make sure I'm only targetting this specific exposed form, I also use the $form['#id'] value. You can get these values by doing a print_r($form) or dpm($form) in your module. My alter now looks like this:
/**
* Implementation of hook_form_alter().
*/
function demo_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'views_exposed_form' && $form['#id'] == 'views-exposed-form-content-search-page-1') {
$form['submit']['#value'] = t('Search');
}
}

I can do all sorts of things with forms here. I can remove elements, rename them, add new ones. I can also add or override submit and validation functions. Here are a few examples:
/**
* Implementation of hook_form_alter().
*/
function demo_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'views_exposed_form' && $form['#id'] == 'views-exposed-form-content-search-page-1') {
// Rename the submit button
$form['submit']['#value'] = t('Search');
}
if ($form_id == 'search_block_form') {
// Add default "Search" text in the searchbox
$form['search_block_form']['#default_value'] = t('Search');
}
if ($form_id == 'page_node_form') {
// Remove the "Preview" option
unset($form['buttons']['preview']);
// Add my extra validation function
$form['#validate'][] = 'demo_extra_validate';
}
}

21 Comments
Hi, since you are so brave
Submitted by Twisterforever (not verified) on
Hi, since you are so brave and i'm so neewbie with php :)
Could you say me how i can remove with Hook_alter_form the email address from select value?
Thanks in advance
Twisterforever
I'm not sure what select
Submitted by Brenda Boggs on
I'm not sure what select value you mean. Which form is this?
If you use the Devel module you get a handy function called dpm() which allows you to print out the form elements in a nice way. dpm($form) in your hook_form_alter to figure out how to find the elements you need.
I really like it when
Submitted by Eric (not verified) on
I really like it when individuals come together and share
ideas. Great blog, continue the good work!
Also take a look at http:/
Submitted by Brenda Boggs on
Also take a look at http://www.lullabot.com/articles/quick-and-dirty-debugging - some good tips on debugging.
Is it possible to change the
Submitted by carla (not verified) on
You can do it individually
Submitted by Brenda Boggs on
You can do it individually like this:
$form['field_category_value']['#options']['All'] = 'By Category';thank you! works perfectly.
Submitted by carla (not verified) on
thank you! works perfectly.
I need to insert some <div>s
Submitted by John K (not verified) on
I need to insert some <div>s into my forms at specific places. These divs are basically titles, that help guide the user through the data input process. The form has been modified with CCK, so I'm not sure how the weights are being adjusted. So, my question is two parts: 1) How do I insert a title/information div and 2) How do I go about ordering it into the right place? Any guidance would be greatly appreciated...
I wanted to say THANK YOU!
Submitted by Alfonso (not verified) on
I wanted to say THANK YOU!
I've been searching a way to use hook_form_alter with 3 different exposed forms in the same page. your approach worked like a charm:
if ($form_id == 'views_exposed_form' && $form['#id'] == 'views-exposed-form-content-search-page-1')
Glad it helped!
Submitted by Brenda Boggs on
Glad it helped!
Thanks for the post this is
Submitted by Csatlos Sandor (not verified) on
Thanks for the post this is exactly what i need, my only question is that i created a view named "company" with exposed filters, but i dont have a module for it so how i will name the hook_form_alter function? company_form_alter?
Thanks
You need to name the function
Submitted by Brenda Boggs on
You need to name the function after your module. It doesn't matter what the View is called. If you name your custom module with a directory "mymodule" which contains "mymodule.info" and mymodule.module", the function name would be mymodule_form_alter(). https://drupal.org/node/206753 has more thorough information on creating modules.
Yeah, I agree you will need
Submitted by email archiving (not verified) on
Yeah, I agree you will need to name the function after your module to make the program up and running
Now i know that this is quite
Submitted by Male Waxing (not verified) on
Now i know that this is quite different to joomla
I am still learning the functions, thank you for this site
Thanks for the information. I
Submitted by Guest (not verified) on
Thanks for the information. I will study the site even better later.
My question: How to override the comment form ?! What is the $form_id of that ?! I want to override the labels and descriptions inside that form globally, all over the site.
Thanks.
could you suggest how i might
Submitted by brian (not verified) on
could you suggest how i might use hook_form_alter in drupal 7 to display the results from a search (in a Views block) --- on a new page (a search results page - in Views)? create a new page View and use POST data as an argument? i'm certainly a newbie! thanks!
Hi, Great article. Very
Submitted by Adrian (not verified) on
Hi, Great article. Very Useful. Can a custom sort option be applied? What I mean is I have a list of exposed values but they're all over the place. Can I rearrange the options alphabetically?
How would I alter the above
Submitted by Simon (not verified) on
How would I alter the above example so that the validation happens after the user has clicked the apply button. I've seen and tried a few examples but the error message (eg this input is required) always appears when the exposed view is loaded. Thanks in adavnce
Simon,
Submitted by Brenda Boggs on
Simon,
Exposed filters are tricky because of the way they always submits the form when first generating the results. Going the route, if it isn't incredibly sensitive, of using jQuery to validate is one possibility. You can also, technically, validate in the form_alter itself using the $_GET values. Since it's bypassing the Drupal API, though, you'll need to make sure to do your own sanity and security checking.
Hi, I want to either override
Submitted by RK (not verified) on
Hi, I want to either override or add some parameters to the destination url from an exposed filter. I have spent a couple days searching the web and cannot find a solution. The exposed filter builds the passed parameters somewhere but I cannot figure out how to manipulate it. The redirect field is ignored if there are parameters in this case the field name and values passed from the exposed filter. I don't see anything happen when using hook_drupal_goto_alter. I have to add some parameters to feed fullcalendar and can't figure a way to get the parameters added to the url when the exposed filter is submitted.
I have an support issue on the drupal view site but have not gotten any answers. You seem to be the only site I have found that actually answers questions. If you can help, I would be eternally appreciative.
could you plz tel me how to
Submitted by Joseph (not verified) on
could you plz tel me how to override a form submit action with another one....
Add new comment