I have an ASPX page that includes an ASCX control, which in turn references a script in a separate file. I want the ASCX to handle a button click by calling a function in the script file, but whenever the page loads, the browser's debugger says that it cannot find the function.
What is supposed to be happening in the code below is this: When ParentPage.aspx loads, it includes ASCX control Control1.ascx, which has a button which, when clicked, calls JavaScript function ShowAnAlert(). However, the browser's debugger says, "Unexpected identifier 'ShowAnAlert'".
How do I access the function from the ASCX? Note that the click handler is being called; that's not the problem.
ParentPage.aspx:
<%@ Register TagPrefix="ascx" TagName="Control1" Src="~/Control1.ascx" %>
<asp:Content ID="Content1" ContentPlaceHolderID="AuthContent" Runat="Server">
<div >
<div id="Control1">
<ascx:Control1 ID="Step1Control" runat="server" />
</div>
</div>
</asp:Content>
Control1.ascx:
<button id="TheButton" text="Click Here" onclick="TheButton_Click" />
<script type="text/javascript" src="Control1Script.js"></script>
Control1.ascx.vb:
Protected Sub TheButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), "Alert1", "ShowAnAlert('ShowAnAlert works')", True)
End Sub
Control1Script.js:
function ShowAnAlert(theText) {
alert(theText);
}
CodePudding user response:
Use ScriptManager
The code has multiple problems, but we can get it working.
The main reason it doesn't work is because the script is not loading. On an HTML page you load the script using a <script>
tag, but an ASCX control needs to load scripts using ScriptManager.
Modify your Control1.ascx file as shown below. It adds an asp:Button control with an OnClientClick handler that calls the JavaScript function. The script tag is replaced with a ScriptManagerProxy control. The proxy tells the Script Manager on the host ASPX page which scripts it requires. This ensures that scripts only load once even though the page may use multiple controls.
Control1.ascx
<%@ Control Language="VB" AutoEventWireup="false" CodeFile="Control1.ascx.vb" Inherits="Control1" %>
<asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="javascript:return ShowAnAlert('Hello World');"/>
<asp:ScriptManagerProxy runat="server" ID="Manager">
<Scripts>
<asp:ScriptReference Path="~/Control1Script.js" />
</Scripts>
</asp:ScriptManagerProxy>
And then in ParentPage.aspx (or the master page) we need to add the ScriptManager control as shown on the first line.
ParentPage.aspx
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div id="Control1">
<ascx:Control1 ID="Step1Control" runat="server" />
</div>
And voilà! When we run the app and click the button we now see our alert box.
Keep in mind that this solution shows just one of a couple of different ways you might use ScriptManager. To read more about it see: ScriptManager Class
CodePudding user response:
I got it to work, but I had to jump through a hoop or two.
The main problems were, (a) I should have been using the ClientScriptManager (Page.ClientScript), (b) I have to use RegisterStartupScript instead of RegisterClientScriptBlock (something to do with when the script is loaded in relation to the existing scripts), and (c) when using Page.ClientScript.RegisterStartupScript, the ... tags have to be included.
In other words, change Control1.ascx.vb to:
Protected Sub TheButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Page.ClientScript.RegisterStartupScript(Me.GetType(), "Alert", "<script type=""text/javascript"">ShowAnAlert('ShowAnAlert works');</script>")
End Sub