Old hand at ASP.NET, new to the UpdatePanel. I have a reporting page which executes a fairly length SQL query... takes about 10 seconds right now. What I would like to do is have my page fully render, with some placeholder text (Loading...) and then have the UpdatePanel kick off the actual time-consuming reporting process and render the report when it's done.
So... my theory is to use RegisterStartupScript() to kick this off and drop the string from GetPostBackEventReference() to trigger the UpdatePanel update. Some problems crop up:
1) Can I actually use GetPostBackEventReference w/ the UpdatePanel or do I need to trigger it some other way? Use this method on a button inside the Update Panel?
2) What event gets triggered when the postback reference is the UpdatePanel? It's not clear to me. I've got to call my databinding code somewhere! Again, maybe I need to use a button inside?
I had to do something very similar recently, here's how i did it (right or wrong):
The trick is a "Hidden Async Postback Trigger".
<asp:UpdatePanel ID="upFacebookImage" runat="server">
<ContentTemplate>
<!-- Your updatepanel content -->
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="hiddenAsyncTrigger" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" style="display:none;" />
Then from JavaScript, whenever you want to trigger the async postback, you do this:
__doPostBack('<%= hiddenAsyncTrigger.ClientID %>', 'OnClick');
In my example, i needed to trigger an async postback from a particular JS event. But you could attach it to doc ready.
I seem to remember trying #Marko Ivanovski's way, but for some reason it didn't work. I think you need to specify a "postback-able" control (ie a button) to trigger the postback.
HTH.
Updating this with my solution, I pieced together mostly from the first answer above.
I need my page to load, then then start loading content for my update panel. The panel calls some webservices and we don't want the whole page to crash in the event that the remote server doesn't respond. We don't want the wait either.
My HTML:
<asp:UpdatePanel ID="udpCheckout" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Image ID="imgSpinner" runat="server" Visible="true" ImageUrl="~/images/ajax-loader.gif" />
<br />
<asp:Label ID="lblWait" runat="server" Visible="true" Text="Please wait..."></asp:Label>
<asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" style="display:none;" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="hiddenAsyncTrigger" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
My Code behind snippets:
In page_load:
ScriptManager.RegisterStartupScript(Me.Page, Me.Page.GetType, "LoadUpdate", GetPostBackEventReference(hiddenAsyncTrigger, String.Empty), True)
And the button handler:
Sub LoadUpdatePanels(ByVal o As Object, ByVal e As EventArgs) Handles hiddenAsyncTrigger.Click
System.Threading.Thread.Sleep(5000) 'wait 5 seconds so I can see the page change
imgSpinner.Visible = False
lblWait.Text = "Content is now loaded."
'udpCheckout.Update()
End Sub
This was my test to see if I could get it working. Now to replace all of this with the real code!
Try something like this (not tested).
Set the UpdateMode of the UpdatePanel to Conditional.
Add this to your <head> section:
<script type="text/javascript">
window.onload = __doPostBack('UpdatePanel1', ''); // Replace UpdatePanel1 with the ID of your UpdatePanel
</script>
Simplifying RPM1984's very helpful earlier answer (thanks ;)) and showing some tweaks & a little more of the surrounding detail that I found necessary:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="upFacebookImage" runat="server">
<ContentTemplate>
<asp:PlaceHolder runat="server" ID="PlaceHolderMediaPrompts" />
<asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" OnClick="WasPage_Load" style="display:none;" />
</ContentTemplate>
</asp:UpdatePanel>
Note:
The hidden button's vital OnClick= parameter, this is what specifies the server function to call!
No trigger clause or triggers in the Update-panel, I am using the child controls which are automatically triggers - specifically the button Click event.
And to trigger it from client-side Javascript you can use:
document.getElementById("hiddenAsyncTrigger").click();
However, I found it necessary to prevent this being called on subsequent page loads (as it caused unnecessary page load looping & consequent flicker). See the neat little IsPostBack() check below :)
e.g. To invoke this after page load (as per the original question), I just added a call to invoke the above line of code as the onload-parameter to the main Body-tag thus:
<body onload="DoPostLoad();">
...
<script type="text/javascript">
function DoPostLoad()
{
if ( IsPostBack() != true ) // ***This is NEW and ESSENTIAL! ***
document.getElementById("hiddenAsyncTrigger").click();
}
function IsPostBack() { // Ref. https://stackoverflow.com/questions/26978112/execute-javascript-only-on-page-load-not-postback-sharepoint
var ret = '<%= Page.IsPostBack%>' == 'True';
return ret;
}
. . .
</script>
</body>
Related
I have a problem, and looking for a solution for 2 days
Target : Create/edit client... in HTML build a dialog with and asp fields with clientIDMode static
<div id="divDialog" runat="server" clientidmode="Static" style="display: none;">
<div class="DialogFields">
<asp:Label ID="Label1" runat="server" Text="Firstname"></asp:Label>
<br />
<asp:TextBox ID="tbxFirstName" runat="server" ClientIDMode="Static"></asp:TextBox>
</div>
...
In script
$("#btnShowDialog").click(function () {
openDialog();
});
function openDialog() {
$("#divDialog").dialog('open');
$("#divDialog").parent().appendTo($("form:first"));
}
When I click the button btnShowDialog it works fine... But
Beneath it I have a gridview within it a edit button (asp:Linkbutton) with a event to the codebehind it looks like:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="Edit" OnCommand="Edit_Click" CommandArgument='<%#Eval("RelationID") %>'
runat="server"><img src="../images/Edit-item.png" alt="Edit" /></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
In codebehind take the parameter from commandargument and fire LoadInfo (specific data to all the fields in de dialog).
LoadInfo(e.CommandArgument != null ? int.Parse(e.CommandArgument.ToString()) : -1);
but no way I get the dialog open.
I tried
ClientScript.RegisterStartupScript(this.GetType(), "Popup", "openDialog();", true);
and
ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "script", "openDialog();", true);
after this LoadInfo, push btnShowDialog button and it opens the dialog and all data perfect in place.
Also tried the other way around as Directly to Jquery function, get all data loaded and open the dialog. 2 problems, loading in codebehind was not even started before the dialog opens. and I only can get a static function in the codebehind.
A lot of ground to cover for me, but can any body help me out (even for a part).
...Thanx
If I understand your question correctly, you are trying to fire some client scripts (openDialog) from the server side, but they wont fire?
Try placing your page in an update panel, lets assume that we name the update panel "MyUpdatePanel". And then refer to the update panel like this:
ScriptManager.RegisterStartupScript(MyUpdatePanel, MyUpdatePanel.GetType(), "MyUpdatePanelScript", "openDialog();", true);
MasterPage.master
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="10000">
</asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
MasterPage.master.vb
Protected Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'some sql select codes
con.Open()
Dim result As Integer = DirectCast(cmd.ExecuteScalar(), Int32) 'ExecuteScalar() only return 1 row and ignore rest
con.Close()
If result > 0 Then
'Page.ClientScript.RegisterStartupScript(Me.GetType(), "AlertMessageBox", "alert('hello world');", True)
'Page.ClientScript.RegisterStartupScript(Me.GetType(), "AlertMessageBox", "alert('" & result & " hello world');", True)
ScriptManager.RegisterStartupScript(Me.UpdatePanel1, Me.UpdatePanel1.GetType(), "AlertMessageBox", "alert(‘hello world’);", True)
End If
End Sub
Basically I have a Timer control that run a SQL Select on a fixed interval and if the result is greater than 0, there will be a popup alert.
The codes work fine if I do not use an UpdatePanel but without the UpdatePanel, whenever the Timer control runs, the page will refresh, causing whatever the user is working on to be lost.
edit: further clarification
Timer1_Tick does run every 10sec. The problem lies with the pop-up, no pop-up occurs on the browser.
Add OnTick="Timer1_Tick" to your .master markup.
Also, you should not need to, but your could try adding:
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
im stuck with Javascript in Asp.net...
I made a TextBox named tbValidFrom and another named tbValidTo.
I also made two ModalPopups.
Then i try to open the ModalPopupExtenders when the TextBoxes get focus:
<script type="text/javascript">
$('#tbValidTo').focus(function () {
$find('ModalPopupExtenderNV1').show();
})
$('#tbValidFrom').focus(function () {
$find('ModalPopupExtenderNV2').show();
})
</script>
but it doesnt finds tbValidTo or ModalPopUpExtender ?
Runtime-Error in Microsoft JScript: Object expected
Here is one of the two ModalPopupExtenders and TextBoxes:
<asp:TextBox ID="tbValidFrom" runat="server"></asp:TextBox>
<asp:UpdatePanel ID="UpdatePanelNV2" runat="server" RenderMode="Inline" UpdateMode="Conditional">
<ContentTemplate>
<cc1:ModalPopupExtender ID="ModalPopupExtenderNV2" runat="server" TargetControlID="HiddenField6"
PopupControlID="PanelNewVersion" BackgroundCssClass="modalBackground" BehaviorID="ModalPopupExtenderNV2"
Enabled="True" />
<asp:HiddenField ID="HiddenField6" runat="server" />
</ContentTemplate
</asp:UpdatePanel>
The same as above is with the other ModalPopupExtender and TextBox...
Help would be really nice.
Thanks
Edit: Yes i use a masterpage!
Fails where it is marked yellow.
your jQuery syntax is wrong.
change your script to:
<script type="text/javascript">
$('#tbValidTo').focus(function () {
$(this).find('#<%=ModalPopupExtenderNV1.ClientID%>').show();
});
$('#tbValidFrom').focus(function () {
$(this).find('#<%=ModalPopupExtenderNV2.ClientID%>').show();
})
</script>
elements that has runat="server" will eventually end with a different ID than you entered in the aspx file.
i used the <%= %> to get the 'final' id.
hope that helps
Seeing that markup there is two chances for the issues.
With the ModalPopupExtender.
Where you have given the panel "PanelNewVersion" . Seems like its missing in the markup.
In the Javascript code. If you want to hide that Popup, give the name of the panel. NOt the name of the ModalPopupextender.
Also you have given an update panel there in page, so you can easily handle the modalpopup in any srever side event of your textbox.
Otherwise, if you want to use the Modal popup ijn client side, use jQuery Modalpopup. That will the better option.
ASP.NET Can modify the ID's of elements, if you use a Masterpage the element id's will be modified to something like the following : ctl001_ContentPlaceHolder1_tbValidFrom
To get around this ASP.NET modification of your elements you can use ASP.NET Inline Expressions to get the rendered ID from the object.
See the answer to the following question for more information on ASP.NET Inline Expressions
You can look at changing the Client ID Mode (The way ASP.NET Modifies IDs when the page is rendered) here :
ASP.NET Client ID Modes
EDIT :
The AjaxControlToolkit's ModalPopupExtender is not rendered on the page as a html element, therefore you cannot find this item using the ClientID of the ModalPopupExtender.
You must use the BehaviourID to call the show function on.
The below code should work correctly :
$('#<%= tbValidTo.ClientID %>').focus(function () {
$find('ModalPopupExtenderNV1').show();
})
$('#<%= tbValidFrom.ClientID %>').focus(function () {
$find('ModalPopupExtenderNV2').show();
});
This will find the textbox object using the ASP.NET Inline expressions to find the client ID and will then find the behaviour ID and execute the Show method.
Example Markup :
<script type="text/javascript">
$(document).ready(function() {
$('#<%= tbValidFrom.ClientID %>').focus(function () {
$find('ModalPopupExtenderNV2').show();
});
});
</script>
<asp:TextBox ID="tbValidFrom" runat="server"></asp:TextBox>
<asp:UpdatePanel ID="UpdatePanelNV2" runat="server" RenderMode="Inline" UpdateMode="Conditional">
<ContentTemplate>
<cc1:modalpopupextender id="ModalPopupExtenderNV2" runat="server" targetcontrolid="HiddenField6"
popupcontrolid="PanelNewVersion" backgroundcssclass="modalBackground" behaviorid="ModalPopupExtenderNV2"
enabled="True" />
<asp:HiddenField ID="HiddenField6" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Panel ID="PanelNewVersion" runat="server">
testing panel
</asp:Panel>
I have the following update panel with a text field limited to 9 characters only accepting numbers.
<asp:UpdatePanel ID="updatePanelsearchusers" runat="server" UpdateMode="Always">
<ContentTemplate>
<div class="formfieldarea">
<div id="searchfield1" class="searchfieldbox">
<asp:Label ID="USIDSearchlbl" runat="server" Text="USID: " CssClass="formlabel" />
<asp:TextBox ID="USIDSearchBox" runat="server" MaxLength="9" />
<cc1:FilteredTextBoxExtender ID="FilteredTextBoxExtender1" runat="server" TargetControlID="USIDSearchBox" ValidChars="0123456789" />
<asp:ImageButton ID="USIDsearchbutton" runat="server" ImageUrl="/tissuebank/images/searchButton.png" CausesValidation="true" OnClick="search1_Click" CssClass="searchbutton" />
</div>
</div>
<div>{output from search}</div>
</ContentTemplate>
</asp:UpdatePanel>
And the following JavaScript which will automatically trigger the search button if the number of characters reaches 9.
<script type="text/javascript" language="javascript">
function setupUSIDFocus() {
$('#<%=USIDSearchBox.ClientID %>').focus().keyup(function () {
if ($(this).val().length == 9) {
$('.searchbutton').first().click();
}
});
}
$(document).ready(function () { setupUSIDFocus(); });
</script>
If I have the code as above this works fine and loads with the focus being on the element USIDSearchBox as I intended, however when the update panel is updated but the event is no longer assigned to the box and the focus is lost. To fix this I added an ASP.Net Ajax control UpdatePanelAnimationExtender so that the focus and events are reassigned when the request is complete.
<AjaxControlToolkit:UpdatePanelAnimationExtender ID="upae" runat="server" TargetControlID="updatePanelsearchusers">
<Animations>
<OnUpdated>
<Sequence>
<Parallel duration="0">
<ScriptAction Script="setupUSIDFocus();" />
</Parallel>
</Sequence>
</OnUpdated>
</Animations>
</AjaxControlToolkit:UpdatePanelAnimationExtender>
And indeed this does reset the focus and the keyup event but for some reason the element does not get focus when the page is first loaded. Though the keyup event is still attached onload I am just missing the focus being on the USIDSearchBox field. If I remove the UpdatePanelAnimationExtender then I get the focus back on load, so it must be something to do with this control.
Does anyone have any idea how to get the focus onload of the page?
Alternatively, you can use 'ScriptManager.RegisterStartupScript' in 'search1_Click' to call the jQuery function after ajax update:
ScriptManager.RegisterStartupScript(this,this.GetType(),"myscript","setupUSIDFocus();",true);
I am unable to call a Javascript function on the OnLoad event of a asp:button
HTML
<asp:Button ID="btnFromCalOpen" runat="server" Text=" > " onLoad = "AllHide()" OnClientClick ="ShowCal()" />
Javascript
function AllHide() {
alert("Hello");
}
Please Help
You will need to use JavaScript to toggle styles like you are trying
<asp:Button ID="btnFromCalOpen" runat="server" Text="" OnClientClick ="ShowCal()" style="display:none;visiblity:hidden;" />
Original Comment You can't do onLoad with JavaScript for any button. What are you hoping to accomplish? We can help figure out that solution.
You can do it at the page level. The page has a javascript onload event.
You can't do that.
Here's why. The OnLoad event in ASP.NET for a control is fired while the server is building the page (on the web server), but before it sends it to the browser (running on the user's machine).
Code on the web server can't directly call code on the browser computer (which hasn't even got the page yet).
If you just want to hide the control, just do this in your markup:
<asp:Button ID="btnFromCalOpen" runat="server" Text=" > " visible="false" OnClientClick ="ShowCal()" />
Another approach (hidden control doesn't takes up space):
<asp:Button ID="btnFromCalOpen" runat="server" Text=" > " style="display:none;" OnClientClick ="ShowCal()" />
Another approach (hidden control takes up space)
<asp:Button ID="btnFromCalOpen" runat="server" Text=" > " style="visibility:hidden;" OnClientClick ="ShowCal()" />