Avoid ASP.NET special behavior of Ajax controls - asp.net

I have a form where the user can ajaxly change a lot of the information using modal popups. I am using Ajaxtoolkit and standard ASP.NET Ajax controls (that is, scriptmanager, updatepanel, etc.)
When a user is hitting the back button the user is going through all the stages of changes the user has made. I would like to avoid that. I would like that if PAGE1 is calling to PAGE2 and even though PAGE2 is radically changed using Ajax, hitting the browser's 'back' button will take the user back to PAGE1 directly. How can I do that?

The browser back button does not get the page from server, but rather from the browser cache. So there are two ways of handling this situation:
This method can make us to call the previous page from the server instead of the cache:
<body onUnload = "DoSomethingHere()"> ... </body>
<script language = "javascript">
DoSomethingHere() {
window.location.href = "URL of the previous page";
}
</script>
This way we will prevent the back button action:
function preventBack(){window.history.forward();}
setTimeout("preventBack()", 0);
window.onunload = function(){null};

Related

is it possible to not reload user control when redirect to a page?

I have created a user control for side menu navigation and when user clicks on one of the item on a menu, it displays details of the company and information. Now it is redirecting to different page for each company using passing parameter (ex. company.aspx?ID=10) and everytime when I clicked, it refreshes whole page. I would like to keep side menu user control without refresh as there is a live search option.
Is this possible? or should I change opposite way to do it? should be the side menu in a page and company info in a user control??
If you want to do a proper way using Ajax, you'll need to change the entire site structure. Here is a quick and dirty way of doing it using jQuery.
<script>
$(document).ready(function () {
$("#left-pane a").click(function (e) {
e.preventDefault();
loadUrl($(this).attr("href"));
});
});
function loadUrl(url) {
$("#right-pane").load(url);
}
</script>
I think what you're talking about is partial page update, where, rather than posting and reloading the entire page, you only reload part of it.
Here's a good article: Understanding Partial Page Updates with ASP.NET AJAX

Showing a PopUp in an ASP.Net before Page_load

I am developing an ASP.net application in which i am supposed to show a select language Popup( a simple screen where user can select language) to the user when he logs in for the first time. I tried calling the PopUp from the InitializeCulture event but the PopUp appears after the home Page Gets loaded.
I want the PopUp to appear before the page is loaded. Once the user selects the language from the PopUp, i want the page to appear in that language.
I am using the following code the call the PopUp
Page.ClientScript.RegisterStartupScript(typeof(Page), "onload", script);
Have the user redirected to a select language page. Then redirect to the site afterwards. You can also check on page load to be sure a language has been selected or redirect to the page.
To provide some explanation of Chad's response, it helps to understand the core of the ASP.NET Page Life Cycle. In particular, when an aspx page is requested from the server for the first time (i.e. not a post-back), IIS recognizes the .aspx extension and hands it off to the ASP.NET engine for rendering. The ASP.NET engine first instantiates the code-behind class, executes any pre-render methods or events (Init, Page_Load, PreRender, etc.), and also processes all of the non-HTML markup ('<%...%>' and '') in the .aspx file. When all of this is done, it has the complete HTML page that is then returned to the browser in the HTTP response).
The point here is that the browser never sees any of your HTML, including the RegisterStartupScript code, until after your Page_Load or any other server-side code has already completed.
Another possible solution is to use a MultiView which shows the language selection UI in one View and the actual page content in another view. The language selection would now be done via controls directly on the page rather than in a pop-up. In your Page_Load, you check to see if a language has been selected and if not, show the first View. After the user selects their language, is submits a post-back to the server which calls the Page_Load a second time (this time with IsPostBack being true). You then set the language in your code based on the user's selection and switch to the second View that contains the main page content. You may also get a slightly better user experience by wrapping the MultiView in an UpdatePanel so you get AJAX post-backs, instead of full-page ones.
So the basic logic in your Page_Load would look something like this (using C# like syntax):
if (!IsPostBack) {
string userLang = SomehowGetSelectedLanguageFromUserProfile(); // You provide
if (String.IsNullOrEmpty(userLang) {
PopulateLanguageComboBox(); // You provide
multiView1.ActiveView = 0;
} else {
DoAnyWorkNecessaryToRenderPageInSpecifiedLanguage(userLang); // You provide
multiView1.ActiveIndex =1;
}
} else {
if (multiView.ActiveView == 0)
{
if (comboLangSelect.SelectedIndex <= 0) {
lblErrorMessage.Text = "You must select a language to continue";
lblErrorMessage.Visible = true;
} else {
DoAnyWorkNecessaryToRenderPageInSpecifiedLanguage(comboLangSelect.SelectedValue);
multiView1.ActiveIndex =1;
}
} else {
// Any other PostBack processing required for the main page.
}
}
Please note that I wrote this entirely here in the response box and have not compiled nor tested this in any way. It is only meant to provide you the general logic behind the solution I am suggesting.
If you really need to do the language selection in a pop-up, it can be done, but then you need to have the pop-up window communicate the results back to the main page window and have it manually post-back the results to the server. This is a little more involved but it is possible.

Redirection from a Telerik Rad Window

In an asp.net web application, I have a modal popup built with a Telerik Rad Window. In that popup there is a button which must do some action in its "code-behind" and then redirect the application to another page.
For the redirection I use the javascript command 'top.document.location.href = myPage' (sent to the browser from the code-behind with a ScriptManager.RegisterClientScriptBlock(...)).
This solves my problem but it is not very nice. When the button is pressed, this triggers the post-back. In the browser the popup is covered by a RadLoadingPanel which disapper when the post-back is finished. Then during a few seconds, nothing happens in the application and it is only after some time that the browser loads the new page.
The fact that nothing happens during a few second is not great since a user cannot know what the application is doing.
What can I do ? Is there a better way to do the redirection ? (I'm very new to javascript programming...).
Instead of just calling 'top.document.location.href = myPage', you can call a function that displays an overlay (e.g. show a RadAjaxLoadingPanel over the parent page body) and then set the new URL. See http://www.telerik.com/help/aspnet-ajax/ajxshowhideloadingpanel.html for info on how to show loading panels with JavaScript.
I think the delay after you set location.href is normal - the browser/server take some time to retrieve the new page HTML so the old page cannot go away instantly.

asp.net make button show different view of MultiView AND download a file

I have a page on my site on which users have to fill out details before they can download a document. The user details section is on the first view in a MultiView control.
After filling out their details I'd like the user to click a button which will show them a file download prompt (I've done this successfully with an ashx handler) then redirect them to the second view page of the MultiView which will say "thank you for downloading" or something like that.
I've tried the usual Response.Redirect("~/DownloadHandler.ashx"); within the button click event handler, but obviously this prevents the page completing the postback and showing the last page of the MultiView.
Is there a way around this, or should I just change my UI to accommodate this?
EDIT:
I've concluded that it's better to just provide a hyperlink to the document (on my confirmation page, and change the wording accordingly) as this provides a consistent user experience independent of the browser they're using.
Go ahead and take them to the second view of the MultiView. Add a javascript method that will download the document, and trigger it from your codebehind.1 E.g.,
In your page:
<script>
function downloadFile(url) {
window.location = url;
//you could also try window.open(url, 'Download')
}
</script>
In your code behind:
script = string.Format("downloadFile('{0}');", "DownloadHandler.ashx");
Page.ClientScriptManager.RegisterStartupScript(typeof(Page), "download", script, true);
You could also add a delay (using setTimeout) before the file is downloaded.
More info:
Initiating a file download that works well, even in IE?

SimpleModal breaks ASP.Net Postbacks

I'm using jQuery and SimpleModal in an ASP.Net project to make some nice dialogs for a web app. Unfortunately, any buttons in a modal dialog can no longer execute their postbacks, which is not really acceptable.
There is one source I've found with a workaround, but for the life of me I can't get it to work, mostly because I am not fully understanding all of the necessary steps.
I also have a workaround, which is to replace the postbacks, but it's ugly and probably not the most reliable. I would really like to make the postbacks work again. Any ideas?
UPDATE: I should clarify, the postbacks are not working because the Javascript used to execute the post backs has broken in some way, so nothing happens at all when the button is clicked.
Both of you were on the right track. What I realized is that SimpleModal appends the dialog to the body, which is outside ASP.Net's <form>, which breaks the functionality, since it can't find the elements.
To fix it, I just modified the SimpleModal source to append eveything to 'form' instead of 'body'. When I create the dialog, I also use the persist: true option, to make sure the buttons stay through opening and closing.
Thanks everyone for the suggestions!
UPDATE: Version 1.3 adds an appendTo option in the configuration for specifying which element the modal dialog should be appended to. Here are the docs.
All standard ASP.NET postbacks work by calling a __doPostBack javascript method on the page. That function submits the form (ASP.NET only really likes one form per page) which includes some hidden input field in which all the viewstate and other goodness lives.
On the face of it I can't see anything in SimpalModal that would screw up your page's form or any of the standard hidden inputs, unless the contents of that modal happened to come from a HTTP GET to an ASP.NET page. That would result in two ASP.NET forms being rendered into one DOM and would would almost certainly screw up the __doPostBack function.
Have you considered using the ASP.NET AJAX ModalPopup control?
Web browsers will not POST any disabled or hidden form elements.
So what's happening is:
The user clicks on a button in your dialog.
The button calls SimpleModal's close() method, hiding the dialog and the button
The client POSTs the form (without the button's ID)
The ASP.NET framework can't figure out which button was clicked
Your server-side code doesn't get executed.
The solution is to do whatever you need to do on the client (closing the dialog in this case) and then call __doPostback() yourself.
For example (where "dlg" is the client-side SimpleModal dialog reference):
btn.OnClientClick = string.Format("{0}; dlg.close();",
ClientScript.GetPostBackEventReference(btn, null));
That should hide the dialog, submit the form, and call whatever server-side event you have for that button.
#Dan
All standard ASP.NET postbacks work by calling a __doPostBack javascript method on the page.
asp:Buttons do not call __doPostback() because HTML input controls already submit the form.
got caught out by this one - many thanks to tghw and all the other contributors on the appendto form instead of body fix. (resolved by attributes on the 1.3 version)
btw: If anyone needs to close the dialog programmatically from .net - you can use this type of syntax
private void CloseDialog()
{
string script = string.Format(#"closeDialog()");
ScriptManager.RegisterClientScriptBlock(this, typeof(Page), UniqueID, script, true);
}
where the javascript of closedialog is like this....
function closeDialog() {
$.modal.close();
}
I have found the following works without modifying simplemodal.js:
function modalShow(dialog) {
// if the user clicks "Save" in dialog
dialog.data.find('#ButtonSave').click(function(ev) {
ev.preventDefault();
//Perfom validation
// close the dialog
$.modal.close();
//Fire the click event of the hidden button to cause a postback
dialog.data.find('#ButtonSaveTask').click();
});
dialog.data.find("#ButtonCancel").click(function(ev) {
ev.preventDefault();
$.modal.close();
});
}
So instead of using the buttons in the dialog to cause the postback you prevent their submit and then find a hidden button in the form and call its click event.
FWIW, I've updated the blog post you pointed to with come clarification, reposted here - the reasoning & other details are in the blog post:
The solution (as of my last checkin before lunch):
Override the dialog's onClose event, and do the following:
Call the dialog's default Close function
Set the dialog div's innerHTML to a single
Hijack __doPostBack, pointing it to a new function, newDoPostBack
From some comments I’ve seen on the web, point 1 needs some clarification.  Unfortunately, I’m no longer with the same employer, and don’t have access to the code I used, but I’ll do what I can.  First off, you need to override the dialog’s onClose function by defining a new function, and pointing your dialog to it, like this:
$('#myJQselector').modal({onClose: mynewClose});
Call the dialog's default Close function.  In the function you define, you should first call the default functionality (a best practice for just about anything you override usually):
Set the dialog div's innerHTML to a single – This is not a required step, so skip it if you don’t understand this.
Hijack __doPostBack, pointing it to a new function, newDoPostBack
function myNewClose (dialog)
{
dialog.close();
__doPostBack = newDoPostBack;
}
Write the newDoPostBack function:
function newDoPostBack(eventTarget, eventArgument)
{
var theForm = document.forms[0];
if (!theForm)
{
theForm = document.aspnetForm;
}
 
if (!theForm.onsubmit || (theForm.onsubmit() != false))
{
document.getElementById("__EVENTTARGET").value = eventTarget;
document.getElementById("__EVENTARGUMENT").value = eventArgument;
theForm.submit();
}
}
The new Jquery.simplemodal-1.3.js has an option called appendTo. So add an option called appendTo:'form' because the default is appendTo:'body' which doesn't work in asp.net.
Had the same problem, but {appendTo:'form'} caused the modal popup to be rendered completely wrong (as though I had a CSS issue).
Turns out the template I'm building on top of has includes that put other forms on the page. Once I set {appendTo:'#aspnetForm'} (the default Asp.net form ID), everything worked great (including the postback).
In addition to tghw's answer, this excellent blog post helped me: jQuery: Fix your postbacks in Modal forms -- specifically BtnMike's comment: "You also must not have CssClass=”simplemodal-close” set on your asp:button." Taking that off the class was the not-obvious-to-me solution.
-John
if you don want modify the SimpleModal source.
try this..
After you call the modal() method add this:
$("#simplemodal-overlay").appendTo('form');
$("#simplemodal-container").appendTo('form');
the SimpleModal plugin add two this to your markup.
'simplemodal-overlay' for the background
'simplemodal-container' containig the div that you whant as pop up modal.

Resources