I'm trying to alter/patch/hack node_level_blocks (like the admin blocks overview page) so that some users are restricted in choosing regions for certain blocks. For instance the "New Content" view must always be in the Right region. The normal user can change the weight and add more blocks to that region, but they can't remove that block from that region.

What I did (I'm pretty close):

  • Form alter the <select> to that it contains only 1 option
  • Override Drupal.tableDrag.blocks.onDrag to fix and improve the standard tableDrag handler and make the row jump back to its forced position

That works, but the user can still drag the block around to regions it doesn't belong. (I don't have a demo online.)

How do I tell tableDrag to NOT let some blocks out of their original regions? I don't understand its 400 options...

  • Similar questions was asked here already. You need to play with Drupal.tableDrag.prototype.row.prototype.isValidSwap() and "simply" make it return FALSE if swap should not be valid. At least that's how I solved my similar issue.
    – Mołot
    Commented Jan 30, 2014 at 15:41
  • you did all the real work, so you should benefit from it. All I did was to point you to the right place, way too little to earn rep on it.
    – Mołot
    Commented Jan 31, 2014 at 7:58
  • Fair enough. BIG BIG thanks. I've been looking for this for a long time. (What a weird place to add another class: inside another class' prototype.)
    – Rudie
    Commented Jan 31, 2014 at 11:52

1 Answer 1


The checking-magic comes from Drupal.tableDrag.prototype.row.prototype.isValidSwap and you can override that to add a custom validation. This solved my problem:

// onDomReady: override Drupal.tableDrag.prototype.row.prototype.isValidSwap to add swap-validation.
jQuery(function($) {
  if (Drupal.tableDrag) {
    var _isValidSwap = Drupal.tableDrag.prototype.row.prototype.isValidSwap;
    Drupal.tableDrag.prototype.row.prototype.isValidSwap = function(tr) {
      // Do standard tableDrag validation.
      var valid = _isValidSwap.apply(this, arguments);
      if (!valid) {
        return false;

      // One of us?
      var $select = $('.form-select', this.element),
        loner = $select[0].options.length <= 1;
      if (loner) {
        // Can't swap with non-draggables, since that would mean a boundary.
        if (!$(tr).is('.draggable')) {
          return false;

        // Can't skip over any rows, since that might be a boundary.
        var diff = tr.rowIndex - this.element.rowIndex;
        if (Math.abs(diff) > 1) {
          return false;

      return true;

All thanks to Mołot of course.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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