Drupal Alters and Overrides: hook_form_alter

Tags: 

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';
  }
}

22 Comments

I need to insert some <div>s

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...

Thanks for the post this is

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

Thanks for the information. I

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

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!

How would I alter the above

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,

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

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.

Add new comment