I'm trying to dynamically add multiple toggle fields to a form (in my case webform) via a form-alter-hook.

function module_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  foreach ($roles as $role) {
    $form['elements'][$role->id()] = array(
      '#type' => 'webform_toggle',
      '#title' => t($role->label()),
      '#default_value' => 0,
      // More webform specific arguments follow here.
      '#webform_id' => "edit_membership_roles--" . $role->id(),
      '#webform_key' => $role->id(),
      '#webform_parent_key' => "",
      '#webform_parent_flexbox' => FALSE,
      '#webform_depth' => 0,
      '#webform_children' => [],
      '#webform_parents' => [$role->id()],
      '#webform_multiple' => FALSE,
      '#webform_composite' => FALSE,
      '#admin_title' => $role->id(),
      '#webform' => "edit_membership_roles",
      '#webform_submission' => NULL,
      '#access' => TRUE,
      '#webform_element' => TRUE,
      '#element_validate' => [],

This works in a way that the form is displayed correctly, with all dynamically added toggle elements. However, when trying to load the WebformSubmissionInterface $webform_submission via $webform_submission->getData(); in my custom class FormHandler extends WebformHandlerBase {...}, the array only contains the elements that I manually added to the webform via the GUI.

I checked the first answer of this question, but my $form does not have a $form['submitted']

Am I just missing something or does this approach not work at all?


I did the same approach with a custom form built with Drupal FormApi and it works. So I must be missing something specific to webforms.


Adding elements dynamically via hook form alter does not work because the Webform module can't recognize the new elements. Your best bet is to create a custom webform element.


In first instance I would also go with the suggested approach by @jrockowitz.

However I had a use case where the element was already in use and it couldn't be swapped out with a new element. What we ended up doing was to substitute the element's class with an extended class in a .module file:

use Drupal\foo\Plugin\WebformElement\CustomWebformToggle;

 * Implements hook_webform_element_info_alter().
function CUSTOM_MODULE_webform_element_info_alter(array &$definitions) {
  // Substitute the original element class with additional functionality.
  $definitions['webform_toggle']['class'] = CustomWebformToggle::class;

In the extended class I also had to implement defineDefaultProperties() for the additional changes in form() to take effect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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