How to show wait message that is used by actions

  • 3
  • Question
  • Updated 4 months ago
  • Answered
I have some remoting calls that tend to take a bit of time to complete. I would like to display the same blocking ui message that is used by actions. How would I do that using javascript?

Just for some background I have to do some additional processing after the response that I need to perform which could result in additional remoting calls so I can't simply just use a button and action to make the call. I need control over when to start showing the message and when to hide it. 
Photo of John De Santiago

John De Santiago

  • 120 Points 100 badge 2x thumb

Posted 4 years ago

  • 3
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
Skuid's waiting messages use the jQuery blockUI plugin, which you can access via Skuid's jQuery using skuid.$.blockUI, skuid.$.unblockUI:

var $ = skuid.$;
// To start showing the message
$.blockUI({
   message: 'Doing something crazy asynchronous...'
});
setTimeout(function(){
    // Turn off the block UI
    $.unblockUI();
},5000);

To make a message that goes away after 3 seconds, use the timeout property:

$.blockUI({
   message: 'There was a problem with our asynchronous insanity. It was this: ',
   timeout: 3000
});
Photo of John De Santiago

John De Santiago

  • 120 Points 100 badge 2x thumb
Awesome. Thanks. That will work for me. 
Photo of Peter Bender

Peter Bender, Champion

  • 6,246 Points 5k badge 2x thumb
Does this not work anymore? I can't get the sample code to do anything at all in my instance.
Photo of John De Santiago

John De Santiago

  • 736 Points 500 badge 2x thumb
It should still work. I still use this extensively and have used it with the current and recent superbank release in a dev environment.

Maybe if you have a snippet I look at it and see if something jumps out about why it isn't working of for you.
Photo of Peter Bender

Peter Bender, Champion

  • 6,246 Points 5k badge 2x thumb
Here's the button javascript I'm using, but adding the "blockUI" code doesn't seem to do anything at all.

var params = arguments[0],
    row = params.item.row,
    classModel = params.model,
    classID = classModel.getFieldValue(row, 'Id'),
    $ = skuid.$,
    stuModel = skuid.model.getModel('Student'),
    stuID = stuModel.getFieldValue(stuModel.getFirstRow(),'Id');

$.blockUI({ message: 'Enrolling...' });

var enrModel = skuid.model.getModel('Student Enrollment');
var enrRow = enrModel.createRow({
    additionalConditions: [
        {field: 'Enrollment_Status__c', value: 'Pending'},
        {field: 'Student__c', value: stuID},
        {field: 'Class__c', value: classID}
    ]
});

enrModel.save({callback: function(result){
    if (result.totalsuccess) {

        enrModel.updateData();
    } else {
        console.log(result.insertResults);
        console.log(result.updateResults);
        console.log(result.deleteResults);      
    }
}});

$.unblockUI();
(Edited)
Photo of John De Santiago

John De Santiago

  • 736 Points 500 badge 2x thumb
You might need to put the $.unblockUI(); inside your save callback method. The save method runs asynchronously so save is called and then your message is hidden. If you put it inside the callback function you should get better results.
Photo of Peter Bender

Peter Bender, Champion

  • 6,246 Points 5k badge 2x thumb
Yup, that did it, thanks!
Photo of Eric Tuggle

Eric Tuggle

  • 332 Points 250 badge 2x thumb
I've been having an issue where the blocking of the UI is delayed when a table row action is applied.  I looked for and found this solution to try and moved the blocking action inside the snippet rather than a standard block action on the "mutiple row action" that proceeds the snippet action call.

While it does work, I have the same issue of a delay where it actually completes the actions within the snippet and then blocks....not exactly very useful.  So my expectation is an "immediate blocking" occurs and then start the work that the snippet is to do.

I have a specific application using custom objects so you cannot run the snippet....but if you did, you'd see that the updates to the tables have completed (italics since I do not save) and then the UI is blocked.  This is about 1/3 of my overall snippet so there are two other updates and one row creation so the gap between seeing updates/row creation and the start of blocking the UI is more noticeable.  Across the entire snippet and row actions, there is no query of data or save of date...just update to records in models (these model have 1-4 records) and create rows.  So this is typically really fast and so I started with no blocking...however, there is a risk of click happy users doing so on row actions multiple times.

if helpful in offering feedback, I could point this snippet to a standard model and fields to make it clearer and to have the option to execute.

var params = arguments[0],$ = skuid.$;

// To start showing the message
$.blockUI({
   message: 'Doing something crazy asynchronous...'
});
setTimeout(function(){
    // Turn off the block UI
    $.unblockUI();
},5000);

var model = params.model,
list = params.list,
selectedItems = params.item ? [params.item] : list.getSelectedItems();

var SelectDJModel = skuid.model.getModel('SelectedJob');
var SelectDJRow = SelectDJModel.getFirstRow();

SelectedDJ_GroupID = SelectDJModel.getFieldValue(SelectDJRow, 'Group_Id__c', true);
SelectedDJ_TotalLength = SelectDJModel.getFieldValue(SelectDJRow, 'Total_Job_Length__c', true);
SelectedDJ_TubeDJ = SelectDJModel.getFieldValue(SelectDJRow, 'DJ_Child_Name__c', true);

//Grab key values for the selected tube DJ...where action is initiated....
//then update record to tie it to consolidated tube DJ and relink
$j.each(selectedItems,function(i,item){    
    ReplacedGroupID = model.getFieldValue(item.row, 'Group_Id__c');
    ReplacedTubDJ = model.getFieldValue(item.row, 'DJ_Child_Name__c');
    ReplacedParentDJ = model.getFieldValue(item.row, 'DJ_Parent_Name__c');
    ReplacedJobLength = model.getFieldValue(item.row, 'Job_Length__c');
    ReplacedTotalJobLength = model.getFieldValue(item.row, 'Total_Job_Length__c');
    ReplacedTotalJobLength = ReplacedTotalJobLength - ReplacedJobLength;
    SelectedDJ_TotalLength = SelectedDJ_TotalLength + ReplacedJobLength;
    
    model.updateRow(item.row, {
    Group_Id__c : SelectedDJ_GroupID,
    DJ_Interface_Status__c : 'Submitted:Create DJ-DJ Link',
    DJ_Child_Name__c : SelectedDJ_TubeDJ
    });
});
Photo of Eric Tuggle

Eric Tuggle

  • 332 Points 250 badge 2x thumb
A little more info....I moved the blocking back to the row action framework and add one of my field updates before the snippet call and "seeing the simple field update and all the changes caused by the snippet" occurs after the blocking of the UI has started. So page is unblocked while action in and outside of snippet are completed..then changes are applied to the screen...then screen is block

See seq of actions:
Show Message and block UI (2 sec)
Update a field on row(2)
Run a Skuid JavaScript Snippet

I've removed the snippet and repeated this and the blocking still occurs after the update field action is complete.

it really appears as if the blocking is only useful when save or requery occurs...then you can lock user out until the database level stuff is complete.
Photo of Eric Tuggle

Eric Tuggle

  • 332 Points 250 badge 2x thumb
Last update and then I'll give someone else a chance....  I've added a query of a small model for a single record (so price is not too high) and the blocking occurs immediately...  I then call the snippet and let it unblocks at the end so this achieves my objective.  I'd still appreciate either an explanation or an alternative solution that could eliminate the small model query.

See seq of actions:
Show Message and block UI (10 sec)
Query Model
Run a Skuid JavaScript Snippet
Photo of Praveen Pannala

Praveen Pannala

  • 580 Points 500 badge 2x thumb
Am trying this, but not sure why this is not working. I do not get any loading icon


var params = arguments[0],
   $ = skuid.$;
var count = 0;
var triggerModel = params.model;
var triggerConditions = triggerModel.conditions;
var allModels = skuid.model.getModelsList();
$.blockUI({
   message: 'Doing something crazy asynchronous...'
});
//iterate though all the page models
$.each(allModels, function(i, model) {
    //&& triggerModel.id !== model.id
    if (triggerModel.objectName == model.objectName ) { //make sure we're only concerning ourselves with like-typed models
        $.each(triggerConditions, function(j, condition) { //iterate through all the triggering model's conditions
           var conditionToUpdate = model.getConditionByName(condition.name);
           if (conditionToUpdate && (conditionToUpdate.inactive != condition.inactive || conditionToUpdate.values != condition.values)) {
               console.log('am here start');
               if (conditionToUpdate.type == 'multiple') { //use values
                   model.setCondition(conditionToUpdate, JSON.parse(JSON.stringify(condition.values))); //deep clone via JSON stringify
               } else {
                   model.setCondition(conditionToUpdate, JSON.parse(JSON.stringify(condition.value))); //deep clone via JSON stringify
               }
               conditionToUpdate.inactive = condition.inactive; //sync the active/inactive
               model.updateData(func);
           }
        });      
    }
});



function func(){
    count = count+1;
    console.log(count);
    if(count === 5){
        $.unblockUI();
    }
}
Photo of Praveen Pannala

Praveen Pannala

  • 580 Points 500 badge 2x thumb
I figured, i have to use jquery promises to complete this.