2

I have a block that is rendering a webform programmatically however I want to change a field based on the node that it's appearing on. I'm performing this like so.

    $webform_id = 'contact';
    $current_node = \Drupal::routeMatch()->getParameter('node');
    $contact_form = \Drupal\webform\Entity\Webform::load($webform_id);
    $values = ['data' => ['contact_email' => $current_node->field_email->value, 'message' => 'test']];
    $contact_form->getSubmissionForm($values);
    $contact_form_render = \Drupal::entityManager()
        ->getViewBuilder('webform')
        ->view($contact_form);
    return $contact_form_render;

It is able to render the webform just fine, however the supplied values for the contact_email field and the message field do not appear, even though they were supplied as a parameter for getSubmissionForm. I've used https://www.drupal.org/docs/8/modules/webform/webform-cookbook/how-to-embed-a-webform as an example but I don't seem to see any discrepancies between my code and theirs.

Is there something wrong with how I'm supplying the values to the programmatically rendered webform?

UPDATE: I tried doing things in a more manual manner

$form_storage = \Drupal::entityTypeManager()->getStorage('webform');
$webform_submission = $form_storage
      ->create(['webform_id'=>'contact', 'data' => ['contact_email' => $current_node->field_email->value],'message' => 'testing']);

$contact_form_render = \Drupal::entityManager()
      ->getViewBuilder('webform')
      ->view($webform_submission);

However I get the error

Exception: Webform id (webform_id) is required to create a webform submission. in Drupal\webform\Entity\WebformSubmission::preCreate() (line 586 of modules/contrib/webform/src/Entity/WebformSubmission.php).

Even though I'm explicitly setting the webform_id.

1 Answer 1

6

Did you try using the Webform render element documented at the bottom of https://www.drupal.org/docs/8/modules/webform/webform-cookbook/how-to-embed-a-webform.

return [
  '#type' => 'webform',
  '#webform' => 'your_form_id',
  '#default_data' => ['name' => 'Custom Name'],
];
4
  • Yep that worked. Would be kind of nice to know why the other way didn't work though.
    – Amy
    Oct 4, 2017 at 17:11
  • 3
    @Matt, jrockowitz is right, building a render array is always the best option in D8. While doing this don't forget to add a cache tag for the node and a cache context, otherwise the block won't update when viewing different nodes: '#cache' => ['contexts' => ['url.path']],
    – 4uk4
    Oct 4, 2017 at 17:55
  • The recipe can be updated and the first example should be removed.
    – jrockowitz
    Oct 4, 2017 at 21:00
  • I like to render two forms at the same page. Any idee how to return the render array?
    – Justme
    Jan 11 at 4:09

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.