Index: components/select.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/select.inc,v
retrieving revision 1.18.2.19.2.18
diff -u -r1.18.2.19.2.18 select.inc
--- components/select.inc	23 Jul 2008 06:02:37 -0000	1.18.2.19.2.18
+++ components/select.inc	8 Aug 2008 18:00:33 -0000
@@ -82,6 +82,13 @@
   // Convert the user-entered options list into an array.
   $default_value = _webform_filter_values($component['value'], NULL, NULL, FALSE);
   $options = _webform_select_options($component['extra']['items']);
+  
+  // We need to deal with the situation where optgroup's are specified, but
+  // we're not rendering as a select or a listbox. In this case, we flatten the
+  // options.
+  if ($component['extra']['aslist'] != 'Y') {
+    $options = _webform_flatten_options($options);
+  }
 
   if ($component['extra']['aslist'] == 'Y' && $component['extra']['multiple'] != 'Y') {
     $options = array('' => t('select...')) + $options;
@@ -187,7 +194,8 @@
  *   Nothing.
  */
 function _webform_submit_select(&$data, $component) {
-  $options = drupal_map_assoc(array_flip(_webform_select_options($component['extra']['items'])));
+  
+  $options = drupal_map_assoc(array_flip(_webform_flatten_options(_webform_select_options($component['extra']['items']))));
 
   if (is_array($data)) {
     foreach ($data as $key => $value) {
@@ -378,15 +386,56 @@
  */
 function _webform_select_options($text) {
   $options = array();
-  $rows = array_filter(explode("\n", _webform_filter_values(trim($text))));
+  $rows = array_filter(explode("\n", trim($text)));
   foreach ($rows as $option) {
     $option = trim($option);
-    if (preg_match('/^([^|]+)\|(.*)$/', $option, $matches)) {
-      $options[$matches[1]] = $matches[2];
+    
+    /**
+     * If the Key of the option is within < >, treat as an optgroup
+     * 
+     * <Group 1>
+     *   creates an optgroup with the label "Group 1"
+     * 
+     * <>
+     *   Unsets the current group, allowing items to be inserted at the root element.  
+     */
+    
+    if (preg_match('/^\<([^>]*)\>$/', $option, $matches)) {
+      if (empty($matches[1])) {
+        unset($group);
+      }
+      else {
+        $group = _webform_filter_values($matches[1], NULL, NULL, FALSE);
+      }
+    }
+    else if (preg_match('/^([^|]+)\|(.*)$/', $option, $matches)) {
+      $key = _webform_filter_values($matches[1]);
+      $value = _webform_filter_values($matches[2]);
+      isset($group) ? $options[$group][$key] = $value : $options[$key] = $value;
     }
     else {
-      $options[$option] = $option;
+      $filtered_option = _webform_filter_values($option);
+      isset($group) ? $options[$group][$filtered_option] = $filtered_option : $options[$filtered_option] = $filtered_option;
     }
   }
   return $options;
 }
+
+/**
+ * Utility function to flatten $options so that it does not contain any arrays.
+ * @param $options
+ *   An array possibly containing options.
+ * @return
+ *   The flattened array.
+ */
+function _webform_flatten_options($options) {
+  foreach($options as $optgroup_key => $optgroup) {
+    if (is_array($optgroup)) {
+      foreach ($optgroup as $option => $value) {
+        $options[$option] = $value;
+      }
+      unset($options[$optgroup_key]);
+    }
+  }
+  return $options;
+}
\ No newline at end of file
