I've been updating one of my Drupal 7 modules to 8 and I'm having an issue with my form alter. I'm adding a validation function and a submit handler. The validation function is getting called just fine, but the submit function is not getting fired. I'm wondering if this means there is a Symfony-style approach that needs to be taken to adding submit handlers to existing forms. I've done a lot of searching and I can't find any examples. Also looked through some work-in-progress D8 modules but I haven't really found any working examples there either.

Does anyone have any idea what the correct Drupal 8 way to do this is?

  • 2
    You should post your existing code so people can take a look at it and spot any issues/suggest alternatives. Commented Dec 7, 2013 at 0:39
  • There are, as of D8 beta9, getters and setters for submit handlers, but I couldn't seem to get them to work and used the answer below. I would hope the node interface gets some events dispatched in the future, as I would rather subscribe to an event than use a hook. Commented Apr 14, 2015 at 21:12

5 Answers 5


According to the example in the documentation it's the same as for Drupal 7:

$form['actions']['submit']['#submit'][] = 'mymodule_upload_enabled_types_submit';

You can find similar (working) logic in

And a few others besides.

  • 1
    I can't argue with the API docs. Probably something screwy with my implementation, I'll dig deeper.
    – Arbee
    Commented Dec 7, 2013 at 2:22
  • See my update above, aside from $form['actions']['submit'] there are also $form['actions']['publish'] and ['unpublish'] sections that can have submit handlers attached.
    – Arbee
    Commented Dec 8, 2013 at 1:17
  • I had to use $form['actions']['publish']['#submit'][] instead of $form['actions']['submit']['#submit'][] for my submit handler to work when the node was published. However, I can't seem to get the callback to work when the node is first saved as unpublished. Commented Apr 14, 2015 at 21:10

You can add how many submit handler you want using the following code:

 $form['actions']['submit']['#submit'][] = 'mymodule_what_ever_function';

If you want to add a submit handler after the default submit handler, (a submit handler that will be called after the submit callback), you can use the following.

$form['#submit'][1] = test_function;

To remove the submit handler:


The behavior is either changed or differs from case to case. With the Node Delete Multiple confirmation form

$form['actions']['submit']['#submit'][] = 'mymodule_upload_enabled_types_submit';

@Clive's code causes Drupal to ignore the main handler. In this case add the handler to the $form['#submit'] section:

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

Here's how to attach a custom submit handler to the article node add/edit form in Drupal 8:


use Drupal\Core\Form\FormStateInterface;

 * Implements hook_form_alter().
function my_module_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Use this to reveal the form id.

  // Use this with the devel module to inspect the button action(s).

  switch ($form_id) {

    case 'node_article_form':      // New article nodes.
    case 'node_article_edit_form': // Existing article nodes.

      // Attach our custom submit handler.
      $form['actions']['publish']['#submit'][] = 'my_module_node_article_form_submit';



function my_module_node_article_form_submit($form, FormStateInterface $form_state) {
  drupal_set_message('Running custom submit handler...');

I was not able to successfully append a custom submit handler to $form['#submit'] and have the function fire properly. I had to explicitly attach it to the Save and publish button when creating a new article, and attach it to the Save and keep published button when editing an existing article.

Besides publish, here are some of the other button actions available:

  • I'm in Drupal 8.7.3, and my_module_node_article_form_submit($form, FormStateInterface $form_state gave me TypeError: Argument 2 passed to _ccad_content_log_webform_submit() must be an instance of FormStateInterface, instance of Drupal\Core\Form\FormState given; changing it to _submit($form, $form_state) fixed the errors.
    – user1359
    Commented Aug 5, 2019 at 20:22

To replace/override the existing handler in Drupal 9 this worked for me:

 * Implements hook_form_FORM_ID_alter()
function MODULE_NAME_form_FORM_ID_alter(&$form, $form_state, $form_id) {

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

function custom_submit($form, $form_state) {
  \Drupal::messenger()->addStatus(t('Submit overriden by custom_submit!'));

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.