Sort Table with Drag and Drop

Finally implemented jQuery .sortable() to enable drag-and-drop reordering on a skuid table. turned out to be much simpler than I expected! 

I have an Order__c field on the object which starts at index 1, and I’m just updating that field after every reorder.

Here’s my inline javascript:

(function(skuid){
var $ = skuid.$;
$(document.body).one(‘pageload’,function(){
var component = skuid.$C(‘MyComponentId’),
   listContents = component && component.element.find(’.nx-list-contents’);
listContents.sortable({
   placeholder: “ui-state-highlight”,
   stop: function( event, ui ) {
       var data = ui.item.data(‘object’),
           model = data.list.model,
           movedRow = data.row,
           target = $(event.target);
       
       target.children().each(function(index,tr){
           var row =  $(tr).data(‘object’).row,
               order = row.Order__c;
          if (index + 1 !== order) {
              model.updateRow(row,‘Order__c’,index+1,{initiatorId:component._GUID});
          }
       });
           
   }
});
});
})(skuid);

Here’s the table in action:

Very slick. Going to use this for sure!

The one problem with this solution is that it makes tables with textareas in them uneditable or selectable.

Hmm, even if you click on the ‘edit’ row action?

Yes, it blocks the rich text panel that comes up.

I love this and can work around the inline editing of the text. Thanks!

Matt~

This is very cool!

Thanks for sharing with the community :slight_smile:
Karen

Karen, can you file the rich text issue as a bug with skuid?

Works great. I additional save the model after setting the index.

// Sprint Work Drag &amp; Drop reorder var component = skuid.$C('sk-39dlIj-483'), listContents = component &amp;&amp; component.element.find('.nx-list-contents'); listContents.sortable({ placeholder: "ui-state-highlight", stop: function( event, ui ) { var data = ui.item.data('object'), model = data.list.model, movedRow = data.row, target = $(event.target); target.children().each(function(index,tr){ var row = $(tr).data('object').row, order = row.Sprint_Rank__c; if (index + 1 !== order) { model.updateRow(row,'Sprint_Rank__c',index+1,{initiatorId:component._GUID}); } }); <b> $.blockUI(); $.when( model.save() ) .done(function(){ $.unblockUI(); }); </b> } });<br>

John~

Clarification question: Is this specific to when you use Matt’s snippet or to tables in general? 

Thanks!
Karen

This is anytime you apply a JQuery UI sortable to a skuid table.

John,

Have you tried tabbing over to the rich text area? 

Thanks!
Amy

You can tab over but you can’t click into it. It’s not really an acceptable solution to train users to do this.

I found a workaround for the rich text issue: use a handle for the sortable action. Add a row action with no actions and put in the class of the icon. Here is code with the handle, save and requery: (function(skuid){ var $ = skuid.$; $(document.body).one(‘pageload’,function(){ var component = skuid.$C(‘johntt’), listContents = component && component.element.find(’.nx-list-contents’); listContents.sortable({ placeholder: “ui-state-highlight”, handle: ‘.fa-ellipsis-v’, stop: function( event, ui ) { var data = ui.item.data(‘object’), model = data.list.model, movedRow = data.row, target = $(event.target); target.children().each(function(index,tr){ var row = $(tr).data(‘object’).row, order = row.Order__c; if (index + 1 !== order) { model.updateRow(row,‘Order__c’,index+1,{initiatorId:component._GUID}); } }); $.blockUI(); $.when(model.save()).done(function(){ model.updateData(function(){ $.unblockUI(); }); }); } }); }); })(skuid);

Clever workaround! I like it

John,

I’m glad you found a workaround, and thanks for sharing it with the community!

Thanks!
Amy

Perfect! I’m definitely implementing the handle. Thanks, John!

I took this and made a super fancy version :D

Going further down the fancy rabbit hole I used this http://tobiasahlin.com/spinkit/ to put in a css based spinner

Matt, this is cool. Will come in very handy