I am adding several buttons to a node form. The result is something that looks like this pastebin. The pastebin is a somewhat truncated version, here is the real short one:

$form = [
  '#submit' => [],
  '#actions' => [
   'submit' => [
     '#type' => 'submit',
     '#submit' => ['node_form_submit']
   'skip_done' => [
     '#type' => 'submit',
     '#submit' => ['skip_done_handler']

I thought that if $form['#submit'] was empty then the only submit handlers that would be called are the ones on the respective buttons. I'm either completely wrong in my understanding or I've misconfigured something.

Should this work they way I'm expecting it to? If so, what am I doing wrong?

1 Answer 1


If you leave $form['#submit'] unset or empty then drupal_prepare_form will try to replace it with a submit handler provided by the base form:

if (!isset($form['#submit'])) {

// Ensure that modules can rely on #submit being set.
$form['#submit'] = array(


// Check for a handler specific to $form_id.
if (function_exists($form_id . '_submit')) {
  $form['#submit'][] = $form_id . '_submit';
elseif (isset($form_state['build_info']['base_form_id']) && function_exists($form_state['build_info']['base_form_id'] . '_submit')) {
  $form['#submit'][] = $form_state['build_info']['base_form_id'] . '_submit';

If you're submitting a node form then $form_state['build_info']['base_form_id'] . '_submit' will be equal to node_form_submit, which is why it's being called.

In order to prevent node_form_submit from being called, you'll need to provide a $form['#submit'] handler, or define FORMID_form_submit, which takes the form NODETYPE_node_form_submit for nodes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.