You are here

function webform_conditional_prepare_javascript in Webform 7.4

Loop through all the conditional settings and add needed JavaScript settings.

We do a bit of optimization for JavaScript before adding to the page as settings. We remove unnecessary data structures and provide a "source map" so that JavaScript can quickly determine if it needs to check rules when a field on the page has been modified.

Parameters

object $node: The loaded node object, containing the webform.

array $submission_data: The cid-indexed array of existing submission values to be included for sources outside of the current page.

int $page_num: The number of the page for which javascript settings should be generated.

Return value

array Array of settings to be send to the browser as javascript settings.

1 call to webform_conditional_prepare_javascript()
template_preprocess_webform_form in ./webform.module
Prepare for theming of the webform form.

File

includes/webform.conditionals.inc, line 1418
Form elements and menu callbacks to provide conditional handling in Webform.

Code

function webform_conditional_prepare_javascript($node, array $submission_data, $page_num) {
  $settings = array(
    'ruleGroups' => array(),
    'sourceMap' => array(),
    'values' => array(),
  );
  $operators = webform_conditional_operators();
  $conditionals = $node->webform['conditionals'];
  $components = $node->webform['components'];
  $topological_order = webform_get_conditional_sorter($node)
    ->getOrder();
  foreach ($topological_order[$page_num] as $conditional_spec) {
    $conditional = $conditionals[$conditional_spec['rgid']];
    $rgid_key = 'rgid_' . $conditional['rgid'];

    // Assemble the main conditional group settings.
    $settings['ruleGroups'][$rgid_key] = array(
      'andor' => $conditional['andor'],
    );
    foreach ($conditional['actions'] as $action) {
      if ($action['target_type'] == 'component') {
        $target_component = $components[$action['target']];
        $target_parents = webform_component_parent_keys($node, $target_component);
        $aid_key = 'aid_' . $action['aid'];
        $action_settings = array(
          'target' => 'webform-component--' . str_replace('_', '-', implode('--', $target_parents)),
          'invert' => (int) $action['invert'],
          'action' => $action['action'],
          'argument' => $components[$action['target']]['type'] == 'markup' ? filter_xss_admin($action['argument']) : $action['argument'],
        );
        $settings['ruleGroups'][$rgid_key]['actions'][$aid_key] = $action_settings;
      }
    }

    // Add on the list of rules to the conditional group.
    foreach ($conditional['rules'] as $rule) {
      $rid_key = 'rid_' . $rule['rid'];
      switch ($rule['source_type']) {
        case 'component':
          $source_component = $components[$rule['source']];
          $source_parents = webform_component_parent_keys($node, $source_component);
          $source_id = 'webform-component--' . str_replace('_', '-', implode('--', $source_parents));

          // If this source has a value set, add that as a setting. NULL or
          // array(NULL) should be sent as an empty array to simplify the
          // jQuery.
          if (isset($submission_data[$source_component['cid']])) {
            $source_value = $submission_data[$source_component['cid']];
            $source_value = is_array($source_value) ? $source_value : array(
              $source_value,
            );
            $settings['values'][$source_id] = $source_value === array(
              NULL,
            ) ? array() : $source_value;
          }
          $conditional_type = webform_component_property($source_component['type'], 'conditional_type');
          $operator_info = $operators[$conditional_type][$rule['operator']];
          $rule_settings = array(
            'source_type' => $rule['source_type'],
            'source' => $source_id,
            'value' => $rule['value'],
            'callback' => $operator_info['js comparison callback'],
          );
          if (isset($operator_info['comparison prepare js'])) {
            $callback = $operator_info['comparison prepare js'];
            $rule_settings['value'] = $callback($rule['value']);
          }
          $settings['ruleGroups'][$rgid_key]['rules'][$rid_key] = $rule_settings;
          $settings['sourceMap'][$source_id][$rgid_key] = $rgid_key;
          break;
        case 'conditional_start':
          $settings['ruleGroups'][$rgid_key]['rules'][$rid_key] = array(
            'source_type' => $rule['source_type'],
            'andor' => $rule['operator'],
          );
          break;
        case 'conditional_end':
          $settings['ruleGroups'][$rgid_key]['rules'][$rid_key] = array(
            'source_type' => $rule['source_type'],
          );
          break;
      }
    }
  }
  return $settings;
}