Drupal : Creating Form with Drag and Drop Ordering

    User Rating: 2 / 5

    Star ActiveStar ActiveStar InactiveStar InactiveStar Inactive
     

    drupal form with drag and drop ordering

    So you want to create a form with drag and drop ordering in Drupal 7? Here are 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;
    }

    2. 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;
    }

    3. 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 

    Please publish modules in offcanvas position.