0

I am using the Content Moderation control block, which adds a form at the top of a Draft node page to allow easily setting a new workflow state. This form has a single button built as:

$form['submit'] with a form submit handler as $form['#submit'] = [':submitForm']. 

I am trying to add a 2nd button which runs the form submit handler but also runs its own submit handler.

Adding this to a hook_form_alter seems as though it should work:

 $form['apply_and_send'] = [ '#type' => 'submit', '#name' => 'apply-and-send', '#value' => t('Apply and send newsletter'), '#weight' => 4, '#submit' => '_send_newsletter_email', ]; 

I have tried many variations of this such as wrapping both buttons in an "actions" wrapper, setting this button's handler to both the form handler and my new handler and then removing the form handler and a couple others variations. The only option which causes my custom handler to get hit is to simply add it to the form handler like this:

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

but even then, everything in $form_state suggests it was still the original button that has been clicked (op, triggeringElement, etc.). The only way I can tell that my new button has been clicked is to look in $_POST.

Is there a way to properly add a 2nd button with its own handler?

--- EDIT --------------- From comments below, here is current version of full form_alter:

function ssc_newsletters_form_content_moderation_entity_moderation_form_alter(&$form, &$form_state): void { $form_handler = $form['#submit']; // Add form level handler to existing Apply button. $form['submit']['#submit'] = $form_handler; // Add 2nd button to "apply and send". $form['apply_and_send'] = [ '#type' => 'submit', '#name' => 'apply-and-send', '#value' => t('Apply and send newsletter'), '#weight' => 4, '#submit' => $form_handler, ]; // And add new submit handler to send email. $form['apply_and_send']['#submit'][] = '_send_newsletter_email'; unset($form['#submit']); } 

I have tried with/without #name and as well as unsetting or not the original $form['#submit']. Same result in all cases, :submitForm is run, but my added handler is never hit.

3
  • $form['#submit'] = [':submitForm'] is automatically added to all forms by Drupal core. If you add submit handlers on submit button level the top level is ignored. So your approach to mix both doesn't work. You must also add ::submitForm to the button level. Only trying to clear the things you have in your question. As for why a 2nd button doesn't trigger, there is nothing in the question to work on. There are many forms with multiple submit buttons. Commented Mar 20 at 13:41
  • Remove this line, as it will only cause you problems '#name' => 'apply-and-send', Commented Mar 20 at 14:01
  • I originally tried without #name set and also didnt work. Then i found a post here from a couple years ago (by me) asking a similar question to this one and answer (which worked for that) was to add #name. Regardless, no difference there or not there. I have tried all the options of adding :submitForm to new button and removing from $form level, doesn't help. I'll post one of the variations that has what i think 4uk4 is requesting. Commented Mar 20 at 14:43

1 Answer 1

0

Minimal code example to add a 2nd button to the Content Moderation control form:

function mymodule_form_content_moderation_entity_moderation_form_alter(&$form, &$form_state): void { $form['second_button'] = [ '#type' => 'submit', '#value' => t('Second Button'), '#submit' => ['::submitForm', '_mymodule_submit_second_button'], ]; } function _mymodule_submit_second_button(&$form, &$form_state) { \Drupal::messenger()->addStatus('Submit handler for second button'); } 

This will produce a message from each submit handler assigned to the button:

The moderation state has been updated.

Submit handler for second button

This code to get the button's name in the submit handler is only for demonstration:

function _mymodule_submit_second_button(&$form, &$form_state) { $element = $form_state->getTriggeringElement(); $name = $element['#name']; // without #name you can still get the button name if ($name === 'op' && !empty($element['#array_parents'])) { $name = end($element['#array_parents']); } \Drupal::messenger()->addStatus("Submit handler for $name"); } 

I've added it because the OP asked about #name and the triggering element. You don't need it if the submit handler is assigned only to one button.

1
  • Perhaps this works (I haven't tried it, i suspect it does not work) because the custom handler runs before the ::submitForm? I need my custom handler to run after the form is submit. Also, seems unlikely the handler would know #name, when you haven't set it. I'll test it (with the order of functions as you have them). Commented Mar 21 at 13:36

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.