Hello,
Ever wanted how to re-order your items (nodes, custom,…) easily with drag and drop just like drupal do with menus ?
It can be done with the function
the process can be divided in 3 steps
- build a form (to change weight of your items)
- theme it as a table (to add the js stuff)
- update weight items in db (..to save it)
Let’s take the example of Benecol. They want to display / send 21 tips, 1 a day. A solution can be to store the day of the tip in the edit / add form and update it if necessary. but if we want to change day 20 to day 2 we have to update every tips from 2 to 20… not very handy and can be source if errors.
this update can be done easily with drag and drop, without errors !
in this example we will create a table containing the 21steps and displayed with step number, title, body and an edit link
1. build a form
function benecol_eplan_display_content_form() {
$r = db_query("select title, nid, field_estdnumb_value as step, body
from node inner join node_revisions using(nid)
inner join content_type_estep using(nid)
order by field_estdnumb_value");
while ($row = db_fetch_object($r)){
//create a partial table row containing the data from the table
$data = array(
"(".$row->step.")",
$row->title,
truncate_utf8(strip_tags($row->body),100,TRUE,TRUE),
l(t('edit'), "node/".$row->nid."/edit", array('query'=>drupal_get_destination()))
);
//add our static "row" data into a form value
$form['rows'][$row->nid]['data']=array('#type' => 'value','#value' => $data);
//now create the weight form element. (if js is enabled, it will be hidden by core tabledrag.js)
$form['rows'][$row->nid]['weight-'.$row->nid]=array(
'#type'=>'textfield',
'#size'=>5,
'#default_value'=>$row->step,
'#attributes' => array('class'=>'weight'),
);
}
//add submit
$form['submit']=array(
'#type'=>'submit',
'#value'=>t('Save changes'),
);
return $form;
}2. theme the form as a table
function theme_benecol_eplan_display_content_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'][$id]['weight-'.$id]);
//Add the row to the array of rows and css class for js
$table_rows[] = array('data'=>$this_row, 'class'=>'draggable');
}
}
//Make sure the header count matches the column count
$header=array(
t("Day"),t("Title"), t("Body"),t("Edit"),t("Order")
);
$output = theme('table',$header,$table_rows,array('id'=>'esptep-table'));
$output .= drupal_render($form);
//will add tabledrag.js
drupal_add_tabledrag('esptep-table', 'order', 'sibling', 'weight');
return $output;
}3. update weight in db on submit
function benecol_eplan_display_content_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' && is_numeric($data)) {
//we have the DB id of the row in the element name
$id = str_replace('weight-','',$key);
//and the order in $data
db_query("UPDATE {content_type_estep} SET field_estdnumb_value=%d WHERE nid=%d",$data,$id);
}
}
}


