1

I need to put some javascript absolutely in the <head> block of the page -- it must execute before the rest of the page because a possible outcome of the script is to redirect to a different page.

However, when I use RegisterClientScriptInclude (to put some jQuery in there) and RegisterClientScriptBlock for my code which uses the jQuery, it puts it near the top of the <body> block, and it does not execute. I can't see a way to programmatically put this javascript into the <head> block -- it must be programmatically because sometimes I don't want it there, and sometimes I do.

I've tried to see if I can directly reference Content1, the ID of the asp:Content element corresponding to the <head> block, but no go.

Just in case anyone thinks that RegisterStartupScript might work: it doesn't. It puts it lower in the <body> block than everything else. Oddly enough.

Want some code? Here:

Type csType = this.GetType();
ClientScriptManager clientScript = Page.ClientScript;

if (!clientScript.IsClientScriptIncludeRegistered(jqueryScriptName))
{
    clientScript.RegisterClientScriptInclude(jqueryScriptName, "~/Scripts/jquery-1.7.1.min.js");
}

if (!clientScript.IsClientScriptBlockRegistered(citrixDetectorScriptName))
{
    clientScript.RegisterClientScriptBlock(csType, citrixDetectorScriptName, citrixDetectorScriptText, true);
}

By popular demand, how I detect the ActiveX component. This is JScript.

try {
    var icaObj = new ActiveXObject("Citrix.ICAClient");

    var CitrixVersion = icaObj.ClientVersion.split(".");
    var MajorMinorVersion = CitrixVersion[0] + "." + CitrixVersion[1];
    if (MajorMinorVersion == "11.0") {
        // Citrix is OK
    }
    else {
        window.navigate("WrongCitrix.aspx?Citrix=" + MajorMinorVersion);
    }
}
catch (e) {

    window.navigate("NoCitrix.aspx");
}

If the ActiveX component is not present, then redirection is a page that tells the user they need to install it. If the ActiveX component is any other version than 11.0, then the redirect is to a page that explains this and how to deal with the situation (backrevving for example).

An prior check during page load checks to make sure they have Internet Explorer v4 thru v9, because any other version will not work with the product (and IE10+ will crash if it even tries to load v11.0 of the ActiveX component).

10
  • 1
    Why wait until the page is rendered and use JavaScript to redirect? Save yourself a response and use Server.Transfer in the back-end.
    – codemonkeh
    Commented Nov 19, 2013 at 22:58
  • and if user has script disabled??? makes no sense
    – charlietfl
    Commented Nov 19, 2013 at 23:04
  • I don't want to wait for the page to render, @codemonkeh, that's the issue! The javascript that goes into the head tries to detect whether a certain ActiveX component exists on the client's workstation. If it does not, the user is redirected (via window.navigate) to another page which explains the problem and provides information on how to install the ActiveX component. If the javascript is not in the head block, it doesn't execute even after the page is rendered. Commented Nov 19, 2013 at 23:07
  • 1
    @charlietfl, if the user has script disabled then they can't use the product that the page is the portal for. It's that simple. And this is a company intranet, not the public web. Our way or the highway. Sorry if that makes no sense to you, but it doesn't need to. Commented Nov 19, 2013 at 23:11
  • @Cyberherbalist my point was that by waiting to modify the JavaScript in the post-back you are rendering the page regardless (even if just the header). But I do see your point.
    – codemonkeh
    Commented Nov 19, 2013 at 23:12

3 Answers 3

3

If I understand your question, you can insert PlaceHolder control wherever you want inside the page.

<%@ Page Language="C#" AutoEventWireup="True" 
   CodeBehind="Default.aspx.cs" Inherits="WebApplicationTelerik.Default" %>
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <script type="text/javascript" 
    src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <asp:PlaceHolder runat="server" ID="PlaceHolder1"></asp:PlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
    </form>
</body>
</html>

protected void Page_Load(object sender, EventArgs e)
{
    PlaceHolder1.Controls.Add(new LiteralControl(
       "<script type=\"text/javascript\"> alert('here'); </script>"));
}
1
  • This worked wonderfully. Thanks, I had not know the PlaceHolder control could be used for this! Commented Nov 20, 2013 at 0:08
1
document.GetElementsByTagName("head")[0].appendChild( newScriptNode );

or jQuery

$("head")[0].append( newScriptNode );
1
  • Those are neat, but I run into the same problem as before, because I can't know at design time whether or not I can add the script -- and adding the script conditionally at run time using the RegisterClientScriptBlock method puts the script in the Body, not the Head of the page. Commented Nov 19, 2013 at 23:36
0

If you really must insert JavaScript into the head tag, you can just make it an ASP.NET control and insert a control into it's child collection.

E.g. In the ASPX file:

<head runat="server" id="header">...</head>

In the code behind:

header.Controls.Add(new Literal("<script type='text/javascript'>...</script>"));

Although I do think you need to think about your process, it would be more efficient to redirect the user in the back-end before the page is rendered.

Oh and RegisterStartupScript correctly places your JavaScript after your html for increased load performance.

1
  • Before the page is rendered I don't know if they have the ActiveX component installed. Until the javascript snippet I show above actually RUNS on the client, I don't know this. Unless you know a way for IIS to mind-read the client before it sends any data to it? Commented Nov 19, 2013 at 23:20

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