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.

4

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'],
];
  • Yep that worked. Would be kind of nice to know why the other way didn't work though. – Matt Oct 4 '17 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']], – 4k4 Oct 4 '17 at 17:55
  • The recipe can be updated and the first example should be removed. – jrockowitz Oct 4 '17 at 21:00

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.