title: Drupal: Parent-child draggable table
body: <p>So I've been going at this one for a while now. I'm trying to create a draggable table that has a parent-child relationship, but where the children cannot be moved out of the parent group, and all of the parents are sortable among each other. I've modeled my form and theme off of the admin menu code, and I have it duplicating that functionality. The problem is that I can move the children to another parent, or let it become a parent. As an illustration:</p>
  
  <pre><code>Category 1
  |
  |--Item 1
  |--Item 2
  Category 2
  |
  |--Item 3
  |--Item 4
  |--Item 5
  </code></pre>
  
  <p>I would like to be able to sort Item 1 and Item 2 with each other, and Item 3, Item 4, and Item 5 with each other, but not move them between Category 1 and Category 2. I also need to be able to sort Category 1 and Category 2 with one another, taking the children with them. I've went through so many combinations of <code>$action</code>, <code>$group</code>, <code>$subgroup</code> settings mixed with <code>$class</code> settings for the categories and items that I've lost track. Nothing I have tried so far has produced the desired result. Here's the relevant bits of my code as it is currently:</p>
  
  <p>In my form:</p>
  
  <pre><code>$form['#tree'] = true;
  foreach($categories as $cat) {
      if(!isset($form['categories'][$cat-&gt;cid])){
          $form['categories'][$cat-&gt;cid] = array(
              'weight' =&gt; array(
                  '#type'         =&gt; 'weight',
                  '#delta'        =&gt; 25,
                  '#attributes'   =&gt; array('class' =&gt; array('item-weight', 'item-weight-' . $cat-&gt;cid)),
              ),
              'cid' =&gt; array(
                  '#type'         =&gt; 'hidden',
                  '#value'        =&gt; $cat-&gt;cid,
                  '#attributes'   =&gt; array('class' =&gt; array('cid')),
              ),
          );
          foreach($cats[$cat-&gt;cid] as $item) {
              $form['categories'][$cat-&gt;cid]['items'][$item-&gt;id] = array(
                  'weight' =&gt; array(
                      '#type'         =&gt; 'weight',
                      '#delta'        =&gt; 25,
                      '#default_value'=&gt; $item-&gt;weight,
                      '#attributes'   =&gt; array('class' =&gt; array('item-weight', 'item-weight-' . $cat-&gt;cid)),
                  ),
                  'cid' =&gt; array(
                      '#type'         =&gt; 'hidden',
                      '#value'        =&gt; $cat-&gt;cid,
                      '#attributes'   =&gt; array('class' =&gt; array('cid')),
                  ),
              );
          }
      }
  }
  </code></pre>
  
  <p>In my theme:</p>
  
  <pre><code>$children = element_children($form['categories']);
  $rows = array();
  if(count($children) &gt; 0) {
      foreach($children as $cid) {
          $row = array(
              drupal_render($form['categories'][$cid]['weight']) .
                  drupal_render($form['categories'][$cid]['cid']),
          );
  
          $rows[] = array(
              'data' =&gt; $row,
              'class' =&gt; array('draggable', 'tabledrag-root'),
          );
          foreach(element_children($form['categories'][$cid]['items']) as $id) {
              $row = array(
                  theme('indentation', array('size' =&gt; 1)) . drupal_render($form['categories'][$cid]['items'][$id]['name']),
                  drupal_render($form['categories'][$cid]['items'][$id]['weight']) .
                      drupal_render($form['categories'][$cid]['items'][$id]['cid']),
              );
  
              $rows[] = array(
                  'data' =&gt; $row,
                  'class' =&gt; array('draggable', 'tabledrag-leaf'),
              );
          }
          drupal_add_tabledrag('cat-table', 'order', 'sibling', 'item-weight', 'item-weight-' . $cid);
      }
  }
  
  
  drupal_add_tabledrag('cat-table', 'match', 'parent', 'cid', 'cid', 'cid', true, 1);
  $output = theme('table', array('header' =&gt; $headers, 'rows' =&gt; $rows, 'attributes' =&gt; array('id' =&gt; 'cat-table')));
  $output .= drupal_render_children($form);
  return $output;
  </code></pre>
  
  <p>I've read over the documentation for <code>drupal_add_tabledrag()</code>, looked at the code, looked at example code, and searched around drupal.org and Google, but haven't come up with anything.</p>
  
  <p>My only solution so far is to copy and modify the tabledrag.js file to just eliminate those capabilities, but while stopping the indent problem with the items (meaning, not letting them be on the same as the categories), keeping them in the same category has been Not Fun. </p>
  
  <p>I suppose the most important question is, using standard Drupal is this possible?</p>