In a custom module, does anyone know how I could go about disabling the table drag functionality for some of the fields in node edit? I don't want the user to be able to change the weights.

Comments

asherry’s picture

I'd really like to know this as well. I would have thought it would be a setting.

tce’s picture

It seems table dragging is added using the function drupal_add_tabledrag(). Looking at the code, the Javascript file is added to add the functionality. So disabling it is a case of removing this file. In a module I did the following...

<?php
/**
 * Implements hook_js_alter().
 */
function MODULENAME_js_alter(&$javascript) {
  unset($javascript['misc/tabledrag.js']);
}
?>

Obviously, you'd want a condition in there so it only deletes if for the form you want. Also, that removes it for ALL tables, if you want to remove it for a single table you need to find the reference to the tabledrag in $javascript['settings]['data'] and unset that instead.

asherry’s picture

If you remove this file that will disable drag functionality for the entire page load. The problem is disabling tabledrag for certain fields, or just a particular set of weighted rows.

tce’s picture

Good point. I think settings.tableDrag decides if the table is draggable or not. Maybe manipulating that will help.

If you look at drupal_add_tabledrag(), it adds it doing the following:

<?php
 $target = isset($subgroup) ? $subgroup : $group;
  $source = isset($source) ? $source : $target;
  $settings['tableDrag'][$table_id][$group][] = array(
    'target' => $target, 
    'source' => $source, 
    'relationship' => $relationship, 
    'action' => $action, 
    'hidden' => $hidden, 
    'limit' => $limit,
  );
  drupal_add_js($settings, 'setting');
?>

Maybe using a hook to remove this before being rendered would work, possibly using hook_js_alter()? How to do this for certain fields only I have no idea. Maybe go in and unbind events using JS.

asherry’s picture

That makes sense, manipulating the Drupal.settings variable might be possible, I'll see if I can try it out myself.

Maybe in the longterm, a drupal_remove_tabledrag function can be discussed?

tmsss’s picture

I tried your solution on a image field but is not working, does it use other function than theme_field_multiple_value_form()?

lionslair’s picture

I have tried it too. It is calling the function but still adding the drag and drop.

Did you sort it out either?

harcher’s picture

Thanks Jeff the solution in that link worked :)

glass.dimly’s picture

This works great. Just dropped it into a custom module and worked like a charm.

bburg’s picture

Sorry for not addressing the specific question of targeting fields to disable tabledrag, but this issue is the most common search result on the subject in general.

For some reason, unset($javascript['misc/tabledrag.js']); does not work for me...

Jeff Burnz's solution is probably more elegant, but I was looking for a quick solution to disable tabledrag altogether and came up with this:


function hook_js_alter(&$javascript) {
  if (isset($javascript['misc/tabledrag.js'])) {
    $javascript['misc/tabledrag.js']['data'] = drupal_get_path('module', 'my_module') . '/includes/nodrag.js';
  }
}

Where my_module/includes/nodrag.js is an empty file. Akin to removing the contents of tabledrag.js itself, but that would be hacking core.

Metatag should be in core.

malberts’s picture

For anyone else finding this page, there is a module that implements the solution from http://www.commercialprogression.com/post/how-remove-tabledrag-rearrangi...

Module: No Table Drag

fluxline’s picture

jeff's solution does not work for inline entity forms.

StephenRobinson’s picture

/**
 * Implements hook_field_widget_form_alter().
 */
function mymodule_field_widget_form_alter(&$element, &$form_state, $context) {
  $disabledragid='';
  $fieldnames=array('field_timeline'); // add more fields here...........
  if(isset($element['#field_name'])){
    if( in_array($element['#field_name'], array_values($fieldnames)) ){
      if(isset($element['_weight'])){
        $element['_weight']['#access']=false;
        $disabledragid='.field-type'.str_replace('field_','-',$element['#field_name'].'-field');
      }
    }
  }
  if($disabledragid!=''){
    drupal_add_js("
(function ($) { 
  var hideColumns = Drupal.tableDrag.prototype.hideColumns;
  Drupal.tableDrag.prototype.hideColumns = function() {
    hideColumns.call(this);
    $('".$disabledragid." .tabledrag-toggle-weight').text('');
    $('".$disabledragid." .field-multiple-drag').text('');
    $('".$disabledragid." th:last').text('');
  }
  var showColumns = Drupal.tableDrag.prototype.showColumns;
  Drupal.tableDrag.prototype.showColumns = function () {
    showColumns.call(this);
    $('".$disabledragid." .tabledrag-toggle-weight').text('');
    $('".$disabledragid." .field-multiple-drag').text('');
    $('".$disabledragid." th:last').text('');
  }
})(jQuery);
", 'inline');
  }
}
tfranz’s picture

The module Field lock multi values has this feature for some fields, too:

This module:
- allow disable edit previous field values
- allow disable field values reorder

Supported fields: if field widget "multiple values" behavior value FIELD_BEHAVIOR_DEFAULT.
Example: textfield, textarea, Field collection, Entity reference, …

Unfortunately (for me) it seems not to work for file-fields?!

dunx’s picture

Or for a much quicker solution, just hide the drag handle using css.

#field-my-sortable .handle {
  display:none;
}
Ronino’s picture

Here's what worked for me for a two-value field:

function hook_form_FORM_ID_alter(&$form, &$form_state) {
  // Remove the table drag functionality from the multi-value field.
  // theme_field_multiple_value_form() will then render the two value fields
  // like regular ones, more or less, after some adaptions.
  $form['my_field']['und']['#cardinality'] = 1;

  // Set the title on the first value field as the container is not rendered.
  $form['my_field']['und'][0]['value']['#title'] = $form['my_field']['und']['#title'];

  // Remove the weight select boxes for every .
  $form['my_field']['und'][0]['_weight']['#access'] = FALSE;
  $form['my_field']['und'][1]['_weight']['#access'] = FALSE;
}
handkerchief’s picture