Quick Guide to using drupal_add_tabledrag and enjoying jquery drag and drop loveliness
We are finding that the feature exciting most end users in Drupal 6 is the lovely new jquery based drag and drop, as seen on the blocks and menu edit pages - we will be quite happy never have to explain the concept of "weights" again. The best news is that you can add this functionality to your own forms for free - and here is how.
Build and theme the form
We are assuming your vaguely familiar with the form API - you can brush up here http://api.drupal.org/api/file/developer/topics/forms_api.html - so we won't go into too much detail here. Essentially we need to create a form that will be themed into a table, each row in the table will need a form element capable of holding the "weight" or "order" value.
function example_form(&$form_state){ //fetch the data from the DB $result = db_query("SELECT id, value1, value2, weight FROM {foo} ORDER BY weight ASC"); while ($row = db_fetch_object($result)){ //create a partial table row containing the data from the table $data = array( $row->value1, $row->value2 ); //add our static "row" data into a form value $form['rows'][$row->id]['data']=array( '#type' => 'value', '#value' => $data ); //now create the weight form element. //NOTE how we add the id into the element key $form['rows'][$row->id]['weight-'.$row->id]=array( '#type'=>'textfield', '#size'=>5, '#default_value'=>$weight, //add a specific class in here - we need this later '#attributes' => array('class'=>'weight'), ); } //Don't forget the submit button $form['submit']=array( '#type'=>'submit', '#value'=>t('Save changes'), ); }That should create a pretty basic and ugly form - we now need to theme this as a table
function theme_example_form($form){ //loop through each "row" in the table array foreach($form['rows'] as $id => $row){ //we are only interested in numeric keys if (intval($id)){ $this_row = $row['data']['#value']; //Add the weight field to the row $this_row[] = drupal_render($form['rows'][$sid]['weight-'.$sid]); //Add the row to the array of rows $table_rows[] = array('data'=>$this_row, 'class'=>'draggable'); } } //Make sure the header count matches the column count $header=array( "Value1","Value2","Order" ); $output = theme('table',$header,$table_rows,array('id'=>'example-table')); $output .= drupal_render($form); // Call add_tabledrag to add and setup the JS for us // The key thing here is the first param - the table ID // and the 4th param, the class of the form item which holds the weight drupal_add_tabledrag('example-table', 'order', 'sibling', 'weight'); }Don't forget - we are in Drupal 6 land now so we need to register our theme function before it will take affect (how many times have I forgotten this already!)
function example_module_theme() { return array( 'example_form' => array( 'arguments' => array('form' => NULL), ), ); }Handle the submit
We should now have a working drag and drop enabled form themed as a table, we now need to handle the submit and store our new weight values.
function example_form_submit($form, &$form_state) { foreach($form_state['values'] as $key=>$data){ //we are only interested in weight elements if (substr($key,0,6)=='weight'){ //cunningly we have the DB id of the row in the element name $id = str_replace('weight-','',$key); db_query("UPDATE {foo} SET weight=%d WHERE id=%d",$data,$id); } } //optionally set the redirect value in form_submit ... }
- johnvsc's blog
- Login to post comments

There are a few errors in this code -- double-check it before using it on your own site.
--Cliff Smith