Index: includes/webform.components.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.components.inc,v
retrieving revision 1.7
diff -u -r1.7 webform.components.inc
--- includes/webform.components.inc	6 Nov 2009 00:27:40 -0000	1.7
+++ includes/webform.components.inc	10 Jan 2010 00:30:52 -0000
@@ -409,6 +409,75 @@
     '#description' => t('Optional. In the menu, the heavier items will sink and the lighter items will be positioned nearer the top.'),
     '#weight' => 4,
   );
+  
+  // Add conditional fields.
+  $component_options = array();
+  $counter = 0;
+  $last_pagebreak_slice = 0;
+  foreach ($node->webform['components'] as $cid => $test_component) {
+    // Only components before the pagebreak can be considered.
+    if ($test_component['type'] == 'pagebreak') {
+      $last_pagebreak_slice = $counter;
+    }
+    if ($test_component['name'] == $component['name']) {
+      break;
+    }
+    if ($test_component['type'] != 'pagebreak') {
+      $component_options[$test_component['form_key']] = $test_component['name'];
+    }
+    $counter++;
+  }
+  if ($component['type'] != 'pagebreak') {
+    $fieldset_description = t('Create a rule to control whether or not to skip this page.');
+  }
+  else {
+    $fieldset_description = t('Create a rule to control whether or not to show this form element.');
+  }
+  $component_options = array_slice($component_options, 0, $last_pagebreak_slice, TRUE);
+  $form['conditional'] = array(
+    '#weight' => 5,
+    '#type' => 'fieldset',
+    '#title' => t('Conditional rules'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#description' => t('Create a rule to control whether or not to show this form element.'),
+    '#tree' => FALSE,
+  );
+  $form['conditional']['extra'] = array(
+    '#tree' => TRUE,
+  );
+  $form['conditional']['extra']['conditional_component'] = array(
+    '#type' => 'select',
+    '#title' => t('Component'),
+    '#options' => $component_options,
+    '#description' => t('Select another component to decide whether to show or hide this component. You can only select components occurring before the most recent pagebreak.'),
+    '#default_value' => $component['extra']['conditional_component'],
+  );
+  $form['conditional']['extra']['conditional_operator'] = array(
+    '#type' => 'select',
+    '#title' => t('Operator'),
+    '#options' => array(
+      '=' => t('Is one of'),
+      '!=' => t('Is not one of')
+    ),
+    '#description' => t('Determines whether the list below is inclusive or exclusive.'),
+    '#default_value' => $component['extra']['conditional_operator'],
+  );
+  $form['conditional']['extra']['conditional_values'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Values'),
+    '#description' => t('List values, one per line, that will trigger this action. If you leave this blank, this component will always display.'),
+    '#default_value' => $component['extra']['conditional_values'],
+  );
+  if (empty($component_options)) {
+    $form['conditional']['extra']['conditional_component']['#options'] = array('');
+    $form['conditional']['#description'] = t('You cannot set display options for a component appearing before the first pagebreak.');
+    foreach ($form['conditional']['extra'] as &$el) {
+      if (is_array($el)) {
+        $el['#disabled'] = TRUE;
+      }
+    }
+  }
 
   // Add the fields specific to this component type:
   webform_load_components(); // Load all component types.
@@ -632,5 +701,10 @@
         $component['extra'][$extra] = $default;
       }
     }
+    $component['extra'] += array(
+      'conditional_component' => '',
+      'conditional_operator' => '=',
+      'conditional_values' => '',
+    );
   }
 }
Index: webform.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.module,v
retrieving revision 1.142
diff -u -r1.142 webform.module
--- webform.module	22 Dec 2009 02:32:30 -0000	1.142
+++ webform.module	10 Jan 2010 00:30:51 -0000
@@ -1187,48 +1187,23 @@
     );
 
     // Put the components into a tree structure.
-    $component_tree = array();
-    $page_count = 1;
-    $page_num = 1;
-    _webform_components_tree_build($node->webform['components'], $component_tree, 0, $page_count);
+    if (!isset($form_state['storage']['component_tree'])) {
+      $form_state['storage']['component_tree'] = array();
+      $form_state['storage']['page_count'] = 1;
+      $form_state['storage']['page_num'] = 1;
+      _webform_components_tree_build($node->webform['components'], $form_state['storage']['component_tree'], 0, $form_state['storage']['page_count']);
+    }
+
+    // Shorten up our variable names.
+    $component_tree = $form_state['storage']['component_tree'];
+    $page_count = $form_state['storage']['page_count'];
+    $page_num = $form_state['storage']['page_num'];
 
     if ((!isset($node->build_mode) || $node->build_mode != NODE_BUILD_PREVIEW) && $enabled) {
       if ($page_count > 1) {
         $next_page = t('Next Page >');
         $prev_page = t('< Previous Page');
 
-        // Check if we're in a multipage form and determine the page number.
-        if (!empty($form_state['storage']['submitted'])) {
-          $page_num = $form_state['values']['details']['page_num'];
-          $errors = form_get_errors();
-          if (empty($errors)) {
-            if (end($form_state['clicked_button']['#parents']) == 'prev' && $page_num > 1) {
-              $page_num--;
-            }
-            elseif (end($form_state['clicked_button']['#parents']) == 'next' && $page_num < $page_count) {
-              $page_num++;
-            }
-          }
-        }
-        else {
-          $page_num = 1;
-        }
-
-        $form['details']['page_num'] = array(
-          '#type'      => 'hidden',
-          '#value'     => $page_num,
-        );
-
-        $form['details']['page_count'] = array(
-          '#type'      => 'hidden',
-          '#value'     => $page_count,
-        );
-
-        $form['details']['page_count'] = array(
-          '#type'      => 'hidden',
-          '#value'     => $page_count,
-        );
-
         // Add the submit button(s).
         if ($page_num > 1) {
           $form['previous'] = array(
@@ -1253,7 +1228,6 @@
         }
       }
       else {
-        $page_num = 1;
         // Add the submit button.
         $form['submit'] = array(
           '#type' => 'submit',
@@ -1267,7 +1241,9 @@
     $microweight = 0.001;
     foreach ($component_tree['children'] as $cid => $component) {
       $component_value = isset($form_state['values']['submitted'][$component['form_key']]) ? $form_state['values']['submitted'][$component['form_key']] : NULL;
-      _webform_client_form_add_component($cid, $component, $component_value, $form['submitted'], $form, $submission, $page_num, $enabled, $filter);
+      if (_webform_client_form_rule_check($form_state, $component, $page_num)) {
+        _webform_client_form_add_component($cid, $component, $component_value, $form['submitted'], $form, $submission, $page_num, $enabled, $filter);
+      }
       if (isset($form['submitted'][$component['form_key']])) {
         $form['submitted'][$component['form_key']]['#weight'] += $microweight;
         $microweight += 0.001;
@@ -1275,13 +1251,13 @@
     }
 
     $form['details']['nid'] = array(
-      '#type'      => 'value',
-      '#value'     => $node->nid,
+      '#type' => 'value',
+      '#value' => $node->nid,
     );
     if (isset($submission->sid)) {
       $form['details']['sid'] = array(
-        '#type'      => 'hidden',
-        '#value'     => $submission->sid,
+        '#type' => 'hidden',
+        '#value' => $submission->sid,
       );
     }
   }
@@ -1289,6 +1265,25 @@
   return $form;
 }
 
+/**
+ * Check if a component should be displayed on the current page.
+ */
+function _webform_client_form_rule_check($form_state, $component, $page_num) {
+  $show_component = TRUE;
+  if (isset($component['extra']['conditional_values']) && strlen(trim($component['extra']['conditional_values'])) && $component['page_num'] == $page_num) {
+    $input_value = $form_state['values']['submitted'][$component['extra']['conditional_component']];
+    $test_values = array_map('trim', explode("\n", $component['extra']['conditional_values']));
+    $show_component = in_array($input_value, $test_values);
+    if ($component['extra']['conditional_operator'] == '!=') {
+      $show_component = !$show_component;
+    }
+  }
+  return $show_component;
+}
+
+/**
+ * Add a component to the form. Called recursively for fieldsets.
+ */
 function _webform_client_form_add_component($cid, $component, $component_value, &$parent_fieldset, &$form, $submission, $page_num, $enabled = FALSE, $filter = TRUE) {
   // Load with submission information if necessary.
   if (!$enabled) {
@@ -1361,7 +1356,7 @@
   module_load_include('inc', 'webform', 'includes/webform.submissions');
   webform_load_components();
 
-  $node = node_load(array('nid' => $form_state['values']['details']['nid']));
+  $node = node_load($form_state['values']['details']['nid']);
 
   // Check for a multi-page form that is not yet complete.
   $submit_op = empty($node->webform['submit_text']) ? t('Submit') : $node->webform['submit_text'];
@@ -1383,9 +1378,49 @@
       }
     }
 
-    // Rebuild the form, allowing the rebuild to determine the next page.
-    $form_state['rebuild'] = TRUE;
-    return;
+    // Set the page number.
+    if (!isset($form_state['storage']['page_num'])) {
+      $form_state['storage']['page_num'] = 1;
+    }
+    if ($form_state['clicked_button']['#value'] == t('Next Page >')) {
+      $direction = 1;
+    }
+    else {
+      $direction = 0;
+    }
+
+    // If the next page has no components that need to be displayed, skip it.
+    if (isset($direction)) {
+      $components = $direction ? $node->webform['components'] : array_reverse($node->webform['components'], TRUE);
+      $last_component = end($node->webform['components']);
+      foreach ($components as $component) {
+        if ($component['type'] == 'pagebreak' && (
+            $direction == 1 && $component['page_num'] >= $form_state['storage']['page_num'] ||
+            $direction == 0 && $component['page_num'] < $form_state['storage']['page_num'])) {
+          $previous_pagebreak = $component;
+          continue;
+        }
+        if (isset($previous_pagebreak)) {
+          $page_num = $previous_pagebreak['page_num'] + $direction;
+          // If we've found an component on this page, advance to that page.
+          if (_webform_client_form_rule_check($form_state, $component, $page_num)) {
+            $form_state['storage']['page_num'] = $page_num;
+            break;
+          }
+          // If we've gotten to the end of the form without finding any more
+          // components, set the page number more than the max, ending the form.
+          elseif ($direction && $component['cid'] == $last_component['cid']) {
+            $form_state['storage']['page_num'] = $page_num + 1;
+          }
+        }
+      }
+    }
+
+    // Rebuild the form and display the next page.
+    if ($form_state['storage']['page_num'] <= $form_state['storage']['page_count']) {
+      $form_state['rebuild'] = TRUE;
+      return;
+    }
   }
 
   if (isset($form_state['storage']['submitted'])) {
