How to add one or more custom submit handlers to a Drupal form

Joeri Poesen //

The information in this post relates to Drupal 5.x.

In Drupal 5 it's possible, and easy, to play with a form's submit handlers: you can replace an existing handler with your own and you can even add multple handlers if you want.

In human terms, this means that you can change the function that is called when a certain form is submitted and has passed the validation handler (the function responsible for validating the form input).

Why would you want to do this?
You might want to do some stuff before a node is inserted, like insert the same data into an external database. Maybe you want to change the submitted information before it's handled by Drupal. Maybe you want to send a mail to a certain user when a certain type of node is updated with certain information.

Or maybe you want to interrupt the normal flow and just do something totally different than normally intended.

Whatever you want to do, you can do it all by using your own submit handlers. Here's how:

Each form has a #submit property. The value of that property is the name of the function that is to be called on submit. If this property is not present, Drupal will look for a function called form_id_submit. If that one isn't found either, Drupal will look for a function called #base_submit.

Tip: chapter 10 of Pro Drupal Development does a great job of describing the Form API in detail.

If you want to override this value, simply replace the #submit value with a function name of your choice. You need to do this by implementing a form_alter hook. This means creating a function that will be called when a your form is called, making sure to respect the naming convention and the function"s signature (number and order of parameters)

Example:

function mymodule_form_alter($form_id, &$form){
  switch($form_id){
    case 'some_form_id':
      // code in here will be called when form 'some_form_id' is built.
      // this is your chance to modify it before its html is rendered.
     break;
  }
}

The code to modify the submit handler:

$form['#submit'] = 'mymodule_my_own_submit_handler';

Now, what's cool is that you can queue up multiple submit handlers, meaning that you can have multiple functions called one after the other, upon a form submit. To do this, simply put them in an array and assign it to the #submit property:

$form['#submit'] = array(
  'mymodule_my_own_submit_handler',
  'mymodule_my_second_submit_handler',
  'mymodule_my_third_submit_handler');

If you simply want to add a submit handler, but want to make sure it is executed before the default handler, you need to do something like this:

  // add an additional submit handler to the #submit array. 
  // use array_merge to make sure the new handler is the first one in the array 
  $form['#submit'] = array_merge(array("mymodule_my_handler" => array()), $form['#submit']);    

Putting it all together:

function mymodule_form_alter($form_id, &$form){
  switch($form_id){
    case 'some_form_id':
      $form['#submit'] = 'mymodule_my_own_submit_handler';
     break;
  }
}

Have fun.