Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

Got a placed called 'SiteAssets/test.js' with the function test(). I've created a nonvisual webpart, would like the script via the cs file and then run the function during the loading of the webpart.

I'm surprised by how difficult this has proven. Seems like there is a huge array of possible ways to do this. Tried a bunch of methods but they either seem to fail in the sandbox or I can't get them working at all.

Should I register the script via a writer or ClientScript.RegisterClientScriptBlock or something else? And how should I make sure that the javascript runs when the webpart loads? _spBodyOnLoadFunctionNames.push("test") or SP.SOD.registerSod('test.js', 'SiteAssets/test.js') or some variant of ExecuteOrDelayUntilScriptLoaded that waits for sp.js or a similar script?

share|improve this question
add comment

3 Answers 3

I'll try to summarize this article written by a respected and knowledgeable member of the community, but I'd read this if you want a more in-depth coverage on this topic:

http://blog.mastykarz.nl/dynamically-loading-javascript-sandbox/

I don't think you can use the Register Client scripts (in a Sandbox scenario) on the server side because of the limitations of the Sandbox.

So, yes, you must register them another way. How you register depends...on what you are trying to do in your test() javascript method. If you are relying on functionality exposed by other javascript files, then yes, it'd be appropriate to use the SP.SOD (script on demand) framework to setup dependencies on your file with other files. For example, if your test() method is trying to leverage the Javascript Client Object Model, for example to read contents of a list, then you would use the ExecuteOrDelayUntilScriptLoaded() method like so:

ExecuteOrDelayUntilScriptLoaded(test(), "sp.js");

BTW...ExecuteOrDelayUntilScriptLoaded() is just a part of the SOD framework and is loaded by init.js. If your test() method is relying on functionality exposed by your own scripts (i.e. not SharePoint provided scripts, for example jQuery), then you can also use the SOD framework, but you must ensure that your custom script file is setup to participate in it. You do this by putting a call to NotifyScriptLoadedAndExecuteWaitingJobs() at the end of your file, which lets the SOD framework know that your file has finished loading, and any dependent scripts can now run.

Here is another good resource covering SOD: http://spblog.net/post/2012/01/20/SharePoint-2010-Script-On-Demand%E2%80%93give-my-script-right-now!.aspx

share|improve this answer
add comment

there is one problem in the solution that is provided by Anders Aune. If you add several web parts on the page, you will have several scripts on the page. It is not a good solution. You can use this open source project to solve your problem.

Or write something like this

function loadFile(filename, filetype) {
    var element = document.getElementById(filename);
    if (element == null) {
        var fileref = null;
        if (filetype == "js") {
            fileref = document.createElement('script');
            fileref.setAttribute("type", "text/javascript");
            fileref.setAttribute("src", filename);

        }
        else if (filetype == "css") {
            fileref = document.createElement("link");
            fileref.setAttribute("rel", "stylesheet");
            fileref.setAttribute("type", "text/css");
            fileref.setAttribute("href", filename);
        }
        if (typeof fileref != null) {
            fileref.setAttribute("id", filename);
            document.getElementsByTagName("head")[0].appendChild(fileref);
        }
    }
}

then load this JS and register this function to be run on document ready like Anders Aune said. In this case you have several references to this function, but you have single instance of a JS file.

share|improve this answer
    
That's a good point :) I have only used it some special cases, so didn't have to worry about scripts all over the place. –  Anders Aune Apr 4 '12 at 13:26
    
You have only used it some special cases... but what about another person that will use your solution? it is a joke –  Alexander Apr 4 '12 at 13:29
    
Ofc there would have been an issue if another person would use it(Not that would have happened in the said case). But thanks for sharing, one learns something everyday :) –  Anders Aune Apr 4 '12 at 13:36
add comment

When I had to do this last time I added it in the Render:

protected override void Render(HtmlTextWriter writer)
{
 writer.Write("<script language='javascript' type='text/javascript' src='urlToYour.js'></script>");
}
share|improve this answer
    
Works! Had to add base.Render(writer) , otherwise controls created in CreateChildControls() wouldn't show. Also added _spBodyOnLoadFunctionNames.push("test"); to the top of my js-file to make it run after the webpart loaded. –  Drkawashima Apr 4 '12 at 12:26
    
Yeaj, I usually use $(document).ready(function() or ExecuteOrDelayUntilScriptLoaded –  Anders Aune Apr 4 '12 at 13:22
    
While this answer may work for the simplest of examples, I would not recommend doing it this way. First problem, overriding Render(). Unless you explicitly do so, overriding Render() will not create the web part chrome (borders). A more appropriate method to override would be RenderContents(). Another problem with this approach is, as Alexander points out, if you have multiple instances of this web part on a page, you have redundant references to the same .js file, which could result in unpredictable results. –  Brian Apr 4 '12 at 13:49
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.