You are here

webform_steps.module in Webform steps 7.2

Same filename and directory in other branches
  1. 7.3 webform_steps.module
  2. 7 webform_steps.module

File

webform_steps.module
View source
<?php

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Add webform_steps to the top of the webform.
 * Add submit and validate handlers to handle the step-switching.
 */
function webform_steps_form_webform_client_form_alter(&$form, &$form_state, $form_id) {

  // Let the webform3-shim add the progressbar.
  if (function_exists('webform_steps_w3_progressbar')) {
    webform_steps_w3_progressbar($form, $form_state);
  }
  if (empty($form['progressbar'])) {
    return;
  }

  // Keep track of the last visited page.
  if (!isset($form_state['webform']['page_visited'])) {
    $form_state['webform']['page_visited'] = 1;
  }
  $form_state['webform']['page_visited'] = max($form_state['webform']['page_num'], $form_state['webform']['page_visited']);

  // Submit buttons for step navigation.
  $form['step_buttons'] = array(
    '#type' => 'container',
    '#attributes' => array(
      'class' => array(
        'webform-steps-buttons element-invisible',
      ),
    ),
  );

  // When the form is submitted by pressing enter, the browser submits
  // the first button (position in HTML). We don't want enter to jump to
  // the first step, so we insert an invisible "next"-button.
  $button = isset($form['actions']['submit']) ? $form['actions']['submit'] : $form['actions']['next'];
  unset($button['#id']);
  $form['step_buttons']['next'] = array(
    '#attributes' => array(
      'class' => array(
        'element-invisible',
      ),
    ),
    '#weight' => -100,
  ) + $button;
  array_unshift($form['#submit'], 'webform_steps_navigation_callback');
  $ajax = module_exists('webform_ajax') && $form['#node']->webform['webform_ajax'];
  $current_page = $form_state['webform']['page_num'];
  foreach ($form['progressbar']['#page_labels'] as $n => $label) {
    $page = $n + 1;
    $button = array(
      '#type' => 'submit',
      '#attributes' => array(
        'class' => array(
          'step-button',
        ),
      ),
      '#name' => 'step-btn',
      '#value' => $label,
      '#page' => $page,
      '#disabled' => $current_page == $page || $page > $current_page + 1,
    );
    if ($page < $current_page) {
      $button['#validate'] = array();
      $button['#attributes']['formnovalidate'] = 'formnovalidate';

      // Old versions of jQuery.validate (as bundled in clientside_validations
      // 1.x) run validations unless the button triggering a submit has the
      // 'cancel' class.
      // See: https://www.drupal.org/project/clientside_validation/issues/2113725
      $button['#attributes']['class'][] = 'cancel';
    }
    if ($ajax) {

      // @see webform_ajax_form_webform_client_form_alter().
      $button['#ajax'] = array(
        'callback' => 'webform_ajax_callback',
        'wrapper' => $form['webform_ajax_wrapper_id']['#value'],
        'progress' => array(
          'message' => '',
          'type' => 'throbber',
        ),
        'event' => 'click',
      );

      // Workaround for Drupal core bug http://drupal.org/node/1548976.
      // As long as buttons HTML id are causing problems, and it has bad
      // consequences on pages where Webform AJAX is active, we'll force
      // custom ids on AJAXed Webform's buttons.
      $button['#id'] = drupal_html_id('edit-webform-step-button-' . $page . '-' . $form['#node']->nid);
    }
    $form['step_buttons'][] = $button;
  }
}

/**
 * Submit callback for the step button
 *
 * We simulate next and previous button clicks for
 * @see webform_client_form_pages().
 */
function webform_steps_navigation_callback(&$form, &$form_state) {
  $button =& $form_state['clicked_button'];
  if (!isset($button['#page'])) {
    return;
  }
  $new_page = (int) $button['#page'];
  $old_page =& $form_state['webform']['page_num'];

  // prohibit jumps of more than one step forward at once, after the user
  // jumped back, otherwise one could skip the validations of a step.
  $new_page = min($new_page, $old_page + 1);
  if ($new_page > $old_page) {

    // simulate click on next.
    $button['#parents'][] = 'next';
    $old_page = $new_page - 1;
  }
  else {

    // simulate click on previous.
    $button['#parents'][] = 'previous';
    $old_page = $new_page + 1;
  }
  $form_state['values']['op'] = 'next';
  return $form;
}

Functions