On this page
How to programmatically skip pages in wizard forms
User story
As a form builder, I want to dynamically control what pages a user is sent based off their response so they only have to answer what is required.
Note, this is different than #states because states only apply to fields on a page and with formbuilder wizard forms, not all the questions are on one page.
Code
First off, we need to add hook_form_alter or websubmission form_alter to customize the behavior of our form. Once that is set up, we can drop this code in:
/**
* Goto step/page in form.
*
* @param string $goto_step
* @param array $pages
* @param object $form_state
*
*/
function goto_step($goto_step, $pages, \Drupal\Core\Form\FormStateInterface $form_state){
// Convert associative array to index for easier manipulation.
$all_keys = array_keys($pages);
$goto_destination_page_index = array_search($goto_step, $all_keys);
if($goto_destination_page_index > 0){
// The backend pointer for page will add 1 so to go our page we must -1.
$form_state->set('current_page', $all_keys[$goto_destination_page_index-1]);
}
else{
// Something went wrong.
}
}
With this function, we can send our user to any page by passing the machine name of that page. The function will parse the array and get the page before our destination page. The reason we need the page before and not the actual page is because in the backend the page indicator is being incremented for us. This means, if you update current_page to the destination page, you will always go to the page after your destination page.
All that is left is to call the function based off of some conditional logic for the field you are populating your page based off of.
// If some response is 2, redirect to required questions.
if ($form_state->get('partner_test') == 2) {
$pages = $form_state->get('pages');
// Check yaml source for this value.
$page_name = 'required_pg';
goto_step($page_name, $pages, $form_state);
}
You can put the code above in your custom module. For example, if your webform is called qnmr and your module is in a folder qnmr, create a file qnmr.module file and put this in:
/**
* Implements hook_webform_submission_form_alter().
*/
function qnmr_webform_submission_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
if ($form_id !== 'webform_submission_qnmr_form') {
return;
}
// The following line is only needed if you allow drafts (manual or auto-save).
_qnmr_submit_page($form, $form_state);
$form['actions']['wizard_next']['#submit'][] = '_qnmr_submit_page';
}
function _qnmr_submit_page(array &$form, FormStateInterface $form_state) {
// Conditional logic goes here.
}
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion