0

If you have seen the Views module, there is "sorting criteria", where we add fields and then rearrange fields to set the priority. In order to rearrange, we click on "rearrange" link and all fields get a draggable UI so that we can move it up or down to set sorting priority.

How can I do this thing exactly programmatically?

  • Planing to implement it in a view or in form...?? – Abin Aug 12 '15 at 6:57
  • Implementing it in a ctool modal. Form actually, that opens up in popup. – Sugandh Khanna Aug 12 '15 at 6:59
  • 2
    So, you don't want to use Draggable Views? drupal.org/project/draggableviews – leymannx Aug 12 '15 at 7:08
1

Here is a drupal_add_tabledrag function using which you can add draggable functionality programmatically.

Assists in adding the tableDrag JavaScript behavior to a themed table.

Draggable tables should be used wherever an outline or list of sortable items needs to be arranged by an end-user. Draggable tables are very flexible and can manipulate the value of form elements placed within individual columns.

See this blog for example. You may need to imprement theme function.

$element = $vars['element'];
drupal_add_tabledrag('sample_table', 'order', 'sibling', 'item-row-weight');

$header = array(
  'label' => t('Attribute'), 
  'checkbox' => t('Enabled/disabled'),
  'weight' => t('Weight'),
);
1

Here are the 3 simple steps to create a form with drag and drop ordering:

  1. Implement hook_menu, to register the URL of the form
function module_name_menu() {
$items = array();
$items['admin/config/content/module_name/manage'] = array(
    'title' => 'Recent News: List Links',   
    'page callback' => 'drupal_get_form',
    'page arguments' => array('module_name_manage'),
    'access arguments' => array('access administration pages'),
);
}

We will use the following function to render the form:

function module_name_manage() {
$db_result = db_query( "select id,title position from recent_news order by position");   
// create array and add one element called data
$rows= array();
$form['#tree'] = TRUE;
$max = 60;
foreach($db_result as $row){   
    $title = $row->title;
    if(strlen($title)>$max)
        $title = substr($title,0,$max).' ...';
    $form['slides'][$row->id]['id'] = array(
        '#type' => 'hidden',      
        '#default_value' => $row->id,       
    );
    // Textfield to hold content id.
    $form['slides'][$row->id]['title'] = array(
        '#type' => 'item',        
        '#title' => $title
    );     
    // This field is invisible, but contains sort info (weights).
    $form['slides'][$row->id]['weight'] = array(
        '#type' => 'weight',
        '#title' => t('Weight'),
        '#title_display' => 'invisible',
        '#default_value' => $row->position,
    );
}

$form['submit'] = array('#type' => 'submit', '#value' => t('Save changes'));
return $form;
}
  1. implement hook_theme, to register theme implementation of form with drag and drop support
function module_name_theme($existing, $type, $theme, $path) {
return array(
    'module_name_manage' => array(
        'render element' => 'form',
    ),
);
}

And here is the callback function which will render the form with drag and drop capabilities

function theme_module_name_manage($variables) {
$form = $variables['form'];

$rows = array();
foreach (element_children($form['slides']) as $nid) {
    $form['slides'][$nid]['weight']['#attributes']['class'] = array('slides-order-weight');
    $rows[] = array(
        'data' => array(
            array('class' => array('slide-cross')),               
                drupal_render($form['slides'][$nid]['title']),
                drupal_render($form['slides'][$nid]['weight']),       
            ),
        'class' => array('draggable'),
    );
}

$header = array('',t('title'),t('position'));
$output = drupal_render($form['note']);
$output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'slides-order')));
$output .= drupal_render_children($form);

drupal_add_tabledrag('slides-order', 'order', 'sibling', 'slides-order-weight');

return $output;
}
  1. Implement hook_submit, to handle form submit and save the ordering
function module_name_manage_submit($form, &$form_state) {
$slides = array(); 
foreach ($form_state['values']['slides'] as $slide) {   
    $slides[] = array(
        'id' => $slide['id'],       
        'weight' => $slide['weight'],
    );         
}  
if (!empty($slides)) {
    usort($slides, '_module_name_arraysort');
}  
$position = 1;
foreach($slides as $slide){
    $id = $slide['id'];
    $sql = "UPDATE recent_news SET position={$position} WHERE id = {$id}";
    db_query($sql);
    $position++;
}

drupal_set_message(t('Ordering have been saved.'));
}

// Custom array sort function by weight.
function _module_name_arraysort($a, $b) {
if (isset($a['weight']) && isset($b['weight'])) {
    return $a['weight'] < $b['weight'] ? -1 : 1;
}
return 0;
}

The code is quite long but you can just copy and paste then modify it if necessary. This tutorial is based on Ki Kim's post on http://www.urbaninsight.com/2012/09/11/creating-table-with-draggable-weights-in-drupal-7

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.