使用自动保存拖放表格单元格

I am trying to manipulate a dynamically generated table. At the moment I'm using a table with content editable td's. Database is updated using the following AJAX call ...

$(document).ready(function(){
   $("td[contenteditable=true]").blur(function(){
   var msg = $(".alert");
   var newvalue = $(this).text();
   var field = $(this).attr("id");
   $.post("fn-scp-update.php",field+"="+newvalue,function(d){
       var data = JSON.parse(d);

   });
   });
});

With the following in the td elements for the script to find ....

        echo '<td contenteditable="true" id="due_date:'.$row['id'].'">'.$date_display.'</td>';

The data is split apart in a separate PHP script, and the db updated ...

foreach($_POST as $key=>$value){
    $key = strip_tags(trim($key));
    $value = strip_tags(trim($value));
    $explode = explode(":",$key);
    $user_id = $explode[1];
    $field_name = $explode[0];
    if(isset($user_id)){
        if($field_name == 'due_date'){
          $date = new DateTime($value);
        $value = $date->format('Y-m-d');
        }
        elseif($field_name == 'pend_notes'){
          $value=$conn->real_escape_string($value);
        }
        $update = $conn->query("UPDATE su_master SET $field_name='{$value}' WHERE id='$user_id'"); 
        if($update){
            $response = "Details Updated";
            http_response_code(200); //Setting HTTP Code to 200 i.e OK
        }else{
            $response = "Not Modified";
            http_response_code(304); //Setting HTTP Code to 304 i.e Not Modified
        }
    }else{
        $response = "Not Acceptable";
    }
}
}

I'll get around to making the db function PDO at some point.

Within the td the id is picked up, with the first part being the column name, an id for row reference and then the data is updated.

It all works very nicely, however, I now have a request to make the content of the cells draggable. Basically, if something is already written in the contenteditable cell, it needs to have the ability to be dragged to another contenteditable cell and the data written to the database in the same way as it is current. Or working the same way at least, not necessarily a verbatim copy of the current code.

Given that I'm not even sure where to start, it has made Googling an answer incredibly difficult.

I did try wrapping the contents of the cell in a span, that itself was draggable. Which worked, but not when the cell was editable.

The problem I'm sure is that I'm using blur, which means the db entry isn't written until after I release the mouse, or click elsewhere. If that elsewhere is on another cell, it's messing up the dropping.

3 days, and no resolution, please help :(

Summary ... editable and draggable cells.

I should also mention, that this is all contained within a single table, so is restricted to within a single table element.

OK, so I found the answer in the end.

To grab all of the text, I used an onclick to select all the text inside the content editable. Using this method, double clicking still allowed editing of the contents.

echo '<td contenteditable="true" onclick="document.execCommand(\'selectAll\',false,null)" id="pend_notes:'.$row['id'].'"><a href="'.$link.'">'.$row['pend_notes'].'</td>';

Then to fix the issue with FireFox, used the following as a workaround ...

var r = null;
var origParent = null;
function DoLoad()
{   
    document.addEventListener("drag", DoDrag, false);
    document.addEventListener("drop", DoDrop, false);
}
function DoDrag(evt)
{
   if (r == null)
    {
        var sel = window.getSelection();
    var range = sel.getRangeAt(0);
    r = range.cloneContents();
origParent = evt.rangeParent;
console.log('r is now set');
    }
}

function DoDrop(evt)
{
    if (r != null)
{
    console.log('inserting node.');
        var rng = document.createRange( );
        rng.setStart(evt.rangeParent, evt.rangeOffset);
        //console.log('inserting node.');
        rng.insertNode(r); 
         r = null;
    evt.stopPropagation();
    }
    else{
    console.log('r is null...');
    }

}

Then loaded on body

<body onload="DoLoad()">

This fixed (at least until FF changes something) the inability to drag and drop between cells when using contenteditable.

It doesn't fix the issue that although the cell has been dropped, it doesn't really exist as part of the contenteditable until it has been re-clicked on and then clicked off, but a tweak to my blur may fix that.

If and when I get around to fixing that issue, we might be somewhere near and I'll let you know. If anybody has any suggestions along this line, it would be really helpful.