Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the order of registered scripts in a ScriptManager

Background

Within our master page we have a ScriptManager that looks something like this

<asp:ScriptManager ID="ScriptManager" runat="server" EnablePartialRendering="False" EnableScriptLocalization="true">
    <Scripts>
        <asp:ScriptReference Path="~/js/master.js" />
        <asp:ScriptReference Path="~/js/jquery-min.js" />
    </Scripts>
</asp:ScriptManager>

I'm registering additional scripts in nested controls on pages by doing the following

protected override void OnPreRender(EventArgs e)
{
    ScriptManager.RegisterClientScriptInclude(this, this.GetType(), "jquery-ui", "~/js/jquery-ui.js");
    base.OnPreRender(e);
}

Expected

  1. master.js
  2. jquery-min.js
  3. jquery-ui.js *

Actual

  1. jquery-ui.js *
  2. master.js
  3. jquery-min.js

Question

Is there any way to change the order the registered scripts are loaded in?

- or -

Is it possible to at least ensure the scripts that are registered in the actual ScriptManager block are registered prior to code-behind registered scripts?

like image 369
Richard Avatar asked Jun 20 '12 13:06

Richard


2 Answers

After digging a bit into ScriptManager source code we can make two useful observations:

  • Scripts added to the manager are registered on the page one by one in order they appear in the collection ScriptManager.Scripts (if you are curious - via method ClientScript.RegisterClientScriptBlock, not in the Render method or smth like that).

  • Scripts declared in the markup will be added to the collection ScriptManager.Scripts upon ScriptManager object creation.

Therefore a way to

ensure the scripts that are registered in the actual ScriptManager block are registered prior to code-behind registered scripts

is to add your scripts in controls directly into ScriptManager.Scripts collection instead of using static utility methods of ScriptManager class. Control's code sample follows:

protected override void OnPreRender(EventArgs e)
{
    ScriptManager currentScriptManager = ScriptManager.GetCurrent(this.Page);
    if (currentScriptManager != null)
    {
        ScriptReference scriptRef = new ScriptReference("~/js/jquery-ui.js");
        currentScriptManager.Scripts.Add(scriptRef);
    }
    else
    {
        this.Page.ClientScript.RegisterClientScriptInclude(
            this.GetType(), "jquery-ui", "js/jquery-ui.js");
    }

    base.OnPreRender(e);
}

One small note - as can be seen in the code sample I would recommend handle case when there is no ScriptManager on the page.

like image 115
Andrei Avatar answered Nov 18 '22 22:11

Andrei


In your pages, use <asp:ScriptManagerProxy> to register your scripts and they'll appear in the expected order. Scripts registered in code-behind are added to the script manager before the ASPX is even parsed.

like image 36
Josh M. Avatar answered Nov 18 '22 22:11

Josh M.