3

I'm using Denis' outstanding tableDnD jquery plugin. I would like to allow users to drag/drop rows but only when their mouse is within a particular td within the row.

So far I've tried two methods:(note that the var "tr" contains the jquery row element I'm operating on. the td id="queue_position" is the one I'm trying to enable dragging for).

I think that tableDnD only checks for the nodrag class when it starts up. adding or deleting the nodrop class dynamically doesn't change anything. So I tried two ways to do what I need to do.

Attempt one was to dive into tableDnD internals and try to call it's makeDraggable function. Attempt two was to re-initialize tableDnD after adding/removing the nodrop class.

Either of these methods seems to work to enable dragging when in the allowed td. Neither of them properly disables dragging when leaving the td. Once a row is enabled in the mouseenter event it stays enabled forever.

I'd prefer to find a way to do what I need without modifying tableDnD.

Any suggestions on how to make this work?

$(tr)
  .addClass("nodrag")
  .find("td[id='queue_position']")
//.on("mouseenter",function() { 
//    $(tr).removeClass("nodrag"); 
//    $.tableDnD.makeDraggable(document.getElementById("tableLeft"));
//})
//.on("mouseleave",function() { 
//    $(tr).addClass("nodrag");    
//    $.tableDnD.makeDraggable(document.getElementById("tableLeft"));
//});

 .on("mouseenter",function() { 
      $(tr).removeClass("nodrag"); 
      $("#tableLeft").tableDnD({onDrop: handleDragDrop});
 })
 .on("mouseleave",function() { 
      $(tr).addClass("nodrag");
      $("#tableLeft").tableDnD({onDrop: handleDragDrop});
 });      
davidkonrad
  • 83,997
  • 17
  • 205
  • 265
RoyHB
  • 1,715
  • 1
  • 22
  • 38

3 Answers3

1

Have you tried dragHandle see examples: "Identity rows"

I am sure if you simply give a class name (class="drag-me-only") for the table cel that you want to use as the drag handle and provide that class name as configuration option (dragHandle: ".drag-me-only") option then we would change the cursor and all the other magics will follow suite only when the mouse is over that cel.

nickl-
  • 8,417
  • 4
  • 42
  • 56
0

While waiting to see if someone suggests a better alternative, I've modified tableDnd to do what I need.

For this to work each td in each tr that you want to be active for dragging has to have an I.D. The same id can be used for td's in multiple columns. I could have used a class detection method but named td's seemed like less fussing for a table with many columns.

<tr><td id='queue_position'></td><td id='vin'></td></tr>
<tr><td id='queue_position'></td><td id='vin'></td></tr>
  1. Added a new option called activeCols. activeCols is an array containing 0 or more td id's
  2. Added code to the makeDraggable function that does the traditional stuff if activeCols is empty or does not exist and does different stuff if it does exist.

If anyone else wants to play with or use my mods the entire modified tableDnD is available at jsfiddle

Only barely started testing but it seems to work so far. I'd still rather do this without modifying tableDnD but at least I can check off the item on my to-do list until some better solution comes along.

New option in tableDnD definition:

$("#tableLeft").tableDnD({
        onDrop: handleDragDrop,
        activeCols: ["queue_position","vin"] // new option
});

New option handling:

this.tableDnDConfig = {
    activeCols: options.activeCols ? options.activeCols: [],
    etc, etc, etc

New makeDraggable code:

    makeDraggable: function(table) {
    // Now initialise the rows
    var rows = table.rows; //getElementsByTagName("tr")
    var config = table.tableDnDConfig;
    for (var i=0; i<rows.length; i++) {
        // To make non-draggable rows, add the nodrag class (eg for Category and Header rows) 
    var nodrag = jQuery(rows[i]).hasClass("noDrag");

    if (config.activeCols.length > 0) {
    if (!nodrag) {
        jQuery(rows[i]).find("td").each(function() {
        if (jQuery.inArray($(this).prop("id"),config.activeCols) !== -1) {
            jQuery(this).mousedown(function(ev) {
            jQuery.tableDnD.dragObject = this.parentNode;
            jQuery.tableDnD.currentTable = table;
            jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this.parentNode, ev); // or rows[i].offset?
            if (config.onDragStart) {
                config.onDragStart(table, this.parentNode);
            }
            return false;
            }).css("cursor", "move");
        }
        });
    }
    }
    else {
    if (! nodrag) { //There is no NoDnD attribute on rows I want to drag
        jQuery(rows[i]).mousedown(function(ev) {
        if (ev.target.tagName == "TD") {
            jQuery.tableDnD.dragObject = this;
            jQuery.tableDnD.currentTable = table;
            jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this, ev);
            if (config.onDragStart) {
            // Call the onDrop method if there is one
            config.onDragStart(table, this);
            }
            return false;
        }
        }).css("cursor", "move"); // Store the tableDnD object
    }
    }
    }
},
RoyHB
  • 1,715
  • 1
  • 22
  • 38
0

On the header rows of the table you may want to add nodrag and nodrop class. You just need to put a space between the two class names ( class="nodrag nodrop")