Index: webform.module
===================================================================
RCS file: /cvs/webform/webform.module,v
retrieving revision 1.6
diff -u -r1.6 webform.module
--- webform.module	8 Jun 2009 06:46:01 -0000	1.6
+++ webform.module	9 Jun 2009 19:39:10 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: webform.module,v 1.6 2009/06/08 06:46:01 admin Exp $
+// $Id: webform.module $
 
 /**
  * This module provides a simple way to create forms and questionnaires.
@@ -1481,6 +1481,7 @@
     _webform_components_tree_build($node->webform['components'], $component_tree, 0, $page_count);
 
     if ((!$preview && $enabled)) {
+      $button_states = array('submit' => false, 'prev' => false, 'next' => false);
       if ($page_count > 1) {
         $next_page = t('Next Page >');
         $prev_page = t('< Previous Page');
@@ -1490,11 +1491,13 @@
           $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--;
+            if ($page_num > 1 && (end($form_state['clicked_button']['#parents']) == 'prev' || 
+              $form_state['clicked_button']['#return_value'] == 'prev')) {
+                $page_num--;
             }
-            elseif (end($form_state['clicked_button']['#parents']) == 'next' && $page_num < $page_count) {
-              $page_num++;
+            elseif ($page_num < $page_count && (end($form_state['clicked_button']['#parents']) == 'next' ||
+              $form_state['clicked_button']['#return_value'] == 'next')) {
+                $page_num++;
             }
           }
         }
@@ -1519,11 +1522,12 @@
 
         // Add the submit button(s).
         if ($page_num > 1) {
-          $form['previous'] = array(
+          $form['prev'] = array(
             '#type' => 'submit',
             '#value' => $prev_page,
             '#weight' => 1000,
           );
+          $button_states['prev'] = true;
         }
         if ($page_num == $page_count) {
           $form['submit'] = array(
@@ -1531,6 +1535,7 @@
             '#value' => empty($node->webform['submit_text']) ? t('Submit') : $node->webform['submit_text'],
             '#weight' => 1001,
           );
+          $button_states['submit'] = true;
         }
         elseif ($page_num < $page_count) {
           $form['next'] = array(
@@ -1538,6 +1543,7 @@
             '#value' => $next_page,
             '#weight' => 1001,
           );
+          $button_states['next'] = true;
         }
       }
       else {
@@ -1548,6 +1554,7 @@
           '#value' => empty($node->webform['submit_text']) ? t('Submit') : $node->webform['submit_text'],
           '#weight' => 1000,
         );
+        $button_states['submit'] = true;
       }
     }
 
@@ -1555,7 +1562,7 @@
     $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);
+      _webform_client_form_add_component($cid, $component, $component_value, $form['submitted'], $form, $submission, $page_num, $button_states, $enabled);
       if (isset($form['submitted'][$component['form_key']])) {
         $form['submitted'][$component['form_key']]['#weight'] += $microweight;
         $microweight += 0.001;
@@ -1592,7 +1599,7 @@
   return $form;
 }
 
-function _webform_client_form_add_component($cid, $component, $component_value, &$parent_fieldset, &$form, $submission, $page_num, $enabled = FALSE) {
+function _webform_client_form_add_component($cid, $component, $component_value, &$parent_fieldset, &$form, $submission, $page_num, $button_states, $enabled = FALSE) {
   // Load with submission information if necessary.
   if (!$enabled) {
     // This component is display only.
@@ -1602,6 +1609,25 @@
     }
   }
   elseif ($component['page_num'] == $page_num) {
+    // Check if component is attempting to override a default button. 
+    if (array_key_exists('extra', $component) && array_key_exists('button_type', $component['extra'])) {
+      $button_type = $component['extra']['button_type'];
+      // Loop through the types of button: i.e. submit, previous and next.
+      foreach ($button_states as $type => $show_button) {
+        if ($type == $button_type) {
+          if ($show_button) {
+            // Remove the default button that's being overridden.
+            if (array_key_exists($button_type, $form)) {
+              unset($form[$button_type]);
+            }
+            break;
+          }
+          // Do not display the component if the corresponding button_state is false: i.e. if a default button of 
+          // the type being overridden would not otherwise be displayed.
+          else {return;}
+        }
+      }
+    }
     // Add this user-defined field to the form (with all the values that are always available).
     if (isset($submission->data)) {
       $display_function = '_webform_submission_display_'. $component['type'];
@@ -1636,7 +1662,7 @@
     $microweight = 0.001;
     foreach ($component['children'] as $scid => $subcomponent) {
       $subcomponent_value = isset($component_value[$subcomponent['form_key']]) ? $component_value[$subcomponent['form_key']] : NULL;
-      _webform_client_form_add_component($scid, $subcomponent, $subcomponent_value, $parent_fieldset[$component['form_key']], $form, $submission, $page_num, $enabled);
+      _webform_client_form_add_component($scid, $subcomponent, $subcomponent_value, $parent_fieldset[$component['form_key']], $form, $submission, $page_num, $button_states, $enabled);
       $parent_fieldset[$component['form_key']][$subcomponent['form_key']]['#weight'] += $microweight;
       $microweight += 0.001;
     }
@@ -1667,7 +1693,7 @@
 
   // Check for a multi-page form that is not yet complete.
   $submit_op = empty($node->webform['submit_text']) ? t('Submit') : $node->webform['submit_text'];
-  if ($form_state['values']['op'] != $submit_op) {
+  if ($form_state['clicked_button']['#value'] != $submit_op && $form_state['clicked_button']['#return_value'] != 'submit') {
     // Checkboxes need post-processing to maintain their values.
     _webform_client_form_submit_process($node, $form_state['values']['submitted'], array('select', 'grid'));
 
@@ -2291,7 +2317,7 @@
   }
   else {
     $new = str_replace(
-      array(' ', '-', '€', 'ƒ', 'Š', 'Ž', 'š', 'ž', 'Ÿ', '¢', '¥', 'µ', 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'à', 'á', 'â', 'ã', 'ä', 'å', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Œ',  'œ',  'Æ',  'Ð',  'Þ',  'ß',  'æ',  'ð',  'þ'),
+      array(' ', '-', '€', 'ƒ', 'Š', 'Ž', 'š', 'ž', 'Ÿ', '¢', '¥', 'µ', 'À', '?', 'Â', 'Ã', 'Ä', 'Å', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', '?', 'Î', '?', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', '?', 'à', 'á', 'â', 'ã', 'ä', 'å', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Œ',  'œ',  'Æ',  '?',  'Þ',  'ß',  'æ',  'ð',  'þ'),
       array('_', '_', 'E', 'f', 'S', 'Z', 's', 'z', 'Y', 'c', 'Y', 'u', 'A', 'A', 'A', 'A', 'A', 'A', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'),
       $new);
   }
--- button.inc
+++ button.inc
@@ -0,0 +1,103 @@
+<?php
+// $Id: button.inc $
+/** 
+ * function webform_edit_button
+ * Create a set of form items to be displayed on the form for editing this component.
+ * Use care naming the form items, as this correlates directly to the database schema.
+ * The component "Name" and "Description" fields are added to every component type and
+ * are not necessary to specify here (although they may be overridden if desired).
+ * @returns An array of form items to be displayed on the edit component page
+ **/
+function _webform_edit_button ($current_field) {
+  $edit_fields = array();
+  $edit_fields['name'] = array (
+    '#type' => 'textfield',
+    '#title' => 'Label',
+    '#description' => t("Label to display on button"),
+    '#default_value' => $current_field['name'],
+    '#size' => 60,
+    '#maxlength' => 127,
+    '#weight' => 1,
+  );
+  $edit_fields['extra']['button_type'] = array (
+    '#type' => 'select',
+    '#title' => t("This button will"),
+    '#default_value' => $current_field['extra']['button_type'],
+    '#options' => array(
+      'submit' => 'Submit the form', 
+      'prev' => 'Go back to previous page', 
+      'next' => 'Go forward to next page'
+    ),
+    '#description' => t('What will happen when the user clicks this button?'),
+  );
+  $edit_fields['extra']['#weight'] = 2;
+
+  // Turn off things that webform includes by default that aren't needed for this component.
+  $edit_fields['value'] = array();
+  $edit_fields['mandatory'] = array();
+  $edit_fields['extra']['description'] = array();
+
+  return $edit_fields;
+}
+
+/** 
+ * function webform_render_button
+ * Build a form item array containing all the properties of this component
+ * @param $component An array of information describing the component, directly correlating to the webform_component database schema
+ * @returns An array of a form item to be displayed on the client-side webform
+ * 
+ **/
+function _webform_render_button ($component) {
+  $name = check_plain($component['name']);
+  $src = check_plain($component['value']);
+  $button_type = check_plain($component['extra']['button_type']);
+  
+  $form_item = array (
+    '#type'   => 'submit',
+    '#value' => $name,
+    '#name' => $button_type,
+    '#weight' => $component['weight'],
+    '#prefix' => '<div class="webform-component-' . $component['type'] . '" id="webform-component-'._webform_safe_name($name) . '">',
+    '#suffix' => '</div>',
+  );
+  // Set values used to determine which button was clicked.
+  switch ($button_type) {
+    case 'submit':
+      $form_item['#return_value'] = t('submit');
+      $form_item['#attributes']['class'] = t('override-submit');
+    break;
+    case 'prev':
+      $form_item['#return_value'] = t('prev');
+      $form_item['#attributes']['class'] = t('override-prev');
+    break;
+    case 'next':
+      $form_item['#return_value'] = t('next');
+      $form_item['#attributes']['class'] = t('override-next');
+    break;
+  }
+  return $form_item;
+}
+
+/** 
+ * function _webform_submission_data_button
+ * Display the result of this component's submission. The output of this function will be displayed under the "results" tab then "submissions"
+ * @param $data An array of information containing the submission result, directly correlating to the webform_submitted_data database schema
+ * @param $component An array of information describing the component, directly correlating to the webform_component database schema
+ * @returns Textual output formatted for human reading.
+ **/
+function _webform_submission_display_button ($data,$component) {
+  return '';
+}
+
+/** 
+ * function _webform_help_button
+ * Module specific instance of hook_help
+ **/
+function _webform_help_button($section) {
+  switch ($section) {
+    case 'admin/settings/webform#button_description':
+      $output = t("Buttons: override webform's normal previous, next and submit buttons with input buttons.");
+      break;
+  }
+  return $output;
+}

--- image_button.inc
+++ image_button.inc
@@ -0,0 +1,124 @@
+<?php
+// $Id: image_button.inc $
+/** 
+ * function webform_edit_image_button
+ * Create a set of form items to be displayed on the form for editing this component.
+ * Use care naming the form items, as this correlates directly to the database schema.
+ * The component "Name" and "Description" fields are added to every component type and
+ * are not necessary to specify here (although they may be overridden if desired).
+ * @returns An array of form items to be displayed on the edit component page
+ **/
+function _webform_edit_image_button ($current_field) {
+  $edit_fields = array();
+  $description = t('Path to image using substitution tokens: %base (base path, eg: /), ' .
+    '%theme (path to theme, eg: themes/garland), and %files (path to files).<br />' .
+    'Examples: %theme/images/mybutton.gif, %base/myfolder/mybutton.gif, %files/mybutton.gif, http://example.com/mybutton.gif');
+  $edit_fields['value'] = array (
+    '#type' => 'textfield',
+    '#title' => t("Filepath for image"),
+    '#default_value' => $current_field['value'],
+    '#description' => $description,
+    '#size' => 60,
+    '#maxlength' => 127,
+    '#weight' => 1,
+  );
+  $edit_fields['extra']['button_type'] = array (
+    '#type' => 'select',
+    '#title' => t("This button will"),
+    '#default_value' => $current_field['extra']['button_type'],
+    '#options' => array(
+      'submit' => 'Submit the form', 
+      'prev' => 'Go back to previous page', 
+      'next' => 'Go forward to next page'
+    ),
+    '#description' => t('What will happen when the user clicks this button?'),
+  );
+  $edit_fields['extra']['#weight'] = 2;
+
+  // Turn off things that webform includes by default that aren't needed for this component.
+  $edit_fields['mandatory'] = array();
+  $edit_fields['extra']['description'] = array();
+
+  return $edit_fields;
+}
+
+/** 
+ * function webform_render_image_button
+ * Build a form item array containing all the properties of this component
+ * @param $component An array of information describing the component, directly correlating to the webform_component database schema
+ * @returns An array of a form item to be displayed on the client-side webform
+ * 
+ * Key points for using multiple image_buttons in a form:
+ * 1) Do give each image_button a unique #name (unlike regular buttons, you can't have several image_buttons all named op).
+ * 2) Don't give an image_button a #default_value.
+ * 3) Don't give an image_button a #value
+ * 4) Do give each image_button a #return_value. This is the same as what you would assign to #value if IE6 problems 
+ *   hadn't forced Drupal to implement some unusual element handling. If you don't assign this, it will default to true.
+ * 5) Do use $form_state['clicked_button']['#value'] to find the #value of, well, the clicked image_button. This field 
+ *   will contain the value of #return_value for the clicked image_button.
+ **/
+function _webform_render_image_button ($component) {
+  $name = check_plain($component['name']);
+  $src = check_plain($component['value']);
+  $button_type = check_plain($component['extra']['button_type']);
+  
+  global $theme;
+  init_theme();
+  $themes = list_themes();
+  $theme_obj = $themes[$theme];
+  $path_to_theme = dirname($theme_obj->filename);
+  $tokens = array('%base' => base_path(), '%theme' => $path_to_theme, '%files' => file_directory_path());
+  $image_url = strtr($src, $tokens);
+  
+  $form_item = array (
+    '#type'   => 'image_button',
+    '#src' => $image_url,
+    '#name' => $button_type,
+    '#attributes' => array(
+      'alt' => $name,
+    ),
+    '#weight' => $component['weight'],
+    '#prefix' => '<div class="webform-component-' . $component['type'] . '" id="webform-component-'._webform_safe_name($name) . '">',
+    '#suffix' => '</div>',
+  );
+  // Set values used to determine which button was clicked. These are used by form_type_image_button_value() in form.inc.
+  switch ($button_type) {
+    case 'submit':
+      $form_item['#return_value'] = t('submit');
+      $form_item['#attributes']['class'] = t('override-submit');
+    break;
+    case 'prev':
+      $form_item['#return_value'] = t('prev');
+      $form_item['#attributes']['class'] = t('override-prev');
+    break;
+    case 'next':
+      $form_item['#return_value'] = t('next');
+      $form_item['#attributes']['class'] = t('override-next');
+    break;
+  }
+  return $form_item;
+}
+
+/** 
+ * function _webform_submission_data_image_button
+ * Display the result of this component's submission. The output of this function will be displayed under the "results" tab then "submissions"
+ * @param $data An array of information containing the submission result, directly correlating to the webform_submitted_data database schema
+ * @param $component An array of information describing the component, directly correlating to the webform_component database schema
+ * @returns Textual output formatted for human reading.
+ **/
+function _webform_submission_display_image_button ($data,$component) {
+  return '';
+}
+
+/** 
+ * function _webform_help_image_button
+ * Module specific instance of hook_help
+ **/
+function _webform_help_image_button($section) {
+  switch ($section) {
+    case 'admin/settings/webform#image_button_description':
+      $output = t("Image Buttons: override webform's normal previous, next and submit buttons with image buttons.");
+      break;
+  }
+  return $output;
+}


