Search code examples
drupal-8wizarddrupal-webformmulti-step

Drupal 8 Webform: how to display text input on one page on the next page?


I am trying to develop a multistep webform in Drupal 8 using Webform 8.x-5.1. I have written a WebformHandler that extends Drupal\webform\Plugin\WebformHandlerBase and made it available to the webform.

In the first step of the webform, I collect a text-field. I would like to display the value of that text-field in an HTML element (Advanced HTML/Text or Basic HTML) on the second page after doing some computation.

I have overwritten submitForm() in the WebformHandler and in it assign the value I want to the HTML element as follows:

$form['elements']['page_name']
     ['advanced_html_element']['#text'] = '...my HTML...';

Using ksm() I can see that this assignment works, but the the HTML element is not rendered with my HTML: the element is either invisible or contains the initial value set up in the form editor.

Clearly I'm missing something. Should I be using something other than submitForm? Can anyone help me?


Solution

  • It's been a long haul, but I've finally worked out how to do what I want to. The following works for me.

    Firstly, I discovered the method validateForm in WebformHandlerBase. On each page in a form with multiple pages, you will find that the following methods are called in the order given here:

    • submitForm (called once)
    • alterForm(called possibly more than once)
    • validateForm (called once)

    The name validateForm leads me to believe I may be misusing this method, but that is where I set up the elements on the following page that I wish to programmatically initialise. It works, so what the hey!

    In validateForm, I initialise the elements that appear on the following page as follows:

    $form_state->setValue(<element name>, <data structure>);
    

    The <element name> is the name you give the element in the form editor ("Build" tab). The <data structure> has to be correct, of course: I suggest you find the appropriate structure by first filling in the element on the next page manually and seeing what turns up in $form_state.

    There is also a $form_state->getValue(<element name>), which seems to me to mean that $form_state can also be used for storing session data, say in hidden fields. I initially used Drupal::service('tempstore.private')->get('xxx') for storing data that had to be available across page boundaries, but $form_state might be a cleaner solution.

    I hope this helps someone: I spent a horribly long time trying to get this to work.