Question

I have some code using the javascript object model to get items for several dropdown boxes on a form. I also heard that using Promises was the way to go for speeding up things and created 2 wrapper functions. The first one is using the object model to get items from a list and this is wrapped in a Promise with jQuery (.when). The second one fills the dropdown boxes(.then). There are several calls that are made using the .when and .then architecture. These work great and all the dropdowns get loaded. The issue is that no matter what method I try, I can't inform the user with an animation that the code is indeed running. The addwaitscreenwithnoclose function does start fine, but the image freezes and looks unprofessional. Hours of research has led me to try many options, but none of them work as it has been shown that the long calls by default will freeze the UI. I get that, but it just seems odd that you can't let the user know it is working. My form pops up so fast that the out of box loader is never seen because my form is loaded via the object model. Just wondering if anyone has created a solution or has an idea of what might work. I am not sure that I can post the code yet, but if it is needed I may be able to make it available.

[Code was removed due to client concerns...]

This is good stuff and for what it does is fast, but still takes about 5 seconds to maybe 8 seconds to load and users do not know that it is doing anything when the image freezes. My best attempt so far is using setInterval to draw a colored div across the page, but it too of course freezes due to the longer code...

UPDATE: As an FYI, this code is on a page that is opened in the SP.UI.ModalDialog. It is a custom page where the form is written as an html file that includes the javascript file in a script tag. This html file is the source of a Content Editor Web Part on the page that gets opened in the dialog. The dialog opens very quickly but the data does take some time...

Was it helpful?

Solution

I'm not sure what you mean with freeze, but I can't see where you call or close the "working on it". I made simple example with dummy code, maybe it will help you. Because I have never seen that async calls have locked the UI etc, so you could try this approach:

SP.UI.ModalDialog.showWaitScreenWithNoClose("title", "message", 400, 400);

var dummyExecuteQueryAsync = function(func) {
    func();
}

var AMO = window.AMO || {};
AMO.csom = AMO.csom || {};
AMO.upload = AMO.upload || {};

AMO.csom.GetLookupData = function () {

    var getvalues = function () {
        var deferred = $.Deferred();
        setTimeout(function() {
            dummyExecuteQueryAsync(Function.createDelegate(this, function () { deferred.resolve( "Done: " ); }));   
          },  500 + Math.random() * 3000  );
        return deferred.promise();
    };

    return {
        getvalues: getvalues
    }

}();


AMO.csom.FillDropdowns = function (msg, no) {
    console.log(msg + no);
}


function GetLookupValues() {
    var defferedArr = [];
    defferedArr.push( $.when(AMO.csom.GetLookupData.getvalues())
        .then( 
            function (items) { AMO.csom.FillDropdowns(items,1); } 
        )
    );

    defferedArr.push(  $.when(AMO.csom.GetLookupData.getvalues())
        .then( 
            function (items) { AMO.csom.FillDropdowns(items,2); } 
        )
    );

    defferedArr.push(  $.when(AMO.csom.GetLookupData.getvalues())
        .then( 
            function (items) { AMO.csom.FillDropdowns(items,3); } 
        )
    );

    defferedArr.push(  $.when(AMO.csom.GetLookupData.getvalues())
        .then( 
            function (items) { AMO.csom.FillDropdowns(items,4); } 
        )
    );


    return defferedArr;
}


var def = GetLookupValues();
$.when.apply(null, def).done(function() {
        console.log("All done");
        SP.UI.ModalDialog.commonModalDialogClose();
    });

OTHER TIPS

We have used Spin.js in several such scenarios.

Usage

Define a <div> in the HTML markup

<div id="userTableSpinner"></div>

Then in Javascript code find the div and start spinner and finally stop it once all processing is done:

var userTableSpinner;
function someProcessStartsHere() {
if (userTableSpinner == null) {
    userTableSpinner = new Spinner().spin(document.getElementById('userTableSpinner'));
    }
    else {
        userTableSpinner.spin(document.getElementById('userTableSpinner'));
    }


    // JS Code

    //Finally stop processing
    if (userTableSpinner != null) {
        userTableSpinner.stop();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top