--- nodereference.module	Tue Mar 22 08:37:03 2010
+++ nodereference.module	Tue May  4 15:48:03 2010
@@ -28,6 +28,9 @@
     'nodereference_select' => array(
       'arguments' => array('element' => NULL),
     ),
+    'nodereference_select_sortable' => array(
+      'arguments' => array('element' => NULL),
+    ),
     'nodereference_buttons' => array(
       'arguments' => array('element' => NULL),
     ),
@@ -362,6 +365,14 @@
         'default value' => CONTENT_CALLBACK_DEFAULT,
       ),
     ),
+    'nodereference_select_sortable' => array(
+      'label' => t('Select list with drag & drop sorting'),
+      'field types' => array('nodereference'),
+      'multiple values' => CONTENT_HANDLE_CORE,
+      'callbacks' => array(
+        'default value' => CONTENT_CALLBACK_DEFAULT,
+      ),
+    ),
     'nodereference_buttons' => array(
       'label' => t('Check boxes/radio buttons'),
       'field types' => array('nodereference'),
@@ -400,6 +411,11 @@
       '#columns' => array('uid'), '#delta' => 0,
       '#process' => array('nodereference_select_process'),
     ),
+    'nodereference_select_sortable' => array(
+      '#input' => TRUE,
+      '#columns' => array('uid'), '#delta' => 0,
+      '#process' => array('nodereference_select_sortable_process'),
+    ),
     'nodereference_buttons' => array(
       '#input' => TRUE,
       '#columns' => array('uid'), '#delta' => 0,
@@ -493,6 +509,13 @@
       );
       break;
 
+    case 'nodereference_select_sortable':
+      $element = array(
+        '#type' => 'nodereference_select_sortable',
+        '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL,
+      );
+      break;
+
     case 'nodereference_buttons':
       $element = array(
         '#type' => 'nodereference_buttons',
@@ -569,6 +592,39 @@
  *
  * The $fields array is in $form['#field_info'][$element['#field_name']].
  */
+function nodereference_select_sortable_process($element, $edit, $form_state, $form) {
+  // The nodereference_select widget doesn't need to create its own
+  // element, it can wrap around the optionwidgets_select element.
+  // This will create a new, nested instance of the field.
+  // Add a validation step where the value can be unwrapped.
+  $field = $form['#field_info'][$element['#field_name']];
+  $field_key  = $element['#columns'][0];
+  $element[$field_key] = array(
+    '#type' => 'select',
+    '#options' => nodereference_allowed_values($field),
+    '#multiple' => 0,
+    '#default_value' => isset($element['#value'][$element['#columns'][0]]) ? $element['#value'][$element['#columns'][0]] : '',
+    // The following values were set by the content module and need
+    // to be passed down to the nested element.
+    '#title' => $element['#title'],
+    '#required' => $element['#required'],
+    '#description' => $element['#description'],
+    '#field_name' => $element['#field_name'],
+    '#type_name' => $element['#type_name'],
+    '#delta' => $element['#delta'],
+    '#columns' => $element['#columns'],
+  );
+  return $element;
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $form['#field_info'][$element['#field_name']].
+ */
 function nodereference_buttons_process($element, $edit, $form_state, $form) {
   // The nodereference_select widget doesn't need to create its own
   // element, it can wrap around the optionwidgets_select element.
@@ -719,6 +775,9 @@
   foreach ($references as $key => $value) {
     $options[$key] = $value['rendered'];
   }
+  if (!$field['required']) {
+    $options = array(0 => '<'. t('none') .'>') + $options;
+  }
   return $options;
 }
 
@@ -987,6 +1046,10 @@
   return $element['#children'];
 }
 
+function theme_nodereference_select_sortable($element) {
+  return $element['#children'];
+}
+
 function theme_nodereference_buttons($element) {
   return $element['#children'];
 }
