diff --git a/includes/nodequeue.admin.inc b/includes/nodequeue.admin.inc
index cbc86b3..c129071 100644
--- a/includes/nodequeue.admin.inc
+++ b/includes/nodequeue.admin.inc
@@ -696,7 +696,7 @@ function nodequeue_arrange_subqueue($queue, $subqueue = NULL) {
   // get nodes from the queue
   $nodes = _nodequeue_dragdrop_get_nodes($queue, $subqueue);
 
-  return drupal_get_form('nodequeue_arrange_subqueue_form', $queue, $nodes, $subqueue);
+  return drupal_get_form('nodequeue_arrange_subqueue_form_' . $subqueue->sqid, $queue, $nodes, $subqueue);
 }
 
 /**
@@ -725,6 +725,9 @@ function _nodequeue_dragdrop_get_nodes($queue, $subqueue) {
 function nodequeue_arrange_subqueue_form($form_state, $queue, $nodes, $subqueue) {
   $form = array('#tree' => TRUE);
 
+  // Prepare the main part of the form which will be themed as a table.
+  $form['#theme'] = 'nodequeue_arrange_subqueue_form';
+
   // Save queue and subqueue objects for later use.
   $form['#queue']    = (array) $queue;
   $form['#subqueue'] = (array) $subqueue;
@@ -775,6 +778,7 @@ function nodequeue_arrange_subqueue_form($form_state, $queue, $nodes, $subqueue)
     '#autocomplete_path' => 'nodequeue/autocomplete/'. $subqueue->sqid,
     '#maxlength' => 1024,
     '#default_value' => t('Enter the title of a node to add it to the queue'),
+    '#attributes' => array('class' => 'subqueue-add-nid'),
   );
   $form['add']['submit'] = array(
     '#type' => 'submit',
@@ -785,7 +789,8 @@ function nodequeue_arrange_subqueue_form($form_state, $queue, $nodes, $subqueue)
   // Submit, reverse, shuffle, and clear actions.
   $form['submit'] = array(
     '#type' => 'submit',
-    '#value' => t('Save')
+    '#value' => t('Save'),
+    '#submit' => array('nodequeue_arrange_subqueue_form_submit'),
   );
   $form['reverse'] = array(
     '#type' => 'submit',
diff --git a/nodequeue.module b/nodequeue.module
index d32be14..524c9fc 100644
--- a/nodequeue.module
+++ b/nodequeue.module
@@ -266,6 +266,19 @@ function nodequeue_link($type, $node = NULL, $teaser = FALSE) {
 }
 
 /**
+ * Implementation of hook_forms().
+ */
+function nodequeue_forms($form_id) {
+  $forms = array();
+  if (strpos($form_id, 'nodequeue_arrange_subqueue_form_') === 0) {
+    $forms[$form_id] = array(
+      'callback' => 'nodequeue_arrange_subqueue_form',
+    );
+  }
+  return $forms;
+}
+
+/**
  * Implementation of hook_theme().
  */
 function nodequeue_theme() {
@@ -1860,17 +1873,23 @@ function theme_nodequeue_arrange_subqueue_form($form) {
 
   $subqueue = $form['#subqueue'];
 
-  // get css to hide some of the help text if javascript is disabled
+  // Get css to hide some of the help text if javascript is disabled.
   drupal_add_css(drupal_get_path('module', 'nodequeue') .'/nodequeue.css');
 
-  // TODO: Would be nice to expose qid, sqid, reference as classes for more custom theming :).
-  // TODO: Create unique ID to make multiple tabledrag forms on a page possible
-  drupal_add_tabledrag('nodequeue-dragdrop', 'order', 'sibling', 'node-position');
+  $table_id = 'nodequeue-dragdrop-' . $subqueue['sqid'];
+  $table_classes = array(
+    'nodequeue-dragdrop',
+    'nodequeue-dragdrop-qid-' . $subqueue['qid'],
+    'nodequeue-dragdrop-sqid-' . $subqueue['sqid'],
+    'nodequeue-dragdrop-reference-' . $subqueue['reference'],
+  );
+  drupal_add_tabledrag($table_id, 'order', 'sibling', 'node-position');
   drupal_add_js(drupal_get_path('module', 'nodequeue') .'/nodequeue_dragdrop.js');
 
-  drupal_add_js(array('nodequeue' => array('reverse' => (bool) $form['#queue']['reverse'])), 'setting');
+  $reverse[str_replace('-', '_', $table_id)] = (bool) $form['#queue']['reverse'];
+  drupal_add_js(array('nodequeue' => array('reverse' => $reverse)), 'setting');
 
-  // render form as table rows
+  // Render form as table rows.
   $rows = array();
   $counter = 1;
   foreach (element_children($form) as $key) {
@@ -1900,17 +1919,17 @@ function theme_nodequeue_arrange_subqueue_form($form) {
     $rows[] = array(array('data' => t('No nodes in this queue.'), 'colspan' => 7));
   }
 
-  // render the main nodequeue table
+  // Render the main nodequeue table.
   $header = array(t('Title'), t('Author'), t('Post Date'), t('Position'), array('data' => t('Operations'), 'colspan' => 2), t('Position'));
-  $output .= theme('table', $header, $rows, array('id' => 'nodequeue-dragdrop', 'class' => 'nodequeue-dragdrop'));
+  $output .= theme('table', $header, $rows, array('id' => $table_id, 'class' => implode(' ', $table_classes)));
 
-  // render the autocomplete field for adding a node to the table
+  // Render the autocomplete field for adding a node to the table.
   $output .= '<div class="container-inline">';
   $output .= drupal_render($form['add']['nid']);
   $output .= drupal_render($form['add']['submit']);
   $output .= '</div>';
 
-  // render the remaining form elements
+  // Render the remaining form elements.
   $output .= drupal_render($form);
 
   return $output;
diff --git a/nodequeue_dragdrop.js b/nodequeue_dragdrop.js
index f56c44a..4f8ed2f 100644
--- a/nodequeue_dragdrop.js
+++ b/nodequeue_dragdrop.js
@@ -1,62 +1,72 @@
 
 Drupal.behaviors.nodequeueDrag = function(context) {
-  var tableDrag = Drupal.tableDrag['nodequeue-dragdrop'];
+  $('.nodequeue-dragdrop').each(function() {
+    var table_id = $(this).attr('id');
+    var tableDrag = Drupal.tableDrag[table_id];
 
-  tableDrag.onDrop = function() {
-    $('td.position').each(function(i){
-      $(this).html(i + 1);
-    });
-    
-    nodequeueUpdateNodePositions();
-  }
+    tableDrag.onDrop = function() {
+      $('#' + table_id + ' td.position').each(function(i) {
+        $(this).html(i + 1);
+      });
+
+      nodequeueUpdateNodePositions(table_id);
+    }
+  });
 }
 
 Drupal.behaviors.nodequeueReverse = function(context) {
-  $('#edit-reverse').click(function(){
-    // reverse table rows...
-    $('tr.draggable').each(function(i){
-      $('.nodequeue-dragdrop tbody').prepend(this);
-    });
+  $('#edit-reverse').click(function() {
+    var $table = $(this).parent().find('.nodequeue-dragdrop:first');
+    var table_id = $table.attr('id');
 
-    nodequeueUpdateNodePositions();
+    // Reverse table rows.
+    $table.find('tr.draggable').each(function(i) {
+      $table.find('tbody').prepend(this);
+    });
 
-    nodequeueInsertChangedWarning();
-    nodequeueRestripeTable();
+    nodequeueUpdateNodePositions(table_id);
+    nodequeueInsertChangedWarning(table_id);
+    nodequeueRestripeTable(table_id);
 
     return false;
   });
 };
 
 Drupal.behaviors.nodequeueShuffle = function(context) {
-  $('#edit-shuffle').click(function(){
-    // randomize table rows...
-    var rows = $('table.nodequeue-dragdrop tbody tr:not(:hidden)').get();
+  $('#edit-shuffle').click(function() {
+    var $table = $(this).parent().find('.nodequeue-dragdrop:first');
+    var table_id = $table.attr('id');
+
+    // Randomize table rows.
+    var rows = $('#' + table_id + ' tbody tr:not(:hidden)').get();
     rows.sort(function(){return (Math.round(Math.random())-0.5);});
     $.each(rows, function(i, row) {
-      $('.nodequeue-dragdrop tbody').prepend(this);
+      $('#' + table_id + ' tbody').prepend(this);
     });
 
-    nodequeueUpdateNodePositions();
-
-    nodequeueInsertChangedWarning();
-    nodequeueRestripeTable();
+    nodequeueUpdateNodePositions(table_id);
+    nodequeueInsertChangedWarning(table_id);
+    nodequeueRestripeTable(table_id);
 
     return false;
   });
 };
 
 Drupal.behaviors.nodequeueClear = function(context) {
-  $('#edit-clear').click(function(){
-    // mark nodes for removal
-    $('.node-position').each(function(i){
+  $('#edit-clear').click(function() {
+    var $table = $(this).parent().find('.nodequeue-dragdrop:first');
+    var table_id = $table.attr('id');
+
+    // Mark nodes for removal.
+    $('#' + table_id + ' .node-position').each(function(i) {
       $(this).val('r');
     });
 
-    // remove table rows...
-    rows = $('table.nodequeue-dragdrop tbody tr:not(:hidden)').hide();
+    // Remove table rows.
+    rows = $('#' + table_id + ' tbody tr:not(:hidden)').hide();
 
-    nodequeuePrependEmptyMessage();
-    nodequeueInsertChangedWarning();
+    nodequeuePrependEmptyMessage(table_id);
+    nodequeueInsertChangedWarning(table_id);
 
     return false;
   });
@@ -69,14 +79,17 @@ Drupal.behaviors.nodequeueRemoveNode = function(context) {
     a = '#' + a.replace('nodequeue-remove-', 'edit-') + '-position';
     $(a).val('r');
 
-    // hide the current row
-    $(this).parent().parent().fadeOut('fast', function(){
-      if ($('table.nodequeue-dragdrop tbody tr:not(:hidden)').size() == 0) {
-        nodequeuePrependEmptyMessage();
+    // Hide the current row.
+    $(this).parent().parent().fadeOut('fast', function() {
+      var $table = $(this).parent().parent();
+      var table_id = $table.attr('id');
+
+      if ($('#' + table_id + ' tbody tr:not(:hidden)').size() == 0) {
+        nodequeuePrependEmptyMessage(table_id);
       }
       else {
-        nodequeueRestripeTable()
-        nodequeueInsertChangedWarning();
+        nodequeueRestripeTable(table_id)
+        nodequeueInsertChangedWarning(table_id);
       }
     });
 
@@ -85,12 +98,12 @@ Drupal.behaviors.nodequeueRemoveNode = function(context) {
 }
 
 Drupal.behaviors.nodequeueClearTitle = function(context) {
-  $('#edit-add-nid').focus(function(){
+  $('.subqueue-add-nid').focus(function() {
     if (this.value == this.defaultValue) {
 			this.value = '';
       $(this).css('color', '#000');
 		}
-  }).blur(function(){
+  }).blur(function() {
     if (!this.value.length) {
       $(this).css('color', '#999');
 			this.value = this.defaultValue;
@@ -99,29 +112,26 @@ Drupal.behaviors.nodequeueClearTitle = function(context) {
 }
 
 /**
- * Updates node positions after nodequeue has been rearranged. It cares about the
- * reverse order and populates nodes the other way round.
- * @return
+ * Updates node positions after nodequeue has been rearranged.
+ * It cares about the reverse order and populates nodes the other way round.
  */
-function nodequeueUpdateNodePositions() {
-   
-  var reverse = Drupal.settings.nodequeue.reverse; //check if reverse option is set
+function nodequeueUpdateNodePositions(table_id) {
+  // Check if reverse option is set.
+  var reverse = Drupal.settings.nodequeue.reverse[table_id.replace(/-/g, '_')];
+  var size = reverse ? $('#' + table_id + ' .node-position').size() : 1;
   
-  var size = reverse ? $('.node-position').size() : 1;
-  $('.node-position').each(function(i){
-    var val = $(this).val();
+  $('#' + table_id + ' .node-position').each(function(i){
     $(this).val(size);
     reverse ? size-- : size++;
-  });	
-	
+  });
 }
 
 /**
  * Restripe the nodequeue table after removing an element or changing the
  * order of the elements.
  */
-function nodequeueRestripeTable() {
-  $('table.nodequeue-dragdrop tbody tr:not(:hidden)')
+function nodequeueRestripeTable(table_id) {
+  $('#' + table_id + ' tbody tr:not(:hidden)')
   .filter(':odd')
     .removeClass('odd').addClass('even')
       .end()
@@ -129,7 +139,7 @@ function nodequeueRestripeTable() {
     .removeClass('even').addClass('odd')
       .end();
 
-  $('tr:visible td.position').each(function(i){
+  $('#' + table_id + ' tr:visible td.position').each(function(i) {
     $(this).html(i + 1);
   });
 }
@@ -137,16 +147,16 @@ function nodequeueRestripeTable() {
 /**
  * Add a row to the nodequeue table explaining that the queue is empty.
  */
-function nodequeuePrependEmptyMessage() {
-  $('.nodequeue-dragdrop tbody').prepend('<tr class="odd"><td colspan="6">'+Drupal.t('No nodes in this queue.')+'</td></tr>');
+function nodequeuePrependEmptyMessage(table_id) {
+  $('#' + table_id + ' tbody').prepend('<tr class="odd"><td colspan="6">'+Drupal.t('No nodes in this queue.')+'</td></tr>');
 }
 
 /**
  * Display a warning reminding the user to save the nodequeue.
  */
-function nodequeueInsertChangedWarning() {
-  if (Drupal.tableDrag['nodequeue-dragdrop'].changed == false) {
-    $(Drupal.theme('tableDragChangedWarning')).insertAfter('.nodequeue-dragdrop').hide().fadeIn('slow');
-    Drupal.tableDrag['nodequeue-dragdrop'].changed = true;
+function nodequeueInsertChangedWarning(table_id) {
+  if (Drupal.tableDrag[table_id].changed == false) {
+    $(Drupal.theme('tableDragChangedWarning')).insertAfter('#' + table_id).hide().fadeIn('slow');
+    Drupal.tableDrag[table_id].changed = true;
   }
 }
