Showing a PopUp in an ASP.Net before Page_load - asp.net

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.

Related

ASP.NET conditional yes/no messagebox

I have an asp:Button that fires a code behind function on the OnClick event. In that OnClick event several things happen, and among those things I do a check in the database for if I need to ask the user a yes or no question. For that I need a message box. First I did it like this:
protected void MyButton_Onclick(object sender, EventArgs e)
{
// lots of stuff happening
bool iNeedToAskTheUser = INeedToAskTheUser(stuff);
if (iNeedToAskTheUser)
{
DialogResult result = MessageBox.Show("Do you want to fix all objects?", "Fix objects", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes) // do stuff
}
// some other stuff
}
This works fine locally but not when deployed, so I figure I would need to use ScriptManager.RegisterStartupScript instead. I could just add javascript on the ASPX page that fires up a dialog and saves the response in a hidden control that I can then look at, but I don't want to fire up the dialog unless I have to, which I check for before I do the DialogResult in the code above. So I can't do that immediately when the user clicks the button.
Is there any way I can use ScriptManager.RegisterStartupScript in "the middle" of my _OnClick code so that I can choose whether or not to actually show the button, and then also know if the user clicked yes or no, (preferably) without doing a postback?
I've been thinking and testing two different solutions:
Use ScriptManager.RegisterStartupScript in code behind to fire a JavaScript confirm function on the ASPX page. The JavaScript function would set a value in a hidden control depending on if the user answered yes or no and then my code behind stuff would check the value of that hidden field and act upon that. The problem with that is that once ScriptManager.RegisterStartupScript fires it doesn't wait for the JavaScript function to "finish", ie wait for the user to reply to the confirm(). So the value in the hidden control will always be empty because the code behind gets to the check of that control before the user has a chance to respond to the confirm(). So that's a no go.
Use ScriptManager.RegisterStartupScript in code behind to open up a new ASPX page that asks the user the question and then does all the work in response to the user's answer in that page. The problem then is to pass the object that the new ASPX page needs to do work on in response to the user's response.
I'm sure there are great solutions using Ajax or jQuery but this is a fairly simple function that shouldn't take too long to develop, so that is kind of out of scope for this.
Instead I'll go with a solution where I know what the user will respond to the question before they click the button. (While silently muttering under my breath: "It's 2019 and there's no good way to fire up a yes/no dialog from code behind in a .Net web project...". I need to get back to not working with web).

Avoid ASP.NET special behavior of Ajax controls

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};

Validation using navigation

I have some pages in my website and a left menu control. Control helps to navigate from one page to another.
My query is -> While user try to navigate to another page, I want to impose some validation like in the current page if the form is not saved, user will be asked to save it by using a confirm messagebox and if user presses no button, then user will be allowed to navigate otherwise, system will first save the details and then navigate.
Edit - My page is a content page, I meant, this is using a master page.
Use the following steps
window.onbeforeunload = confirmExit;
and a function that stops/continue the page execution.
function confirmExit() {
var email= document.getElementById("email");
if (email.value != "")
return "You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?";
}
The way I would do this is to have an onbeforeunload javascript event fire which gives the user the choice to save the form. I personally would also poll the form saving data back whist they are completing it. I think this is the method SO uses.
There is a pretty decent example over on Code Project that may help http://www.codeproject.com/KB/aspnet/AutoSaveFormData.aspx
EDIT:
If you only want to call the save method you can mark it with the [WebMethod] filter and call it using XmlHttpRequest or jQuery's $.post

How to load a page with its default values after a postback

I'm creating user controls that i will put into an update panel and make them visible only when required using triggers. Once visible it will float in a dialog box so it has a close button which will just hide the control on client side.
The controls have multiple post back states, like a wizard, i'm using a multi view control to accomplish that. My problem is that once the user is at step number two in the control, if the user closes the dialog, than opens the dialog again, (note that the control is made visible on the server and reloaded by updating the updatepanel) the second step will still be displayed. The reason is . because whenever there is a postback the control will load its state using the viewstate, even if EnableViewState is false it will still load it using the LoadControlState method. so my quesion is how can i force a user control to load fresh with its default values without any postback data.
We had a similar circumstance and the only way we found to reset our control was to do that in the code behind of the page. Not in an ajax call but on submit of the page because then we could set the properties and have them go into viewstate.
i'm pretty sure that that will break your design though.
Have you considered writing the page as RESTful? At least then you can ditch viewstate and read and write to a meaningful data store.
ViewState is probably the number one reason I went over to MVC and now avoid WebForms like the plague.
If its a wizard that uses a dialog and each step is required, dont have a close button.
If the user closes it you could refresh the whole page so the user has to start again?
I had so many issue like this with WebForms, where I was only using the UpdatePanel for ajax as it "looks" like an easy option. MVC sounds like a bit of a learning curve and it is, however you can acheive things by building pages with MVC and jQuery without MS ajax and the hassle of all the events in a page that constantly fighting with each other. Its difficult to make this step without knowing MVC and geetting your hand dirty, but its worth it.
Its is possible.
I found a secret method in the control class, called ClearChildState(), this is a protected method and will clear the viewstate and the controlstate for all childcontrols.
So in my example, i created a class that inherits from panel
namespace MyControls
{
public class Panel:System.Web.UI.WebControls.Panel
{
public void Reset()
{
ClearChildState();
}
}
}
In my page initialize event i check for request[flag] to reset the control
public partial class Test : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (!string.IsNullOrEmpty(Request["Reset"]) && Request["Reset"] == "1")
{
pnlCreateAccountDialog.Reset();
}
}
}
OnClient side i have a Reset() function that i can call whenever i want the next postback to load a clean control
<script type="text/javascript">
function AddReset() {
$('#Reset').val('1');
}
function RemoveReset() {
$('#Reset').val('');
}
</script>

asp.net webforms and jquery: How to save/restore jquery state between postbacks?

I am building a asp.net webforms (3.5 sp1) application, using jquery where I can to animate the UI, change its state. It has worked great until I started doing postbacks, where the UI obviously resets itself to its initial state.
So my question is, what are the best practices for saving and restoring jquery/UI state between postbacks?
Thanks, Egil.
Update: Thanks a lot guys, great input, to bad I cant mark more than one answer as the "answer".
I typically store things like menu state or filter (set of inputs in a div) visibility, etc. server-side in the session via AJAX. When a menu expands or a filter is shown, the click handler will fire an AJAX event to a web service that will record the state of the menu or filter visibility in the user's session. On a postback I use the session variables corresponding to each menu/filter to set it's initial state via CSS. I find that this is better user experience since the page doesn't flash when it is updated by javascript after loading if you make the changes client-side.
Example -- as I'm on the road this not actual code from a project and may be incomplete. Uses jQuery. The Url for the web service is going to depend on how you implement web services. I'm using ASP.NET MVC (mostly) so mine would be a controller action.
<script type='text/javascript'>
$(document).ready( function() {
$('#searchFilter').click( function() {
var filter = $(this);
var filterName = filter.attr('id');
var nowVisible = filter.css('display') === 'none';
if (nowVisible) {
filter.show();
}
else {
filter.hide();
}
$.post('/controller/SetFilterVisibility',
{ name: filterName, visibility: nowVisible } );
});
});
</script>
<div id='searchFilter' <%= ViewData["searchFilterVisibility"] %> >
...
</div>
Server-side code
[AcceptVerbs( HttpVerbs.POST )]
[Authorization]
public ActionResult SetFilterVisibility( string name, bool visible )
{
Session[name] = visible;
return Content( string.Empty ); // not used...
}
[AcceptVerbs( HttpVerbs.GET )]
[Authorization]
public ActionResult SomeAction( int id )
{
...
ViewData["searchFilterVisibility"] = Session["searchFilter"];
...
return View();
}
I think you are referring to saving the state of the ui widgets between postbacks (rather than saving user preferences).
A lot of that state is applicable only to a particular widget, for a particular user, after a particular series of interactions (eg expand this tree node, click on that grid row, etc). This stuff doesn't have to go into the database, or even in the session, unless restoring state across page loads is important to you.
All that stuff I tend to put into an object or two, eg:
treeState.expandedNodeId = 'foo';
gridState.selectedRowIndex = 3;
Then I save it in a hidden field periodically:
$('.treeState').val(Sys.Serialization.JavaScriptSerializer.serialize(treeState));
etc.
The value is sent back with the postback result, and I just deserialize it and restore my widgets from the saved values. Annoying, but it works well.
You have two options:
Client side cookie
Store UI settings server side via postback or webmethod calls
The second option will require alot more effort but would allow you to provide 'portable' UI settings that could be applied for a user regardless of client machine. If the settings are 'throw-away', I would go for client side cookies.
How to work with javascript and cookies:
http://techpatterns.com/downloads/javascript_cookies.php
I generally store UI settings server side in a database via postbacks, however if users are changing their UI via jQuery and you want to persist those changes, I would probably go about it something like this:
add a script manager to your aspx page
set EnablePageMethods="true"
create a WebMethod in your codebehind
in your jQuery methods that update the UI, add a call to your WebMethod and pass back the UI setting
store any settings passed to the WebMethod in the database
then when the user visits the page the next time, either fetch the settings and populate as many controls server side as you can, or use the jQuery ready method to make a call to another webmethod that fetches the UI settings from the database, passes them back to jQuery allowing you to populate the controls.
Here is a decent article on jQuery and WebMethod calls:
http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/
The problem you will need to be aware of is EventValidation; you will get into trouble if you fetch control values outside of the scope of the page lifecycle and then expect to use those settings on postback. For example, adding values to a dropdownlist via a webmethod will throw an error on postback, unless those values were also added to the dropdownlist when the page was built.
I'm using HTML5 storage, you can choose how to persist (local storage or per browser session). If you're worried about non HTML5 you can use Amplify.Storage. The downside is that you have to write the code to call the save/read. I'm looking at a way to automate this, if anyone has any ideas then please say. Thanks.

Resources