1

I am trying to run a piece of javascript after the page loads:

    protected void Page_LoadComplete(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            string controlName = getPostBackControlName();
            if (controlName == "btnSubmit" || controlName == "ddlSalary")
            {
                Page.ClientScript.RegisterStartupScript(GetType(), "myAlertScript", "onLoadDisplay(this)", true);
            }
        }
    }

Here is the referenced javascript:

    function onLoadDisplay(sender) {
        PerDiemClicked(sender);
    }

    function PerDiemClicked(sender) {
        if (document.getElementById('<%= chkbxPerDiem.ClientID %>').checked == true) {
            document.getElementById("PerDiemDisplay").style.display = 'inline';
        }
        else {
            document.getElementById("PerDiemDisplay").style.display = 'none';
        }
    }

I'm getting this error:

0x800a138f - JavaScript runtime error: Unable to get property 'checked' of undefined or null reference

I dont understand why the checked is coming back null because I am waiting for the page to complete postback before checking. How do I check this control and run the above code correctly?

edit: here is the checkbox:

<asp:CheckBox ID="chkbxPerDiem" runat="server" Checked="false" onclick="PerDiemClicked(this)" />
David Tunnell
  • 6,268
  • 17
  • 52
  • 109
  • Is that javascript on the aspx or on a separated js file? – Claudio Redi Jan 08 '15 at 20:15
  • It's currently on the aspx file. – David Tunnell Jan 08 '15 at 20:15
  • 1
    have you validated what `` renders to and if that id actually exists or not? – Claudio Redi Jan 08 '15 at 20:16
  • What is the resulting client-side code? When you debug in the browser, what does `getElementById()` return for that id? – David Jan 08 '15 at 20:17
  • I know works because I use this method when the box is checked or unchecked as well and it shows and hides the panel. – David Tunnell Jan 08 '15 at 20:19
  • 1
    @DavidTunnell: If you "know it works" then what's the question? – David Jan 08 '15 at 20:21
  • The method works fine when fired as an event from the checkbox, however i get a null reference error when run in the Page_LoadComplete method. – David Tunnell Jan 08 '15 at 20:23
  • I know this works because I've done it. We're missing some information here. Are you absolutely clear which line is causing the error? Use the browser to set a breakpoint and then inspect things to get more information. – Jonathan Wood Jan 08 '15 at 20:24
  • @DavidTunnell: What error are you actually trying to resolve here? In your last comment you say you're getting a null reference in server-side code, but in the question you post a null reference error from client-side code. Which is it? What line of code is *actually throwing the error*? – David Jan 08 '15 at 20:25
  • (document.getElementById('').checked == true) is the line throwing the error. It does not throw an error when event is fired. But it does when Page.ClientScript.RegisterStartupScript(GetType(), "myAlertScript", "onLoadDisplay(this)", true); is added to the Page_LoadComplete method. – David Tunnell Jan 08 '15 at 20:25
  • @DavidTunnell: That's a client-side error then, it's *not* happening in `Page_LoadComplete`. Since it's a client-side error, what is the rendered *client-side code* which throws the error? Not what do you assume it is, but what is it actually? When you debug that code in the web browser (by putting a break point on that line), what does `getElementById()` return? We can't debug this for you, you need to provide information. – David Jan 08 '15 at 20:28

3 Answers3

2

Your script likely executed before chkbxPerDiem was added to the DOM. Perform your script in the window load event:

window.addEventListener("load", function() {
    onLoadDisplay(this);
});

Try this:

Page.ClientScript.RegisterStartupScript(GetType(), "myAlertScript", @"        
window.addEventListener('load', function() {
    onLoadDisplay(this);
});", true);

See this answer

Community
  • 1
  • 1
canon
  • 37,149
  • 9
  • 67
  • 92
  • getting the same exception: 0x800a138f - JavaScript runtime error: Unable to get property 'checked' of undefined or null reference – David Tunnell Jan 08 '15 at 20:34
  • (document.getElementById('ContentPlaceHolderBody_chkbxPerDiem').checked == true) – David Tunnell Jan 08 '15 at 20:38
  • 1
    @canon: This is a standard ID in ASP.NET. The prefixed text in the ID refers to the containing controls to ensure the actual ID is unique on the page. – Jonathan Wood Jan 08 '15 at 20:41
  • @DavidTunnell: Keep in mind that JavaScript is interpreted in the order it's found on the page. When this line of code executes, does `ContentPlaceHolderBody_chkbxPerDiem` exist yet? If it hasn't been rendered to the page yet then `getElementById()` will return `null`, which is the behavior you're seeing. (And what this answer proposes to resolve.) – David Jan 08 '15 at 20:42
  • @canon: Well, *you* are. But the OP isn't :) – David Jan 08 '15 at 20:44
  • @canon: Here's hoping. All in all I'm just trying to help explain the issue to the OP so his problem can be resolved. – David Jan 08 '15 at 20:46
0

Page_LoadComplete is a server-side event, and all server-side events will run before the page is even sent to the browser. Remember, these server-side events are related to constructing the page. You need to run your JavaScript after the page has been constructed, served, and fully loaded by the browser. This means the Page_LoadComplete event runs long before your JavaScript code can run.

Page.ClientScript.RegisterStartupScript(GetType(), "myAlertScript", "onLoadDisplay(this)", true);

The code above registers a call to your JavaScript load function. But it will insert the call to that function at the top of your page. So it will run before the rest of the page is loaded.

You need to review how ASP.NET events work. Again, all of the server-side events run before the page is even sent to the browser. The JavaScript shouldn't run until after the browser has received and loaded the page.

Jonathan Wood
  • 59,750
  • 65
  • 229
  • 380
  • If someone is going to downvote an answer, please try and have the guts to state what your complaint is. I don't understand why this was downvoted. It addressed a fundamental misunderstanding that the OP appeared to be expression. – Jonathan Wood Jan 09 '15 at 05:32
0

Here is how I solved it.

This code does in fact post after page load:

    protected void Page_LoadComplete(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            string controlName = getPostBackControlName();
            if (controlName == "btnSubmit" || controlName == "ddlSalary")
            {
                Page.ClientScript.RegisterStartupScript(GetType(), "myAlertScript", "window.addEventListener('load', function() { onLoadDisplay(this); });", true);
            }
        }
    }

I had to modify the javascript function to check if it exists before checking whether its checked:

    function PerDiemClicked(sender) {
        if (document.getElementById('<%= chkbxPerDiem.ClientID %>') != null) {
            if (document.getElementById('<%= chkbxPerDiem.ClientID %>').checked == true) {
                document.getElementById("PerDiemDisplay").style.display = 'inline';
            }
            else {
                document.getElementById("PerDiemDisplay").style.display = 'none';
            }
        }
    }

Thanks everyone.

David Tunnell
  • 6,268
  • 17
  • 52
  • 109
  • 1
    If that-null check was necessary after moving code to the load event, I can only surmise that you have something which toggles the [`Visible`](http://msdn.microsoft.com/en-us/library/system.web.ui.control.visible%28v=vs.100%29.aspx) property of the server control or a parent thereof... – canon Jan 08 '15 at 20:49