I need a very simple code in ASP.NET.
Inside any button on the page that contains a set of statement code, the user is asked to confirm the continuation.
If he agrees, it completes those orders or stops.
Please, can you help me?
if (ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('Are you sure');", true) == ok)
{
Label1.Text = "ok";
// other statements
}
else
{
Label1.Text = "no";
// other statements
}
You can not do that kind of code in web land. Remember, code behind ONLY runs when the user just clicked on a button, THEN whole web page travels up to the server. Code behind runs, AND THEN whole page travels back down to client side browser. The page loads, renders and THEN even the JavaScript code STARTS to run. On the server side, the web page is un-load - blown away to bit. The web server is now waiting for ANY web page to be posted - not necessary your page!
So, code behind NEVER EVER can and will interact directly with the user. The code behind ONLY can touch, modify the web page that is up on the server for a VERY short period of time.
If you say do this:
TextBox1.Text = "Hello how are you?";
ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('Are you sure');", true) == ok)
Or this:
ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('Are you sure');", true) == ok)
TextBox1.Text = "hello world";
The effect is the SAME.
What happens is this:
So, now the web page travels up to the server.
You code can modify that text box. And THEN inject the JavaScript block.
You get this:
The code behind runs. It will inject the JavaScript, runt he code to set the text box.
at this point, what does it matter if I set the text box first, or inject the JavaScript? the page is up on the web server, just sitting their. The user sees that web "wait" spinner.
Now, when you code is done, (and the user STILL DOES not see any changes yet), then the the WHOLE page is sent back to client side like this:
Then whole page re-loads, then JavaScript starts running again, and our injected block of code will NOW run!!!
So, as you can see with above, we don't really interact with the user directly - and in fact we can't!!! - the web page travels up to server - your code behind runs and has a very short little window of time to modify the page, and then the WHOLE page is send back to client, page is re-plot, re-load, and then JavaScript runs again.
So, you not able to "wait", since any code that waits will result in the web page sitting stuck up on the server side.
So in above, the order of the two commands don't matter much, does it? I can modify the text box, or inject some script - but NONE of that will run nor be seen by end user until such time the WHOLE page travels back down to the client side.
So, Any changes to the page, and even in different order in most cases does not matter. Your code is making changes to the web page BEFORE the WHOLE page will be transmitted back to the client side. So, in most cases, the order of things and controls you change on a page don't matter, since those changes can't be seen by the end user until ALL OF your code behind is done, and then the whole page starts the trip back to the client side.
So, in effect, grasping this concept of the round trip is really quite much the most fundamental concept you need to always have clear in your mind to write web code with asp.net. You really can't do web development without the above.
So, we can however add to the button, and use a confirm() like this:
our plane jane asp.net button?
It will now have two routines!!!
It will have the client side click event. This part does the dialog or prompt. If the user answers yes, then we allow the button click (server side) to run. But remember such code can only run client side - that means the WHOLE page has to be sitting on the users desktop - no code behind running at that point.
So, in the most simple format, say we have a button to delete a record.
But, a simple click on the button - rather dangerous.
So, you can add a code stub (JavaScript) to the button like this:
<asp:Button ID="cmdDelete" runat="server" Text="Server delete prompt"
OnClientClick="return confirm('Really delete this file?');" />
So, when we click this button, you get a JavaScript prompt. And if it returns "true", then the button code behind REALLY does run.
So unlike desktop code, you can have that "old way" of say a if/then block of code, and based on a user prompt, conditional run that code. (because code behind ONLY runs during that so called post-back (round trip).
so, the above will work just fine, and looks like this:
Now, of course the "main" issue is that the browser built-in dialog prompts do look rather ugly.
Using nice dialog boxes?
Of course, with the exception of "alert()" and "confirm() in JavaScript which HALT code in the browser? In most cases this is not allowed anymore - since it can lock up and freeze the browser.
And thus, now , Almost EVERY new nice looking "add-in"? Code as a general rule in JavaScript does NOT wait anymore - it runs asynchronous.
So, say we using jQuery.UI and we want to dump the VERY ugly built in browser alert() or confirm dialog?
You can do it this way:
<asp:Button ID="cmdTest" runat="server" Text="Server Delete Prompt" ClientIDMode="Static" style="display:none"
OnClientClick="return mytest(this)"/>
<br />
<div id="MyDialog" style="display:none">
<h2>my cool dialog text</h2>
<h2>This delete operation can't be undone</h2>
</div>
</div>
<script>
var mytest2ok = false
function mytest(cmdBtn) {
if (mytest2ok) {
return true
}
myDialog = $("#MyDialog")
myDialog.dialog({
title: "Delete the whole server system",
modal: true,
appendTo: "form",
autoOpen: false,
buttons: {
ok: function () {
myDialog.dialog('close')
mytest2ok = true
$(cmdBtn).click()
},
cancel: function () {
myDialog.dialog('close')
}
}
})
myDialog.dialog('open')
return false
}
</script>
In this case, we again call and setup a OnClientClick. But, jQuery.UI code as I noted does not wait. So we click on button, our dialog displays and the JavaScript code runs through and finished!!! - that's why we added the ok flag.
So, the dialog is displayed. User hits ok, and then we run the "ok" code stub, and it sets our flag, and clicks the button again!!! - this time the client side button code returns true and the server side button click will run. This code looks like this, and allows you a nice looking dialog, and in effect the SAME reuslts - a pop dialog to conditional run or not the code based on user input.
jQuery.UI lets you use the content of a "div" for anything you want in the dialog.
So, we now have this:
So, this is a web based dialog box - it even makes the screen go "gray-darker" for you. And it is model. But, the code is not frozen, and when you click ok, then the "ok" stub runs, and clicks the server side button for you again.
So, in most cases, you have to:
Pop the dialog in the client browser, and THEN choose to click or run the server side button code if you want.
Could you do this 100% server side? well, you probably could if you used TWO buttons, and hide the 2nd button. So, you click on first button. Server side code runs and injects the JavaScript to pop dialog, and then based on yes/no, then the 2nd button will be clicked on and your server side code stub will run. But NOTE VERY close, this would suggest and mean you again NEVER are waiting in the middle of your code stub server side, but going to pop a dialog, and then based on user answer, another button code will run server side.
As noted, it thus an advantage to put the dialog box in FRONT of the server side button by using client side code to determine the yes/no choice.
So, based on user input, you either click (run) the button server code code, or you do not. But there not a practical means to "halt" the server side code in the middle of a code stub to wait for a prompt, since referring to above diagram, you can see the web page when up on the server does not have any user interaction, but your code can only modify the web page BEFORE it makes the trip back down client side.
So, almost always, we need a client side code bit, and then we choose yes/no to run that button.
So, code behind NEVER interacts with the user, but can ONLY ever wait for a WHOLE web page to be sent up to the server (for code behind to run).
Related
I want to create a dialog confirm in ASP.NET.
I'm doing it with this code:
protected void Button1_Click(object sender, EventArgs e)
{
ClientScriptManager CSM = Page.ClientScript;
string strconfirm = "<script>if(!window.confirm('Are you sure?')){window.location.href='Default.aspx'}</script>";
CSM.RegisterClientScriptBlock(this.GetType(), "Confirm", strconfirm, false);
if (the condition to yes clicked)
{
// do something ....
}
else
{
// do something else ....
}
}
How can I get the yes / no condition in this case?
Thanks for reading my post
You can't do it this way. Your code behind NEVER interacts with the user. Your code behind ONLY interacts with the web page, and ONLY does so WHILE the page is making the round trip.
Before a post back? You have this setup:
You do NOT have this:
And you do not have this either:
So, when a user clicks a button - this occurs CLIENT side. The page - whole web page is sent up to the server - and THEN your code interacts with the web page - NOT the user!!!
so, you click on a button - (browser). The page THEN starts the all important round trip. Like this:
the page travels up to server,
You now have this:
Now and THEN your code behind runs. When done, your code behind MUST finish, else the page stays stuck up on the server side. When done, the whole page page makes the trip down back to the browser. And THEN the page is re-displayed and THEN any js code can run.
So when done? Your page makes the trip back down to the browser like this:
And only AFTER the page makes that trip, can the browser display what your code behind changed. So your code behind NEVER interacts with the user, but in fact can ONLY interact with the web page and ONLY do so for the short time that the web page is up on the server.
So, how can you pop a dialog and get a yes/no answer? Well, you require the dialog to run and launched client side. And based on the user hitting ok, or cancel, you can THEN have a code stub run.
So you can say have code that flows like this:
ClientScriptManager CSM = Page.ClientScript;
string strconfirm = "<script>if(!window.confirm('Are you sure?')){window.location.href='Default.aspx'}</script>";
CSM.RegisterClientScriptBlock(this.GetType(), "Confirm", strconfirm, false);
Function OkCode - runs on user click or seleciton.
Function Cancel Code - runs on user click of cancel button.
So, you need 3 code stubs. One to inject the script that will pop the dialog. And then the ok or cancel button in that script/dialog can THEN launch the server side code again. This will of course require that round trip (as all server side button event code does).
There are a few short cuts. Say I have a standard asp.net button, and I want a confirm dialog? Well, you can do this:
<asp:Button ID="Button1" runat="server" Text="Delete"
OnClientClick="return confirm('Delete record');"/>
The above works, since the confrim in js returns true or false and that will prevent the button code (code behind server side) from running.
You could of course have a script that you call from code behind. Keep in mind that your register script quite much has to be the LAST thing you do and inject into that page before it travels back down to the client. The page dispays and THEN your script you added THEN runs!
You could say then have two buttons on your form - hide them. And then have a js dialog that clicks either button based on what you pass.
So, say we build that function. We will pass it the question/text, and then say two buttons (one for ok click, and one for cancel click). And you could set the style of those buttons as display:none. This will still not get you a server side if/then result from that dialog. So, you have to quite much in near ALL cases break your code out to 3 seperate parts.
The part that triggers the dialog.
And the two buttons that run code behind stubs based on the choice(s) the user makes. In other words, adding the dialog by script would STILL require you to have TWO separate code stubs behind to run (the one for ok, and the one for cancel). You simply can't pop a dialog server side and wait. That would result in the web page being stuck up on the server in the above round trip concept. That round trip dialog MUST be absorbed into your mind - without that model of how the round trip works, then you make mistakes in your design assumptions - and thus your question which is actually not really possible to achieve.
You could create a generalized dialog that you set the text in code behind along with your register script idea. but the button choices and code it runs would also have to be setup in that register script, and you would still require two separate code behind stubs (one for cancel, and one for ok). So it would be possible to setup something that requires you to NOT have special code in each page, but you would require a js function routine you build up, and you would have to supply it the name of the two code stubs, and then that js routine could send a __DoPostBack passing the choice made.
But even again, note how you need separate routines, since that web page is sitting on the users desktop, and your code behind is not waiting for a dialog, but in fact a WHOLE PAGE post back.
So just keep mind that code behind does not interact with the user - it ONLY interacts with the web page, and ONLY does so during that short round trip and in fact ONLY during the time that the web page is up on the server, and your code behind runs and then is finished. And THEN the web page starts that trip back to the client side - the page is re-loaded, changes you made are displayed, and THEN the js in that page starts to run again.
Hi i am trying to enter 1 or 2 digits in a text box in asp.net c#. I want to focus in the next text box.
Here is my code but it throws an error that the textbox1 is being accessed from a different thread that it was created.
private void textBox19_TextChanged(object sender, EventArgs e)
{
Thread t = new Thread(() => {
Thread.Sleep(2000);
textBox1.Focus();`
}
);
t.Start();
}
Ok, first up, you need to grasp and understand the concept of a round trip.
next up, the text changed event does NOT fire until the user is finished typing in that text box and hits TAB. So you can't really do key press processing with code behind.
When you hit tab, then a post back occures. This is is the ALL IMPORTANT start of the round trip. If you do not with absolute certaintity grasp this concpet, then all your fortay into asp.net pages will be lost, and you will forevermore be 100% lost. you must, absolute must grasp this concpet.
So Our round trip:
A button is clicked, or a event is triggered for htat control (keypress processing will not work - it is WHEN the user hits tab).
So, button click or tab on that control.
Post back occures
The WHOLE web page travels up to the server.
When we say whole page, we mean ALL of the browser HTML, all of the whole page
This includes all controls, all graphics, all HTML - the whole deal
Now the page is at the server.
The asp.net processes the market.
THEN your code behind runs. At this point your event code runs
In your event code, you can say modify a value of a control.
Now:
Then the WHOLE PAGE travels back to the browser and is refresed and displald.
The page is now sitting back on the client side browser.
So as the user types. Clicks into a text box etc.? The browser is allowing this.
The server is not being talked to (unless you trigger another post-back (round trip).
So, as the user is typing in that text box?
As the user is editing that text box?
This is ALL occurring browser side. You are NOT talking to the server and those round trips are NOT occuring.
So you can't say put some timer on the text box and look/check/see/hope for a change in what your code sees. None of that code is going to run untill that page post back occures and the round trip starts.
A round trip is expensive, and in general is NOT appropiate for keypress processing. If you were to setup a full page post back for EACH keypress, then each key press would be JUST like a submit button - the whole page has to travel back up to the server.
So, now that you grasp the above?
Well, then you can't loop/pool/test the value of a text box with code behind on the server You can ONLY see/use/check/modify/play with controls on the form AFTER the WHOLE WEB PAGE has been sent up to the server. Thus single key press processing is not practial.
Ok, so what can we do here?
Most simple is to use client side code. Simply check the length of the text box, and if it 2 characters, then set the focus to another control.
So, lets drop a text box on a form, and we can use this markup for this to work:
<asp:TextBox ID="TextBox3" runat="server"
onkeyup="mykeycheck()" >
</asp:TextBox>
<script>
function mykeycheck() {
vTextBox = document.getElementById('<%= TextBox3.ClientID %>');
if (vTextBox.value.length == 2) {
document.getElementById('<%= TextBox1.ClientID %>').focus();
}
}
</script>
So, now, our focus will jump to Textbox1, and we don't have ANY server side code.
Can we "some how" do single key press checking and run server side code?
Well, yes, you can. But then again, that huge large round trip process will occur.
We can however, I suppose introduce a update-panel. This would suggest that the text box is OUTSIDE of the up-date panel, and we could say for example display the results of the text box, and run code behind for each keypress. I can post the code and how to do this, but in general, having a full round trip for each keypress is quite much the same idea as having a submit button for every key you press - quite heavy.
So, I can't stress how absolute important it is to keep in mind that to run/use/have code behind interact with the web page, it can only do so during that "small" time when the page is been posted up to the server, and your code runs, and then the WHOLE page is now re-send back to the browser side. And you code behind can only see/touch/modify/use the controls on that page WHILE the page is up on the server during that round trip. But it not going to stay up there very long - and after all your code runs, the WHOLE page is now send back down client side. And this would also mean that even simple things like your cursor position in the text box would be lost. You can VERY much think of the round trip process VERY much like as if you just had hit the refresh key.
So, you not use nor need any code behind in the text changed event. However, DO keep in mind that when we use the above client side JavaScript, that when we change the focus, if you do still have a server side text changed event wired up, (and postback = true for that text box), then the server side code WILL run, and a post back will occur. Since we really don't need nor want a postback to occur, then of course we will remove that text changed code stub, and turn off the post-back setting for that text box.
I have a very simple page I'm intending to use to show the contents of a network file. The target file is brought in with the Ajax Toolkit AjaxFileUpload control. It works, and I can see the file contents when stepping through the debugger. The offending behavior, however, is that once the file is uploaded, the codebehind loses all ability to update the page. I cannot write the file contents to a multi-line TextBox. I cannot even update a label on the page. Neither can I write hard-coded "Test Text" to the TextBox or Label.
There are no errors or exceptions throw. The code runs to completion without writing the contents to the TextBox.
<h2>
Encrypted File Viewer
</h2>
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:Label ID="ViewingLabel" runat="server" Font-Bold="false" ForeColor="Green"></asp:Label>
<br /><br />
<asp:Button ID="UnauthorizedExitButton" runat="server" Visible="true" OnClick="DoExit" Text=" Exit " />
<br /><br />
<Ajax:AjaxFileUpload ID="AjaxUploader" runat="server" OnUploadComplete="FileOpen" width="800px"></Ajax:AjaxFileUpload>
<br /><br />
<asp:TextBox ID="Viewer" runat="server" Width="800px" Height="500px" TextMode="MultiLine"></asp:TextBox>
In FileOpen()
string tempPath = Path.GetTempFileName();
string tempPath2 = Path.GetTempFileName();
AjaxUploader.SaveAs(tempPath);
myStrUtility.DecryptFile(tempPath, tempPath2);
Viewer.Text = File.ReadAllText(tempPath2); //Fails
// For testing - Debugging
ViewingLabel.Text = File.ReadAllText(tempPath2); //Fails
Response.Write (File.ReadAllText(tempPath2)); //Fails
I'm completely baffled by this, since I can see the decrypted contents of tempPath2.
Thank you in advance for any insights you can offer.
Ok, I have a few minutes.
If you have a bunch of text boxes on your screen. You fill them out.
(no postback has occured yet). So, ANY server side code that runs will NOT have use nor see nor be able to get use of those controls.
So, you enter some stuff into text boxes. You then select a file to upload. You then hit the upload button.
Now, your 3 server side events will run. But the WHOLE idea of AJAX is you don't have to do nor want a page post back to have occurred. And a page post back has NOT occured!
So, now when the 3 server side events (from ajax file upload run), we have:
Start of upload event - server side runs. But again, that code in the form behind will NOT have use of any controls changed.
Single file upload compilate - your server side event code runs. But again, due to no post back having occurred - then any control changed or text entered into controls is NOT available yet.
Final all files upload event - again server side event code runs, and again you can't get or use any controls on the form that changed.
Several solutions:
Any text boxes, or data entered or changed? You need some kind of "ok buttion", and that button does the post back - in that routine, you THEN turn on (display) the up-loader.
Now the user can select file(s), and start the upload. For the 3 ajax events (start of up-loading), single file done, and then all done event can all run server side with use of your controls.
So, just keep in mind that you can enter a bunch of data into the form, and then use the up-loader (select files, then upload button). For this whole process no page post back occurs
Worse? If you put a submit button on the page, and the user has selected files, and then decides to hit the post back? Well the ajax uploader does NOT persist the files selected during a post back. This is why I strong suggest you hide the up-loader (can't use visible, you have to use style).
The most simple solution is if you have a group or bunch of controls on the form that you need to set or will have data/changes made before they start a upload?
Put the group of controls in a up-date panel. And set auto post back for each of the controls. So, any control you edit will now cause a post-back. Now, such data is available in server side code. (and that includes the 3 ajax up-loader server side events).
Do keep in mind that this up-date panel will result in what is called a partial post back (the on-load event will fire).
So, the behavior you are seeing is not a surprise at all. You also can NOT hide/show or change values of controls in the 3 up-loader events because as noted, you will be changing values of controls, but the page has NOT been posted back. If you attempt to change controls in the 3 events, whatever you do will be lost if/when you/users do eventually post back the page. Remember, you have a stateless web page on the desktop.
If that stateless page has not (yet) been posted back, then the 3 ajax server side events can't see the client side browser controls at this point in time. And if your change controls in those 3 events, you are changing the controls sitting server side, but the web page is not going to be updated.
So, you either have the controls on the page do a post back BEFORE they select files and start up-load. As noted, I often "hide" the ajax file up-load. Let user enter some stuff, and then have a "ok - now lets up-load files". When they click that button, your server side code runs, you do whatever, and then turn on (display) the ajax up-loader. At that point then ajax upload events (the 3 server side events) can run, and that code now has a posted back copy of the client browser.
Now, assume the very last ajax event (all files uploaded) has occured. You can now try and modify controls on the page, but the page is still sitting client side. It has NOT been posted back. And you not going to be able to post that page back between the start of the up-loads, and when you finish. If you simply run a bunch of code in the final event and try to update controls and values on the page - you can't!! Because no post back has occurred and the controls and their values are still sitting client side.
Another way to achieve this goal is to use a client side javescript event tied to the LAST ajax event (all files done). However, that means the 2nd event (one file done, and save-as file) will NOT have use of controls if you start the up-load BEFORE the page has been posted back.
So, this means that if you going to use controls during the up-load (start to finish events), or run code in that final event that modifies controls? You need the page posted BEFORE you run the up-load process.
You can try can change all and any controls with code in that 3rd final server side event, but you modifying controls in the server side browser copy. You not see ANY changes take effect. It will thus seem like you cant modify anything.
So, in a good deal of up-loads? Well I want something to occur AFTER all is said and done. This means that the 3rd final event of the up-loader needs a client side event (and it will have a __dopostback() js command. The up-loader is VERY well built in that the client side JS events ONLY fire AFTER the server side events are complete.
So that final post-back trick/tip is ONLY of use if you want something to occur after all is said and done. But this tip don't help you get at controls in the 3 events, and as noted, unless you send the browser page back to the server, then any code you run server side will NOT show up in the browser. In other words, if you want some updates, or message boxes on the screen to update at the end of the load? You cannot use that 3rd final ajax code stub. You have to do a post back BEFORE you attempt to modify anything on the page.
(else you be modifying the server side copy of the browser without having posted back the client side browser copy that is "different" and not the same.
So, those 3 events can't modify any controls, since the page not been posted, and when you eventually do post the page, what controls you modify will be lost/overwritten when the client side browser post back occurs.
So you not losing the ability to modify controls on the page in that 3rd last event, but you modifyng a copy of the server side page - and you never see the changes.
So, with a standard asp.net buttion:
we have:
Post back (browser page goes to server)
Your code (any code behind) can run, can see, can grab/set/see/change any control on the form.
Now browser is re-sent back to client and displayed. (so you can see your server side code changes in those controls.
With the ajax uploader, no page post back has occured, and no re-rendering of the browser will occur. (those controls and events don't cause a post-back). So, you can't run server side code to change things, since you don't have a copy of the client side. And even if you do modify controls, no page is sent back to the client side to re-display.
So, based on the above asp.net model and code behind? You can't change controls unless your server side code runs as a RESULT of a post-back.
So, either get your post back all done and wrapped up BEFORE uploader runs, since those 3 server side events can't modify controls, and will not see client side changes unless you do/did a post back BEFORE the upload starts.
Just put auto-post backs in the controls. But then auto post backs for the several controls does cause a whole page post back. So, you can "mitigate" this by placing the group of controls in a update panel. Or, as noted get all your controls loaded up and set with a post back that THEN displays the up-loader for the user to start.
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).
Here's my situation.
I have a button on my ASP.NET webform. This button creates a new browser window pointing to a page which has a lot of hidden fields (which are dynamically generated). This form submits itself to SQL Reporting Services on the bodies onload event. This works fine and the report is displayed in this new window.
However, now I want to still POST a form to SQL Reporting services but I want to get back an excel spreadsheet. So I add another hidden input with a name of rs:Format and value of Excel. This works and the user gets the option to download the excel file.
However they are now stuck with the extra window that was created. How do I get around this? I've tried creating the dynamic form and POST in the same window, but then they see the (empty) page with the form, and not the page they generated the report from. I've tried closing the window that I've created but I don't know where to put the javascript to do this. If I put it on the onload, then the window closes without the form being submitted.
Any ideas for what to do here?
Edit: What I was doing here wasn't the best way of getting the result I needed. I ended up using a WebRequest to get the excel report from Reporting Services instead posting a form, therefore I didn't need the second window afterall.
Don't close the browser. It belongs to the user, even if you opened it. Closing it can make them mad.
Do redirect to a page the communicates to the user that you're done with the window. There you can provide a (javascript-based) link that make closing the browser a little easier if you want, though closing a browser window is generally pretty easy.
By the way, if the popup doesn't contain any useful output, what you may want to do is submit your form into a small Iframe within the page. This way there's no need to close a window, as the frame can be made invisible.
When user wants an Excel file, there's no need to pop up another window. I assume selection of Excel file or HTML report is done in some HTML control like a radio button or a checkbox. So, before doing anything, check the value of that radiobutton/checkbox with javascript and do the appropriate action. Something like:
function getReport(excelFormat)
{
if (excelFormat)
document.form1.target = '_blank';
else
document.form1.target = '_self';
document.form1.submit();
}
What if the button did an Ajax request back to the original page and got the hidden field values. You could then construct another form on the page with the hidden fields using javascript and submit it -- with the download option. Since the request will return an application/ms-excel file, it shouldn't refresh the current page but the download should still occur. You'd need to make sure that the button click didn't cause a postback by returning false from the client-side function. Note that this only works if the post of the generated form results in a download, not a new html page.
<script type="text/javascript">
function submitReport( button ) {
PageMethod.SubmitReport(onSuccess,onFailure,{ control: button });
}
function onSuccess(values,ctx) {
var form = document.createElement('form');
form.action = reporting-services.url;
form.method = 'post';
document.body.appendChild(form);
.... add hidden fields to form from returned values
form.submit();
document.body.removeChild(form);
}
function onFailure(error,ctx) {
... pop up some error message....
}
</script>
...
<asp:Button runat="server" id="reportButton" ClientClick="submitReport(this);return false;" Text="Report" />
Generally it's ok to close any popup window that your app has created.
This can be done with window.close() (which will pop up a confirmation if the window was not created by script).
If you want to be sure that the download is successful before closing the window, you will need to perform some server-side magic - have your server keep track of the download in progress, and poll it via AJAX from the popup window until the download completes.
Once the server tells you it's done, the window can be closed.