0

I have a webpage which dynamically loads multiple instances of the same usercontrol (.ascx) into and update panel via LoadControl on the backend. In the usercontrol, I have javascript which I want to run when the user control is finished loading. However, every time the page posts back, and a new usercontrol is added, the javascript isn't running.

I've tried adding $(this).load(function(){...}); at the beginning of the user control, but this doesn't seem to be getting hit. I've tried using RegisterStartupScript to run some script at the end of the user control's Page_Load, but this doesn't seem to be running either. I can't debug in google chrome, so I don't know.

Here's my javascript from the user control (.ascx):

<script type="text/javascript">

    // using the clientIDs as names so they only partain to this instance of sectionDetails on the facultyRequest page
    var <%=spanDateRange.ClientID%>,
        <%=aDateRange.ClientID%>, <%=aSpecificDates.ClientID%>;

    function initSection<%=ClientID%>() {
        <%=spanDateRange.ClientID%> = $('#<%=spanDateRange.ClientID%>')[0];
        <%=aDateRange.ClientID%> = $('#<%=aDateRange.ClientID%>')[0];
        <%=aSpecificDates.ClientID%> = $('#<%=aSpecificDates.ClientID%>')[0];

        // have to bind the events here because you can't use asp inside tag attributes

        $(<%=aDateRange.ClientID%>).click(function () {
            <%=spanDateRange.ClientID%>.hidden = false;
        });

        $(<%=aSpecificDates.ClientID%>).click(function () {
            <%=spanDateRange.ClientID%>.hidden = true;
        });

        <%=aDateRange.ClientID%>.click();
    }

</script>

spanDateRange, aDateRange, aSpecificDatesare all divs (runat="server") in my user control

And here's my Page_Load from the .ascx.cs file:

 protected void Page_Load(object sender, EventArgs e)
        {
            Page.ClientScript.RegisterStartupScript(this.GetType(), "initSection", "initSection" + ClientID + "();", true);
        }

And here's where I dynamically load multiple copies of the usercontrol:

protected void LoadSections()
        {
            var numSections = utils.Utils.Clamp(int.Parse(tbNumSections.Text), int.Parse(tbNumSections.Attributes["Min"]), int.Parse(tbNumSections.Attributes["Max"]));
            for (int i = 2; i <= numSections && numSections != tbodySections.Controls.Count - 2; i++) // start at 2 because there's always 1 section, don't load any more sections if they're already loaded
            {
                var newSection = (usercontrols.sectionDetails)LoadControl("usercontrols/sectionDetails.ascx"); // load a new sectionDetails control
                newSection.SectionNumber = i;

                tbodySections.Controls.AddAt(i + 1, newSection);
            }
        }

I expect that after I load each section, the load event would get caught, or the startup script would run, but i don't think any javascript from my dynamically loaded user controls is running. I've tried putting the user control directly into the page, so that's how I know that my javascript is correct syntactically.

  • 1. I would look into .NET Core or something more modern. 2. Ditch jQuery. 3. I don't see how your JavaScript would ever work. You would have to do your function naming/variable magic outside of the script tag. JavaScript has no idea what `<%=something%>` is or how to interpret it. I could see it working if you did all of this logic outside of JavaScript which producted a JavaScript file, then loaded that up. But I don't see how any of this would ever work with the logic in the script tag. – mwilson Mar 26 '19 at 22:40
  • This thread could also help at how you could go about doing it: https://stackoverflow.com/questions/6542079/is-there-a-way-to-use-someobject-clientid-in-an-external-javascript-fil – mwilson Mar 26 '19 at 22:42

2 Answers2

1

asp.net eval script in ajax html reponse

This is it! ^^^

First, I had to move my LoadSections() in the codebehind from the Page_Load to Page_Init.

Then, in my UpdatePanel, I have:

            // this function runs after each postback
            function pageLoad() {
                evaluateScripts('#<%=tbodySections.ClientID%>'); //pass the table body (tbodySections) so we can run the js inside each user control
            }

and then in the master page, I have:

        // this will run any javascript in the selected div
    function evaluateScripts(divSelector) {
        $(divSelector).find('script').each(function () {
            if (this.src) {
                $('body').append(this);
            }
            else {
                var content = $(this).html();
                eval(content);
            }
        });
    }

After each postback, I can dynamically load any number of sections I need, and then hook up all the events in js via the functions pageLoad and evaluateScripts

0

I am not sure about the syntax of the JavaScript you're using. However, it sounds like your code is referencing something inside your ASCX file, before the ASCX file has been fully loaded.

To accomplish this, you have to add your script that you wish to run inside the ASCX file itself. At the end of your ASCX file, add the following code:

  <script type="text/javascript">
        window.addEventListener("load", function() 
        {
              alert('ascx loaded!');

             // enter your code here you want to run when ASCX is ready.
    });
  



</script>

The above, when placed at the end of your ASCX file, will fire "ascx loaded!" in an alert box. You should be able to modify this example to avoid calling elements that do not exist yet.

Josh Harris
  • 446
  • 4
  • 8