asp.net usercontrol won't fire javascript inside updatepanel
Asked Answered
N

5

8

I've seen similar issues to this and answers but none seem to fix the issue.

I have a user control inside an update panel. Inside my user control I output javascript.

The javascript will not fire when triggered. If I move the javascript to the parent page outside of the usercontrol/updatepanels then it fires. This doesn't make sense to do this as I can't use this usercontrol on another page without either duplicating code...by either duplicating the entire javascript (different site) or adding references to a .js file in every page it's used on (same site). It's just less portable

I merely want to output the javascript with the control (inside the update panel).

The updatepanel is mentioned for accuracy of what I'm doing. It doesn't work even if I place the usercontrol outside of updatepanels.

Keeping it simple (This does not work for me):

USERCONTROL:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="_location.ascx.cs" Inherits="_location" %>
<script type="text/javascript">
    function test() {
        alert('Hello World!');
    }
</script>

<a href="javascript:void(0);" onclick="javascript:test();">
    Find For Me
</a>

PARENT:

<uc1:_location runat="server" ID="_location"  />

Debugging in chrome tells me "Uncaught ReferenceError: test is not defined"

If I add the javascript directly to the onclick as below, it works:

onclick="alert('Hello World!');"

And as stated above, moving the function to the parent page ALSO works.

It's as if the browser ignores the script output from the user control.

Any ideas?

Nino answered 13/4, 2013 at 14:1 Comment(2)
Your code works fine for me.Harquebusier
@Harquebusier This code will not work if you call it and update it from inside an UpdatePanel.Domesticity
D
6

When you have an UpdatePanel and that UpdatePanel updates it's content, it treats it's content as simple text/html (not code), it does not have any parser available to run the script and make it available for the page.

So this content,

<script type="text/javascript">
    function test() { alert('Hello World!'); }
</script>

<a href="javascript:void(0);" onclick="javascript:test();">
    Find For Me
</a>

after client side code of update panel runs and updates content of the page, the script part is not parsed - its simple text/html for the page.

This part however runs

<a href="javascript:void(0);" onclick="alert('Hello World!');">Find For Me</a>

because the parse of the onclick attribute is done when you click on it.

There are following workarounds available:

  1. Move your javascript into external file
  2. Move you script outside of the UpdatePanel
  3. Register the script in the code behind with RegisterClientScriptBlock or alternative functions.
Domesticity answered 13/4, 2013 at 14:21 Comment(3)
This is not really much different than the way I stated did work in my question. If I have to put the script outside the updatepanel then I'm forced to include it on the parent page... My usercontrol is inside an updatepanel on the parent page... and yes, putting the script outside that updatepanel works just fine even without using a registerclientscriptblock... While this works, it's less than desirable. Certainly MS has provided a way to include javascript inside a usercontrol for, if nothing else, portability.Nino
@AdamWood You can register the script on code behind. The different in my answer to your question, is that you do not have realize that the update it not parse and can not parse the script - and this is the key point here.Domesticity
Thx. It explains why inline-code on an UserControl within an UpdatePanel is not callable at all. It's just text. Searching for hours ...Borisborja
P
2

In Addition to the solution that Adam Wood posted, I should say that you must use ScriptManager to register the script when using update panel, at least in .net 4.0 because otherwise it won´t work.

So you can put on the PageLoad event of the usercontrol:

string script = @" alert('this is a test');
alert('it worked')";
ScriptManager.RegisterStartupScript(Page,Page.GetType(),"scriptMelhoria",script,true);
Predilection answered 1/10, 2013 at 13:11 Comment(1)
I thought this was the solution to another problem that I have. I'm trying to bind a jquery event to a control. But I receive 0x800a139e - JavaScript runtime error: Syntax error, unrecognized expression: #<%=pnDetails.ClientID%>, s for some reason I can't access my user controls in the script. (I'm trying it like this because if I place the script on my user control, which resides inside an Update Panel, my script doesn't fire at all).Magdalenmagdalena
N
1

Thanks to Aristos for sending me down the right path... Though his solution works, it did not answer the question of outputting the javascript from inside the usercontrol but instead suggested moving it outside. This was not the desired outcome, as stated, as it's not kept inside the control for easier portability.

Here is my solution that accomplishes this: CS file:

String script = "<script type=\"text/javascript\">";
script += "function test() {";
    script += "alert('Hello World!');";
script += "</script>";

Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "locationScript", script);

One might use a stringbuilder if script is longer, but eitherway works.

This keeps the code entirely inside the usercontrol and it works from the onclick event of the a tag.

Nino answered 13/4, 2013 at 15:12 Comment(0)
U
0

Try this;

You can find your script elements after udpdate panel callback and evaluate them.

Add a special attribute to your inline script tag to select elements after callback request.

<script type="text/javascript" data-tag='myscript'>
    function test() {
        alert('Hello World!');
    }
</script>

And add this script to your update panel container aspx file.

<script>

        if (Sys !== undefined) {
            var prm = Sys.WebForms.PageRequestManager.getInstance();
            prm.add_endRequest(endPostbackRequest);
        }

        function endPostbackRequest(sender, args) {
            $("script[data-tag='myscript']:not([data-run])").each(
                function () {
                    eval.apply(window, [$(this).text()]);
                    $(this).attr('data-run', '1');
                });
        }

</script>
Unbearable answered 5/5, 2017 at 8:46 Comment(0)
C
-1

Preferred way of dealing with javscript code that is bound to DOM elements within UpdatePanel is to subscribe to endRequest event of PageRequestManager and execute your code here. For instance you want to set click event handlers here.

// that is standard way for asp.net to execute JS on page load
// pretty much the same as $(function(){ ...}) with jquery
function pageLoad() {
    // find PRM instance and subscribe to endRequest
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);
}

function endRequest() {
    // set all handlers to DOM elements that are within UpdatePanel
    $('<%= myButton.ClientID %>').on('click', test)
}

function test(e) {
   alert('Hi')
}

Alternative solution will be to use event delegation like so:

function pageLoad() {

    // delegate click event on .myButton inside .container
    // to the .container DOM element
    $('.container').on('click', '.myButton', test)

}

And have div with a class named container around your update panel. In this case your div.container is never removed from DOM so all event handlers on it will hold after partial postbacks.

Same code without jquery and using only asp.net ajax will look like this:

function pageLoad() {
   Sys.UI.DomEvent.addHandler($("myContainer"), "click", delegatedTest);
}

function delegatedTest(e) {
   // since asp.net ajax does not support event delegation
   // you need to check target of the event to be the right button 
   if (e.target.id == "myButton") test(e)
}

function test(e) {
   alert("HI")
}
Charleencharlemagne answered 13/4, 2013 at 14:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.