Unfortunately, I cannot reproduce this problem outside my application. I have a VS2012 project I can send anybody who's willing to take a look. It works for me in isolation but not in a larger app.
My objective is to have a common overlay control in the master page that pages can bubble display events during partial postbacks.
Here's what I have:
- A user control that displays a message box in an overlay
- A javascript file that gets the PageRequestManager object and adds a pageLoaded event
- The event handler checks the value of a hidden control and uses jquery to show/hide the message
- A master page with a scriptmanager and the user control wrapped in an updatepanel
- A class containing a shared event to alert the master page that a message needs to be displayed
- A page with an updatepanel containing a div, a button and a textbox
- A css file
What happens in the test app:
- text is entered in the box and the button clicked
- the button click event
- copies the text to the div in the updatepanel
- calls the DisplayMessage method in the custom class to alert the master page
- DisplayMessage instantiates and populates the custom event args and raises the event
- the handler in the master page sets the properties of the usercontrol and calls Update on its UpdatePanel
- the page displays the overlay and trigger pageLoaded [1]
- the javascript function evaluates the Value property of the hidden control and displays the message.
- the user clicks the OK button
- the click handler (server side) sets the hidden value and triggers an update on the usercontrol's updatepanel
- the message disappears
What happens "in real life":
- at point [1], the javascript fails with $ is not defined
The chrome console allows me to input jQuery and displays elements ok.
There are no jq plugins involved, the scriptmanager is at the top of the form in the master. The jquery reference is in the of the master pointing to google with no "http/https".
I have tried adding the external script in a ScriptManagerProxy but to no avail. As it is, the test app works fine with the
<script src="blahblah.js"></script>
at the bottom of the user control markup.
Any help you can offer would be very much appreciated.
Cheers, .pd.
EDIT:
Script references as requested:
This is the Master page:
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script type="text/javascript" src="/scripts/tabindex.js"></script>
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body style="background-color: #cccccc;">
<form id="form1" runat="server">
<asp:ToolkitScriptManager runat="Server" EnablePartialRendering="true" ID="ScriptMan1" EnablePageMethods="true">
</asp:ToolkitScriptManager>
<asp:UpdatePanel ID="updPopupMsg" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<amis:PopupMsg ID="popMaster" runat="server" Hidden="true" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
And this is the UserControl markup:
<div id="divOverlay" runat="server" class="helpbox-overlay"></div>
<div id="divMessage" runat="server" class="helpbox">
<asp:HiddenField ID="hdnHidden" runat="server" Value="True" />
<asp:Panel ID="pnlHelpBox" CssClass="helpbox-popup" runat="server">
<h1>
<asp:Label ID="lblTitle" runat="server"></asp:Label></h1>
<p>
<asp:Label ID="lblMsg" runat="server"></asp:Label>
</p>
<p> </p>
<p align="center">
<asp:Button ID="btnClose" CausesValidation="false" Text="Close" runat="server"/>
</p>
</asp:Panel>
</div>
<script type="text/javascript" src="/scripts/popup-msg.js"></script>
The code in that javascript file looks like this:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(popup_msg_init);
function popup_msg_init() {
if ($('input[id*="hdnHidden"]').attr('value') == 'True')
popup_msg_hide();
else
popup_msg_show();
}
function popup_msg_show() {
$('div[id*="divOverlay"]').show();
$('div[id*="divMessage"]').show();
}
function popup_msg_hide() {
$('div[id*="divOverlay"]').hide();
$('div[id*="divMessage"]').hide();
}
EDIT:
Hey - is it possible the scripts are being loaded asynchronously? Are there any tools I can use to verify what is happening when? I ask because I changed the javascript to the following:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(popup_msg_init);
function popup_msg_init() {
var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
if (input.id.indexOf('hdnHidden') > 0) {
if (input.value == 'True')
popup_msg_hide();
else
popup_msg_show();
}
}
}
function popup_msg_show() {
$('div[id*="divOverlay"]').show();
$('div[id*="divMessage"]').show();
}
function popup_msg_hide() {
$('div[id*="divOverlay"]').hide();
$('div[id*="divMessage"]').hide();
}
And now it all works. So my theory is that pageLoaded is calling my popup_msg_init function on a different thread that can't see jquery and the delay caused by searching the dom manually gives it enough time to load cuz by the time the show/hide functions are called, everything's groovy.
So I thought I'd check that by sticking a timeout on there:
setTimeout(function () {
if ($('input[id*="hdnHidden"]').attr('value') == 'True')
popup_msg_hide();
else
popup_msg_show();
}, 5000);
But it goes back to "$ is undefined."
Any comment on that?