Need jquery drag and drop/reorder/renumber table row functionality

Looking for a plugin that allows one to drag and drop table rows in a new position within the same table and all the other rows are re-numbered accordingly, sort of like how the Netflix queue functions (but I think theirs is too customized to re-purpose). Oh, and it can’t be related to the dataTables plugin because I can’t get that plugin to operate on multiple tables on the same page.

I’ve run up a quick example that updates the table index column after a row has been moved.

See how that goes.

Oh, this could be good…

Thanks, Paul. So far it looks like it is working in my project.

Paul, your plug-in works great and we are using it. We are having a slight problem where in the rows that are being re-sorted there are text input fields awaiting either new content or editing of prior content by the user. When your plugin is enabled the user can no longer click in the field and give it focus so that the field can be typed in. Oddly, the border of the input fields change on hover and so does the cursor. You just can’t click inside and do anything in the field. Once your scripting is disabled then the fields become editable. I am searching for a solution on my own but seeing how this is a professional project I am working on with monetary and time constraints I thought I would post about it here to see if you are able to offer a solution before I stumble on one.

Adding text input fields to that jsfiddle example results in things still working properly.

Perhaps it’s about time for you to show us what you’re doing instead?

I wish I had a URL to provide but it’s only on our local servers right now. Here is the HTML though for the table that has “sortable” added to it, but with only one row of the master table shown (for space saving purposes). I am warning you that it is hideous and not entirely of my own design:

<table width="100%" id="responseOptions" class="grid">
            
        <thead>
            <tr>
                <th class="index sequence">Seq</th>
                <th class="itemlabel">Label</th>
                <th style="width:50px" class="displayimage">Image</th>
                <th class="displayimagecta">Action</th>
                <th class="isactive">A?</th>
                <th style="display:none" class="hiddenflds">&nbsp;</th>
                <th class="rowcta">Row Action</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
                <td align="right" colspan="8"><img class="addItem" src="/Content/img/add.png" alt="Add"> <a class="addItem" style="cursor: pointer;">Create New Option</a></td>
            </tr>
        </tfoot>
        <tbody>
        
            
            <tr>
                <td class="index sequence">1</td>
                <td colspan="6">
            
                   <form method="post" id="form1" data-ajax-success="showgridsave" data-ajax-failure="showgridfailure" data-ajax-complete="showgridsuccess" data-ajax-begin="validategridform" data-ajax="true" action="/testsetup/demographicresponseitemoption/edititem">

                    <table width="100%" border="0">
                        

                        <tbody><tr valign="top">
                            <td class="itemlabel"><input type="text" value="yes" name="item.Label" id="item_Label" data-val-required="Label is required" data-val="true" class="text-box single-line"><span data-valmsg-replace="true" data-valmsg-for="item.Label" class="field-validation-valid"></span></td>
                            <td style="height:40px;width:50px" class="displayimage"><img alt="" src="/content/media/yougotit.jpg?height=40&amp;width=50"></td>
                            <td class="displayimagecta">
                                <input type="image" src="/Content/img/upload.png" title="Upload" alt="Upload" name="" id="upload_11">
                                <input type="image" src="/Content/img/delete.png" title="Remove" alt="Remove" name="" id="remove_11">
                            </td>
                            <td class="isactive"><input type="checkbox" value="true" name="item.IsActive" id="item_IsActive" data-val-required="The Active? field is required." data-val="true" class="check-box" checked="checked"><input type="hidden" value="false" name="item.IsActive"></td>
                            <td class="hiddenflds">
                                <input type="hidden" value="101" name="item.ID" id="item_ID" data-val-required="The ID field is required." data-val-number="The field ID must be a number." data-val="true">
                                <input type="hidden" value="10/18/2012 6:26:53 AM" name="item.DateCreated" id="item_DateCreated" data-val-required="The DateCreated field is required." data-val="true">
                                <input type="hidden" value="27" name="item.OwnerID" id="item_OwnerID" data-val-required="The OwnerID field is required." data-val-number="The field OwnerID must be a number." data-val="true">
                                <input type="hidden" value="11" name="item.ParentID" id="item_ParentID" data-val-required="The ParentID field is required." data-val-number="The field ParentID must be a number." data-val="true">
                                <input type="hidden" value="/content/media/yougotit.jpg" name="item.MediaPath" id="item_MediaPath">
                            </td>
                            <td align="right" class="rowcta">
                                <input type="image" src="/Content/img/save.png" title="Save" alt="Save" name="" id="save_11">
                                <input type="image" src="/Content/img/cancel.png" title="Cancel" alt="Cancel" name="" id="cancel_11">
                                <input type="image" src="/Content/img/delete.png" title="Delete" alt="Delete" name="" id="delete_11">
                            </td>
                        </tr>
                    </tbody></table>
</form>            
            </td></tr>
                    </tbody></table>
</form></td></tr></tbody></table>

The main problem is the nested table in it. I fought against having a nested table but lost the fight. But that doesn’t seem to be the cause of the problem I’m describing. Maybe when I get back to work tomorrow I can start adding elements of this in to the jsfiddle example and see when the problem occurs.

Well by changing the selector so that it doesn’t target the nested table, things seem to work better with this example that involves your code

That’s where $(“#responseOptions tbody”) is instead done as $(“#responseOptions>tbody”)

Hmm, now with your new example it is working in Chrome but not in Firefox. Still testing…

Update: Works in Internet Explorer…

Well good luck with that in Firefox - here’s a tip: don’t use tables for layout.

"here’s a tip: don’t use tables for layout. "

I’m not. I’m using them to present tabular data, which is their correct and intended usage. The table I showed here is part of a much larger page that is being laid out using CSS.

And maybe there’s someone else who knows how to fix this in Firefox… ?

What’s the actual problem? As far as I can see the drag/drop functionality that Paul built actually works fine in Firefox.

The only real problem I see is that you’re hiding a <th> with CSS, Firefox might not like that.

Yeah, the back end guy is storing hidden values in that TH with .NET, or more correctly in their corresponding TD’s down below. I might try to see if there’s a better way to do it.

The problem is that in Firefox you cannot edit within the input fields in each row. The draggable/droppable part does work.

Well, seeing as they are hidden fields you do not need to dedicate an entire table cell for them and hide it, browsers will never display hidden inputs, so you can just put them right after the <form> tag for example.

I just did a quick Google and it looks like this is pretty easy to solve.

Simply remove the .disableSelection(); call at the end of Paul’s code.


$("#responseOptions>tbody").sortable({
    helper: fixHelperModified,
    stop: updateIndex
}); //.disableSelection();

Apparently it is best to only call .disableSelection() on the elements on which you don’t want a selection started but instead you want to use as a sortable handle.

Try out Paul’s more recent jsfiddle in Firefox: http://jsfiddle.net/pmw57/32EmT/ In the input fields (each one defaults to saying “yes”) the user is unable to edit anything within them but this can be done in other non-Firefox browsers such as Chrome and IE.

UPDATE: Thanks for your new response that posted just about the same time as my most recent one.

Going to try to convince the back end programmer that that is what we should do.

An update to the jsfiddle test is at http://jsfiddle.net/pmw57/32EmT/1/ which should now work better with Firefox

Thanks, Paul.

Okay, now I am implementing this on some TEXTAREA’s that are in the rows that are draggable and sortable and these TEXTAREA’s have the jHtmlArea plugin applied. The only problem is that once you begin dragging them they lose all the data that was in the IFRAME that the plugin masks over the associated TEXTAREA. The .clone method is still being used but on its own it doesn’t carry all the data over with it and even setting it to .clone(true) or .clone(true, true) does not preserve the data on drag. Example:

Is there any way to preserve the content?