I have a form with gridview that is bound to a complex stored procedure (financial data). This query takes about 3 minutes to run and load the gridview. The users get impatient and click "Search" repeatedly, which just makes things worse.
As an interim solution, I'd like to show a progress bar, and I found a solution using the ASP.NET AJAX ModalPopupExtender.
This is the code I have for adding the extender to the page:
<ajaxToolkit:ModalPopupExtender ID="mdlPopup" runat="server" TargetControlID="Button1"
PopupControlID="pnlPopup" BackgroundCssClass="modalBackground" />
<asp:Panel ID="pnlPopup" runat="server" CssClass="updateProgress" style="display: none">
<div align="center" style="margin-top: 13px;">
<img src="../images/progress.gif" alt="Progress" />
<span class="updateProgressMessage">Loading ...</span>
</div>
</asp:Panel>
This is the very simple code for the button's click event:
protected void Button1_Click(object sender, EventArgs e)
{
gvInvoice.DataBind();
}
The problem is, when I click the Search button, the modal dialog pops up but the Databind() method never gets called. I tried using mdlPopup.Show() but that doesn't show the dialog and instead just runs the Databind().
What am I missing? How do I ensure that the modal dialog appears, the databind runs, and the modal dialog subsequently disappears?
I think what you need to do here is separate the showing of the dialog and the binding from the fetching of the data.
I would probably solve the problem using an approach like this:
Show Dialog and spin thread to go fetch the data. (the thread would put the data in the session cache, or a customised cache on a database.)
Have the client poll the server for if the data is available (probably using AJAX calls to static page methods).
When the data is available, hide the dialog and do the databind.
You can put additional checks/conditions around when the thread is started so that you don't start too many threads if the user presses search a number of times. I.e. if they haven't changed the search criteria then don't start a new search, but just continue polling.
It looks like you try to show progress panel (modal popup) for full page post-back?
mdlPopup.Show() would work if the search action is done within updatepanel
In your scenario, try this instead
- Step 1, set the TargetControlID of the modalpopupextender to a dummy hidden control
- Step 2, added javascript call that shows the modalpopup $find('mdlPopup').show(); before the post-back call of search button's onclient event (just like adding a validation before post-back)
James
Related
I have several text boxes on a page. I want to save the text in the corresponding TextBox on LostFocus. It is to ensure the data is not lost when power failure or internet connectivity is lost. How can I accomplish something like this?
Another solution would be to use an UpdatePanel. You could then leverage server-side events rather than an event handler. You're markup might look something like this:
<asp:ScriptManager ID="ScriptManager" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<asp:TextBox ID="SomeTextBox" runat="server" TextChanged="SomeTextBox_TextChanged" AutoPostBack="true" />
</asp:UpdatePanel>
</asp:ScriptManager
and then in the TextChanged handler you could do your work.
Explanation: the TextChanged event will fire on the text box in which the text was actually changed when the post back occurs. The AutoPostBack property is necessary so that the page will in fact post back when the text box loses focus.
One final thing to remember, you will probably need to leverage this.IsPostBack on the page in the Load handler because every time a control is updated it's going to reconstruct the page. It's common that logic in the Load handler only needs to execute one time, but that would pose a problem if you didn't check to see if it was a post back because then it would execute every single time you left a text box.
Use jquery.
First on attach blur event handler, where you call ajax method to server passing new value of the textbox.
Handle this ajax event on serverside and write your data to the database or anywhere else.
Here is a piece of code that may help.
$('#textbox_id').blur(function() {
$.ajax({url:"handler_url.ashx?textbox_value=" + $('#textbox_id').val()});
});
Then create your ashx handler on server and handle your requests with ProcessRequest method. From there you will have access to Request.QueryString where new value of textbox will be stored.
Note: I am brand new at ASP.NET. I'm actually going to training on Monday, but we have a hot project that required me to dive in and get done as much as I can.
I've got a textbox on my page, and I would like it to call an event on the server whenever it is changed. I don't care if "changed" means changed and loses focus, or just whenever a keyup happens. Either case will work.
The issue is that, for some reason, whenever I change my textbox and then remove focus, the server-side method is not getting called. Viewing through the debugger in Chrome, I don't even see any sort of AJAX call being made that would inform the server that a textbox was changed.
My Code:
ASCX File
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:TextBox ID="tempTagBuilder" runat="server"
CssClass="depBuilder_tempTagBuilder"
ontextchanged="tempTagBuilder_TextChanged" AutoPostBack="True"></asp:TextBox>
</ContentTemplate>
</asp:UpdatePanel>
ASCX.cs File
//whenever the text is changed
protected void tempTagBuilder_TextChanged(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Hit");
}
Anyone have a good idea of what my issue might be?
Update 1:
I got it working (somewhat). I had to go into the updatepanel's properties and add the textchanged event to the triggers collection. However, now whenever it sends the update it is emptying out the other textboxes on my page!
It doesn't fire because it's in an update panel most likely. Seems the updatepanel requires you to set a trigger for the event.
Problem with textbox inside updatepanel - not causing OnTextChanged event
If I click a button very fast after page load, the post back won't be fired. The following example illustrates this (you have to click the button twice and very fast):
<form id="form1" runat="server">
<div>
<span id="submitText"></span>
<br />
<asp:Button ID="btnSubmitTest" runat="server" Text="Button"
OnClientClick="document.getElementById('submitText').innerText='you should not see this after postback';" />
</div>
</form>
The submitText, the button set's before firing, should not be visible after the postback. But if you click at the button very fast, it happens, that the event doesn't fire.
I think, that the page isn't loaded completely at this moment. Or is there any other reason for that behaviour? How do you handle this?
You will loose all javascript dom updates on postback. What you have explained sounds correct... you see the client click event fire just before page posts back and the dom is reset.
Try the same exercise by populating a textbox. In that instance the value will maintain as the textbox relies on viewstate. You could put a runat="server" on the span, but I believe you would have to manually assign the value to viewstate as I don't believe htmlgenericcontrols automatically utilize viewstate.
I have an UpdatePanel with ContentTemplate specified. When page loads, user can do some AJAX work in other part of the page. Then, after that work is finished, I would like to update only content inside UpdatePanel, but without pressing any buttons etc. I should be done automatically using JavaScript when previously started AJAX work finishes. How to do it without manual clicking on the trigger button?
EDIT:
Ok, I've followed that _doPostBack rule, and whole page is posted.
<asp:UpdatePanel ID="panelAttachments" runat="server">
<ContentTemplate>
........
</ContentTemplate>
</asp:UpdatePanel>
<input type="text" name="test" onchange="__doPostBack('<%=panelAttachments.UniqueID %>',''); return false;" />
</td>
Thanks, Pawel
To refresh an update panel from javascript:
__doPostBack(updatePanelUniqueID,'');
The first parameter is the UniqueID (not CientID) of the UpdatePanel.The 2nd parameter is optional arguments you can pass which will be available to your server code. Both are stored in hidden form fields by ASP.NET, you can access them in codebehind:
Request.Form["__EVENTTARGET"];
Request.Form["__EVENTARGUMENT"];
But if you just want to refresh a panel and don't need to pass any additional info from the client, you can ignore then 2nd argument.
If you look at the HTML generated by ASP.NET for an async postback control, you'll see it's exactly this.
I have some simple javascript that I'd like to run when a button is clicked, but I also want some postback action to occur on the server. The logical code for this looks like this:
<asp:Button ID="btnOK" runat="server" Text="Save Changes" OnClientClick="UpdateParent();" OnClick="btnOK_Click" />
<asp:Button ID="btnCancel" runat="server" Text="Cancel" OnClientClick="window.close();" />
<script language="javascript" type="text/javascript">
function UpdateParent()
{
window.opener.document.location.reload(true); // or should we postback instead?
window.close();
}
</script>
Basically, a popup window should refresh its parent and then close itself. However... if I call window.close(), the postback does not occur and the button handler is not called. But obviously OnClientClick is called before the postback happens. Am I going to have to emit this javascript in the button handler and run it when the page loads after postback? If so, what is the proper way to do this these days for ASP.NET 2.0?
It's a shame that the code above doesn't work as it's elegantly simple and straightforward.
You have to do the postback before closing the window. Also you want to do the postback before refreshing the parent window, as I guess that the reason to refresh the window is to display the information that you are about to save.
Use the RegisterStartupScript in the ClientScript object to run the code after postback:
Page.ClientScript.RegisterStartupScript(this.GetType(), "close", "window.opener.location.reload(true);window.close();", true);
However, if the parent page is a result of a postback, this would cause a dialog window in the browser informing the user that a post request is needed to reload the page. To avoid this you would have to do something like calling a function in the parent page that could do a postback to update the page.