Monday, December 30, 2013

_spBodyOnLoadFunctionNames.push and ExecuteOrDelayUntilScriptLoaded

SharePoint JavaScript Client Object Model: How to Use
 
_spBodyOnLoadFunctionNames.push
 
ExecuteOrDelayUntilScriptLoaded
 
SP.ClientRuntimeContext.executeQueryAsync
 


This is a blog that discusses when and how to use these important SharePoint Javascript calls.

1. _spBodyOnLoadFunctionNames.push() is SharePoint's version of jQuery's $(document).ready() or $(function(){});

It is better to use SharePoint's version than using jQuery's version.

2. _spBodyOnLoadFunctionNames.push() takes the function names as string,

For example, for self-defined function use

_spBodyOnLoadFunctionNames.push('Company.Utility.hideText');

Since the function name passed as string, it is not possible to pass parameters to the function directly. The parameters have to be passed inside the function itself.

3. If your Javascript use SharePoint Client Object Model, you need to use ExecuteOrDelayUntilScriptLoaded to delay your Client Object calls after SharePoint's core Javascript library is loaded. The function name is passed directly as parameter to the function.

ExecuteOrDelayUntilScriptLoaded(Company.Utility.showData"sp.js")

4. To pass parameters to the function calls deplayed by ExecuteOrDelayUntilScriptLoaded.

ExecuteOrDelayUntilScriptLoaded(function () { Company.ReportListView.initListView("<%=ReportName %>") }, "sp.js")

This code also shows the technique to pass server side variable value to the client script.

5. Usually you will need these two functions together to first delay the run of your script after the page is loaded and delay the run of your script after the core SharePoint JavaScript library is loaded.

<script type="text/javascript">
    if (ExecuteOrDelayUntilScriptLoaded && _spBodyOnLoadFunctionNames) {
        _spBodyOnLoadFunctionNames.push(ExecuteOrDelayUntilScriptLoaded(function () { Compnay.ReportListView.initListView("<%=ReportName %>") }, "sp.js"));
    }
</script>

6. To pass parameter to the success function of SP.ClientRuntimeContext.executeQueryAsync

    function initListView(reportName) {
        var context = SP.ClientContext.get_current();
        ... 
        context.load(items);
 
        var sender = { "items": items, "reportName": reportName };
 
        context.executeQueryAsync(function () { succeed(sender); }, failed);
    }
 
    function succeed(sender, args) {
 
         if (sender.items) {
 
            var htmlOutput = "";
            var count = sender.items.get_count();
 
            ...

 

3 comments:

  1. Ethan,

    I stumbled upon your blog while searching for leads to help me resolve a javascript /sharepoint issue I am having unfortunately it isn't a loading issue (least, not that I can tell). In my case the Javascript runs but my output is only realized when I first call a page in the site collection; any following call, be it an F5 refresh or surfing to another page in the site collection and the out put doesn't appear. I am a bit stumped as to why.

    Debuggin in IE shows me that the expected values are there but, simply don't get written to the page and I was wondering if you might have some thoughts or have possibly seen this behavior before.

    What I am doing is getting url values of the current site and site collection and modifying them into html-attribute-friendly values to be written to the body tag's class attribute so that sites throughout the collection have a consistent and nicely parsed out class values that CSS design files can easily target.

    I have a js function which I reference in a master page within the asp:ScriptManager as follows:

    asp:ScriptReference Path="<%$SPUrl:~SiteCollection/Style Library/Scripts/Conditional-CSS.js%>">

    also in this master page I call a function in the above reference through a standard script tag before the closing of the body tag like such:

    _spBodyOnLoadFunctionNames.push("speBodyClasses");
    The function speBodyClasses inside the Conditional-CSS.js file contains the following:

    function speBodyClasses(){
    var siteColClass =
    'sitecol' +
    _spPageContextInfo
    .siteServerRelativeUrl
    .replace(/\//g, "-")
    .toLowerCase()
    ;
    var siteClass =
    'site' +
    _spPageContextInfo
    .webServerRelativeUrl
    .replace(/\//g, "-")
    .toLowerCase()
    ;

    document.body.className += ' ' + siteColClass + ' ' + siteClass;
    }

    Thanks

    ReplyDelete
    Replies
    1. thank you, this article pretty helpful for me

      Delete
  2. Any alternative for SetInterval in sharepoint 2013

    ReplyDelete