Refresh model in Drag and Drop Queue items after drop

  • 1
  • Question
  • Updated 4 years ago
  • Answered
I'm really digging the "Drag and Drop Queues".  This has been a huge addition to our sales management process.  

However, I'd like to be able to  automatically refresh the Record data to reflect the changes after the item has been dropped to a new Queue.   

Below is our Opportunity Wall showing 5 stages and the corresponding Opportunities:




Note that each Opportunity Card has the Stage Name and the Value.  If the Opportunity Card is dropped into a new Stage as follows:



The Stage name and Value is changed in the record itself (I confirmed this by opening the updated opportunity in a new window and saw that the Stage name had indeed changed), even though my Opportunity Card doesn't display this change automatically.  


As a workaround, I created a Page Title button that simply re-Queries all of the models on my page.  The button works as intended:



My question is this:  Is there a way to include a function in my In-line Resource "Make Queue Contents Droppable" to either 1) re-query all of the models on my page or 2) at least re-query the Opportunity Model so that the Opportunity Card updates with the new value?  

Here is the source of my "Make Queue Contents Droppable" (should be the same one from the tutorial.

(function(skuid){
   
   // Global setting -- if true, then all changes will be immediately saved,
   // otherwise, changes will remain unsaved until you click Save.
   var SAVE_IMMEDIATELY = true;
    
   var $ = skuid.$;
   
    var getQueueList = function(queueElement){
        var queueList;
        $.each(skuid.model.list(),function(i,model){
           $.each(model.registeredEditors,function(){
              if (this.element && this.element.is && this.element.is(queueElement)) {
                  queueList = this.lists[0];
                  return false;
              } 
           });
           if (queueList) return false;
        });
        return queueList;
    };
   
   $(document.body).one('pageload',function(){
      $('.nx-queue').each(function(){
         var queue = $(this);
         var listContents = queue.find('.nx-list-contents');
         listContents.droppable({
            hoverClass: 'ui-state-highlight',
            accept: function(draggables) {
                // Do not accept draggables
                // that came from this list
                return (!listContents.is($(draggables[0]).data('listContents')));
            },
            drop: function(e,ui){
                var draggable = ui.draggable;
                
                var sourceItem = draggable.parent().data('object');
                
                // You will get a jQUery UI bug unless you detach the draggable.
                // We wait until now to detach in order to get a 
                draggable.detach();
                
                var sourceRow = sourceItem.row;
                var sourceRowId = sourceRow.Id;
                var sourceList = sourceItem.list;
                var sourceModel = sourceItem.list.model;
                
                var targetList = getQueueList(queue);
                var targetModel = targetList.model;
                
                targetModel.adoptRow(sourceRow);
                sourceModel.removeRowById(sourceRowId);
                
                var targetRow = targetModel.getRowById(sourceRowId);
                
                // Find the first Condition in our target Model,
                // and apply it to our target row.
                // (that is, change the Stage of the dragged Opportunity)
                var targetModelCondition = targetModel.conditions[0];
                targetModel.updateRow(
                    targetRow,
                    targetModelCondition.field,
                    targetModelCondition.value
                );
                
                if (SAVE_IMMEDIATELY) {
                    targetModel.save();
                }
                
                // Re-render just the Source List and the Target List
                sourceList.render();
                targetList.render();
                
            }
         });
      });
   });
   
})(skuid);



Again, everything is working just fine, this would just make this solution much slicker.  

Thanks!

Gary
Photo of Gary Bailey

Gary Bailey

  • 1,648 Points 1k badge 2x thumb
  • Happy, but hungry for a slicker function

Posted 4 years ago

  • 1
Photo of Gary Bailey

Gary Bailey

  • 1,648 Points 1k badge 2x thumb
I thought I could just add " targetModel.updateData();" in my javaScript resource but I'm continually reminded that I know very little about javaScript.  I've tried hacking my way through but still can't get it to work.  

 = fail
Photo of Matt Sones

Matt Sones, Champion

  • 31,500 Points 20k badge 2x thumb
Not sure if this is the best way to go, but you probably just need to wait for the save to complete before the query operation:
$.when(targetModel.save()).then(targetModel.updateData());

Theoretically, you should be able to subsequently remove targetList.render(), since a query against a model will automatically re-render components registered to that model.
Photo of Gary Bailey

Gary Bailey

  • 1,648 Points 1k badge 2x thumb
At what line would I put that code?  

I tried inserting it at line 67 (replacing "targetModel.save();") but this is the error I received:

Photo of Matt Sones

Matt Sones, Champion

  • 31,500 Points 20k badge 2x thumb
Gary,

What line is throwing that error? Apparently something is trying to query the QualifiedSuspect model while it has unsaved changes.

you should be able to replace lines 67 and 68 of your pictured code with the $.when/then statement. Like so:

(function(skuid){   
   // Global setting -- if true, then all changes will be immediately saved,
   // otherwise, changes will remain unsaved until you click Save.
   var SAVE_IMMEDIATELY = true;
    
   var $ = skuid.$;
   
    var getQueueList = function(queueElement){
        var queueList;
        $.each(skuid.model.list(),function(i,model){
           $.each(model.registeredEditors,function(){
              if (this.element && this.element.is && this.element.is(queueElement)) {
                  queueList = this.lists[0];
                  return false;
              } 
           });
           if (queueList) return false;
        });
        return queueList;
    };
   
   $(document.body).one('pageload',function(){
      $('.nx-queue').each(function(){
         var queue = $(this);
         var listContents = queue.find('.nx-list-contents');
         listContents.droppable({
            hoverClass: 'ui-state-highlight',
            accept: function(draggables) {
                // Do not accept draggables
                // that came from this list
                return (!listContents.is($(draggables[0]).data('listContents')));
            },
            drop: function(e,ui){
                var draggable = ui.draggable;
                
                var sourceItem = draggable.parent().data('object');
                
                // You will get a jQUery UI bug unless you detach the draggable.
                // We wait until now to detach in order to get a 
                draggable.detach();
                
                var sourceRow = sourceItem.row;
                var sourceRowId = sourceRow.Id;
                var sourceList = sourceItem.list;
                var sourceModel = sourceItem.list.model;
                
                var targetList = getQueueList(queue);
                var targetModel = targetList.model;
                
                targetModel.adoptRow(sourceRow);
                sourceModel.removeRowById(sourceRowId);
                
                var targetRow = targetModel.getRowById(sourceRowId);
                
                // Find the first Condition in our target Model,
                // and apply it to our target row.
                // (that is, change the Stage of the dragged Opportunity)
                var targetModelCondition = targetModel.conditions[0];
                targetModel.updateRow(
                    targetRow,
                    targetModelCondition.field,
                    targetModelCondition.value
                );
                
                if (SAVE_IMMEDIATELY) {
                    $.when(targetModel.save()).then(targetModel.updateData());
                }
                
                // Re-render just the Source List and the Target List
                sourceList.render();
                
            }
         });
      });
   });
   
})(skuid);
(Edited)
Photo of Gary Bailey

Gary Bailey

  • 1,648 Points 1k badge 2x thumb
Unfortunately it is still giving me the same error.  
Photo of Matt Sones

Matt Sones, Champion

  • 31,500 Points 20k badge 2x thumb
What line is throwing the error?
Photo of Gary Bailey

Gary Bailey

  • 1,648 Points 1k badge 2x thumb
In this situation, the QualifiedSuspect model is the sourceModel (that is that stage that I dragged the record from)...does there need to be something that saves the sourceModel first?  
Photo of Matt Sones

Matt Sones, Champion

  • 31,500 Points 20k badge 2x thumb
Gary,

Try this? Save both models, then query the target model and render the source list.

$.when(skuid.model.save([targetModel,sourceModel])).then(function(){
targetModel.updateData();
sourceList.render();
});
Photo of Gary Bailey

Gary Bailey

  • 1,648 Points 1k badge 2x thumb
That worked!  Here is the full snippet:

(function(skuid){
   
   // Global setting -- if true, then all changes will be immediately saved,
   // otherwise, changes will remain unsaved until you click Save.
   var SAVE_IMMEDIATELY = true;
    
   var $ = skuid.$;
   
    var getQueueList = function(queueElement){
        var queueList;
        $.each(skuid.model.list(),function(i,model){
           $.each(model.registeredEditors,function(){
              if (this.element && this.element.is && this.element.is(queueElement)) {
                  queueList = this.lists[0];
                  return false;
              } 
           });
           if (queueList) return false;
        });
        return queueList;
    };
   
   $(document.body).one('pageload',function(){
      $('.nx-queue').each(function(){
         var queue = $(this);
         var listContents = queue.find('.nx-list-contents');
         listContents.droppable({
            hoverClass: 'ui-state-highlight',
            accept: function(draggables) {
                // Do not accept draggables
                // that came from this list
                return (!listContents.is($(draggables[0]).data('listContents')));
            },
            drop: function(e,ui){
                var draggable = ui.draggable;
                
                var sourceItem = draggable.parent().data('object');
                
                // You will get a jQUery UI bug unless you detach the draggable.
                // We wait until now to detach in order to get a 
                draggable.detach();
                
                var sourceRow = sourceItem.row;
                var sourceRowId = sourceRow.Id;
                var sourceList = sourceItem.list;
                var sourceModel = sourceItem.list.model;
                
                var targetList = getQueueList(queue);
                var targetModel = targetList.model;
                
                targetModel.adoptRow(sourceRow);
                sourceModel.removeRowById(sourceRowId);
                
                var targetRow = targetModel.getRowById(sourceRowId);
                
                // Find the first Condition in our target Model,
                // and apply it to our target row.
                // (that is, change the Stage of the dragged Opportunity)
                var targetModelCondition = targetModel.conditions[0];
                targetModel.updateRow(
                    targetRow,
                    targetModelCondition.field,
                    targetModelCondition.value
                );
                
                if (SAVE_IMMEDIATELY) {
                $.when(skuid.model.save([targetModel,sourceModel])).then(function(){
                  targetModel.updateData();sourceList.render();
                });
                     
                }
                
                // Re-render just the Source List and the Target List
                sourceList.render();
                
                
                
            }
                               
         });
      });
   });
   
})(skuid);
Photo of Matt Sones

Matt Sones, Champion

  • 31,500 Points 20k badge 2x thumb
Glad you got it working, Gary!

You can remove the following lines:

// Re-render just the Source List and the Target List
sourceList.render();
You've already re-rendered the source list within the $.when/then statement.
(Edited)