Index: imagefield.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/imagefield/imagefield.module,v
retrieving revision 1.30.2.6.2.64
diff -u -p -r1.30.2.6.2.64 imagefield.module
--- imagefield.module	13 May 2008 00:02:02 -0000	1.30.2.6.2.64
+++ imagefield.module	29 May 2008 14:11:02 -0000
@@ -615,6 +615,8 @@ function _imagefield_widget_prepare_form
 
       $file['fid'] = 'upload';
       $file['preview'] = $filepath;
+      // Assign a weight outside of range for new uploads.
+      $file['weight'] = 1000;
 
       // If a single field, mark any other images for deletion and delete files in session
       if (!$field['multiple']) {
@@ -660,6 +662,10 @@ function _imagefield_widget_form($node, 
   drupal_add_js('misc/upload.js');
   drupal_add_js(drupal_get_path('module', 'imagefield') .'/imagefield.js');
   drupal_add_css(drupal_get_path('module', 'imagefield') .'/imagefield.css');
+  if (module_exists('jquery_ui')) {
+    jquery_ui_add(array('ui.sortable'));
+    drupal_add_js(drupal_get_path('module', 'imagefield') .'/imagefield.sortable.js', 'theme');
+  }
 
   $fieldname = $field['field_name'];
 
@@ -735,6 +741,14 @@ function _imagefield_widget_form($node, 
           '#theme' => 'imagefield_edit_image_row',
         );
 
+        if ($field['multiple']) {
+          $form[$fieldname][$delta]['weight'] = array(
+            '#type' => 'weight',
+            '#title' => t('Weight'),
+            '#default_value' => $delta,
+          );
+        }
+
         $form[$fieldname][$delta]['flags']['delete'] = array(
           '#type' => 'checkbox',
           '#title' => t('Delete'),
@@ -1015,6 +1029,7 @@ function theme_imagefield_edit_image_row
   $output .= '</div>';
   $output .= drupal_render($element['alt']);
   $output .= drupal_render($element['title']);
+  $output .= drupal_render($element['weight']);
   $output .= '</div>';
   $output = '<div class="imagefield-edit-image-row clear-block">'. $output .'</div>';
   if (isset($element['replace'])) {
@@ -1146,7 +1161,10 @@ function imagefield_js() {
       $items[$key]['alt'] = $image['alt'];
       $items[$key]['title'] = $image['title'];
       $items[$key]['flags']['delete'] = $image['flags']['delete'];
+      $items[$key]['weight'] = $image['weight'];
     }
+    // Re-order images by user-defined weights.
+    usort($items, '_imagefield_sort');
   }
 
   // Get our new form baby, yeah tiger, get em!
@@ -1159,9 +1177,68 @@ function imagefield_js() {
   $form = form_builder('imagefield_js', $form);
 
   $output =  theme('status_messages') . drupal_render($form);
+  if (module_exists('jquery_ui')) {
+    $output .= '<script type="text/javascript">Drupal.imagefieldSortableAutoAttach("#'. form_clean_id($fieldname .'-attach-wrapper') .'");</script>';
+  }
 
   // We send the updated file attachments form.
   echo drupal_to_js(array('status' => true, 'data' => $output));
   exit;
 
 }
+
+/**
+ * Sort uploaded images in $_POST by weight.
+ */
+function _imagefield_sort($a, $b) {
+  return ($a['weight'] > $b['weight'] ? 1 : -1);
+}
+
+/**
+ * Implementation of hook_nodeapi().
+ */
+function imagefield_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
+  switch ($op) {
+    case 'insert':
+    case 'update':
+      // Update image field item order according to their weights.
+      foreach (content_fields() as $field => $info) {
+        if ($info['type'] == 'image' && isset($node->$field)) {
+          $deltas = array();
+          $reorder = FALSE;
+          foreach ($node->$field as $delta => $item) {
+            // Skip this field instance if it's not multiple.
+            if (!isset($item['weight'])) {
+              break;
+            }
+            $new_delta = (int)$item['weight'];
+            $deltas[$delta] = $new_delta;
+            if ($new_delta != $delta) {
+              $reorder = TRUE;
+            }
+          }
+          if (!$reorder) {
+            continue;
+          }
+
+          // Sort by new weight and assign zero-based delta values.
+          $i = 0;
+          asort($deltas);
+          foreach (array_keys($deltas) as $delta) {
+            $deltas[$delta] = $i;
+            $i++;
+          }
+
+          // Temporarily set ridiculously high deltas to avoid primary key
+          // clashes. Then store the new values.
+          $db_info = content_database_info($info);
+          db_query("UPDATE {". $db_info['table'] ."} SET delta = delta + 100000 WHERE vid = %d", $node->vid);
+          foreach ($deltas as $delta => $new_delta) {
+            db_query("UPDATE {". $db_info['table'] ."} SET delta = %d WHERE vid = %d AND delta = %d + 100000", $new_delta, $node->vid, $delta);
+          }
+        }
+      }
+      break;
+  }
+}
+
Index: imagefield.sortable.js
===================================================================
RCS file: imagefield.sortable.js
diff -N imagefield.sortable.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ imagefield.sortable.js	29 May 2008 14:10:14 -0000
@@ -0,0 +1,59 @@
+// $Id: imagefield.js,v 1.1.2.1 2008/04/21 06:59:13 sun Exp $
+
+/**
+ * Overwrite default uploadAutoAttach method.
+ * This will be called onload and after AJAX completes.
+ * @see upload.js
+ */
+Drupal.uploadAutoAttach.prototype = new Drupal.imagefieldAutoAttach();
+Drupal.imagefieldAutoAttach = function() {
+  alert("in");
+  $('input.upload').each(function () {
+    var uri = this.value;
+    // Extract the base name from the id (edit-attach-url -> attach).
+    var base = this.id.substring(5, this.id.length - 4);
+    var button = base + '-button';
+    var wrapper = base + '-wrapper';
+    var hide = base + '-hide';
+    var upload = new Drupal.jsUpload(uri, button, wrapper, hide);
+  });
+  Drupal.imagefieldSortableAutoAttach();
+}
+
+/**
+ * Auto attach jQuery Interface sortable behaviour.
+ */
+Drupal.imagefieldSortableAutoAttach = function(scope) {
+  scope = (typeof scope != 'string' ? '' : scope + ' ');
+//  console.log(scope + '.imagefield-edit-image-row:not(".imagefield-sortable-processed")');
+//  console.log($(scope + '.imagefield-edit-image-row:not(".imagefield-sortable-processed")'));
+  $(scope + '.imagefield-edit-image-row:not(".imagefield-sortable-processed")').each(function() {
+    $(this).addClass('imagefield-sortable-processed')
+//      .parent('[id$="-attach-wrapper"]').change(function() {
+//        setTimeout("Drupal.imagefieldSortableAutoAttach();", 1000);
+//      }).end()
+      .parent().sortable({
+        'items': $('.imagefield-edit-image-row'),
+        'update': Drupal.imagefieldSortableUpdate,
+        'axis': 'y',
+        'opacity': 0.8,
+        'scroll': true,
+        'scrollSpeed': 80
+      });
+  });
+};
+
+/**
+ * Update image deltas after drag'n'drop.
+ */
+Drupal.imagefieldSortableUpdate = function(e, ui) {
+  $(ui.element).children('.imagefield-edit-image-row').each(function(i) {
+    $('select[name*="weight"]', this).val(i);
+  });
+}
+
+// Global killswitch.
+//if (Drupal.jsEnabled) {
+//  $(document).ready(Drupal.imagefieldSortableAutoAttach);
+//}
+
