execution order when running a javascript inside ASP.Net - javascript

I am noob to ASP.net.
I was trying to add a confirmation popup to webpage.
I used the following code :
(which is a variant from this one: http://www.codeproject.com/Articles/8173/A-Simple-ASP-NET-Server-Control-Message-Box-Confir )
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Text;
namespace BunnyBear
{
[DefaultProperty("Text"),
ToolboxData("<{0}:msgBox runat=server></{0}:msgBox>")]
public class msgBox : System.Web.UI.WebControls.WebControl
{
//private string msg;
private string content;
[Bindable(true),
Category("Appearance"),
DefaultValue("")]
public void confirm2(string msg)
{
string sMsg = msg.Replace("\n", "\\n");
sMsg = msg.Replace("\"", "'");
StringBuilder sb = new StringBuilder();
sb.Append(#"<script language='javascript'>");
sb.Append(#" if(confirm( """ + sMsg + #""" ))");
sb.Append(#" { }");
sb.Append(#" else { ");
sb.Append( "document.forms[0].submit(); }");
sb.Append(#"</script>");
content = sb.ToString();
}
protected override void Render(HtmlTextWriter output)
{
output.Write(this.content);
}
}
}
I try it from a test class as follows :
//event triggered when clicking a button
protected void Button2_Click(object sender, EventArgs e)
{
msgBox1.confirm2("are you sure?");
MoreCode();
}
I was expecting that when I click on the button, the confirmation popup pops and asks if I want to confirm:
if I click "no" : postback occurs so MoreCode() is not executed
If I click "yes" : no javascript code is executed, so the execution goes on and MoreCode() is executed.
This is not what happens.
When I click the button with the step by step debugger, I can see that :
it executes msgBox1.confirm2("are you sure?");
it then executes MoreCode()
and afterwards the popup pops
Could you pls explain me why this is executed in this order?
Thanks in advance.

MoreCode() is running on the server side, whereas the popup is on the client side. They are independent operations. If MoreCode must run after the button click, then you need to have a callback in your JavaScript, appending it after
sb.Append(#" if(confirm( """ + sMsg + #""" ))");
The callback would bind to a server call, and that server call would execute MoreCode.

Since you are not using any AJAX, the order of operations is clear: all server-side code is run, then HTML is returned to the browser where the browser executes any necessary client-side code. Here is what happens, in order, starting from when your Button2 is clicked:
Button2_Click server event is called. This event does everything it is asked to do: create a string that will be injected to the resulting HTML page, and then run MoreCode(). Control has not yet been returned to the browser--all this processing is handled on the server-side.
HTML for the resulting page is rendered, along with the string you injected, which includes the JavaScript you have written.
HTML is transferred to the browser and the HTML is executed. Your script triggers a JavaScript prompt, which is then displayed to the user using the text that was specified server-side.

Related

Execute javascript after loading generic handler asp.net

I have a gridview with a list of pdf files. When the user clicks a pdf, it displays the file inline on the page. I want to execute some javascript after the pdf has been loaded but I cannot get this to work. The issue is that the pdf loads after everything else, so the load event fires before the pdf begins to load.
My first approach was to use an iframe. The inner page would retrieve the file and write the data to the response. As mentioned previously, the load event occurred before loading the pdf and I need it to trigger after. The current code uses a generic handler ashx to load the pdf inline. How do I trigger an event to execute javascript, after the pdf data is loaded server side from the ashx generic handler?
Aspx page:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "View")
{
int index = Convert.ToInt32(e.CommandArgument.ToString());
string Id = GridView1.DataKeys[index].Value.ToString();
HtmlGenericControl myObject = new HtmlGenericControl();
myObject.TagName = "object";
Panel1.Controls.Add(myObject);
myObject.Attributes.Add("data", "GetPdf.ashx?Id=" + Id);
}
}
Generic handler ashx:
public void ProcessRequest(HttpContext context)
{
System.Diagnostics.Debug.WriteLine("GetPdf.ashx started");
string Id = context.Request.QueryString["Id"];
byte[] data = GetPdf(Id);
context.Response.ClearContent();
context.Response.ContentType = "application/pdf";
context.Response.AppendHeader("Content-disposition", "inline");
context.Response.AddHeader("Content-Length", data.Length.ToString());
context.Response.BinaryWrite(data);
System.Diagnostics.Debug.WriteLine("GetPdf.ashx is done");
context.Response.End();
}
Have you tried setting an event handler for the object tag's onload event? I'm not sure if that will work across all browsers, but I also don't know which browsers you require it to work on.
Worst-case scenario you could use setTimeout to rapidly poll for the PDF's existence.
Here's a previous answer that may help you with both aspects.

call javascript function with c# methods in razor

I am trying to reload a page every 10 seconds , using Cache Scheduler method mentioned here,
I just want call a JavaScript function to reload current page when Cache is removed. But for some reason basic JavaScript doesn't work.
Razor View:
#{
AddTask("CheckStatus", 10); // reload page every 10 seconds
#functions
{
private static System.Web.Caching.CacheItemRemovedCallback OnCacheRemove = null;
public void AddTask(string name, int seconds)
{
OnCacheRemove = new System.Web.Caching.CacheItemRemovedCallback(CacheItemRemoved);
HttpRuntime.Cache.Insert(name, seconds, null,
DateTime.Now.AddSeconds(seconds), System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.NotRemovable, OnCacheRemove);
}
public void CacheItemRemoved(string k, object v,
System.Web.Caching.CacheItemRemovedReason r)
{
PrintStatus();
}
}
}
#helper PrintStatus()
{
var msg = "<script language='javascript' type='text/javascript'>
alert('Status is open!');</script>";
#Html.Raw(msg)
}
What am i doing wrong ? Or Is there any alternate way to return Javascript to reload page using server side code.
Note: I am not using Javascript set interval because Chrome has issues when the browser is minimized, so i prefer server side code to reload page every x seconds.
Any help would be great.
The cache scheduler is server-side piece of code. It is useless on client. The way this would fire is only if by some miracle the CacheRemoveItem will fire when you're rendering the view.
If I were you I'd create some AJAX service and periodically call it from javascript using setInterval.

How do I call a javascript function immediately from the vb code

This is my sciprt, it display a message box with an 'Ok' and 'Cancel' Button
<script type="text/javascript"> function Confirm() {
var confirm_value = document.createElement('INPUT');
confirm_value.type = 'hidden';
confirm_value.name = 'confirm_value';
if (confirm('Continue?')) {
confirm_value.value = 'Yes';
} else {
confirm_value.value = 'No';}
document.forms[0].appendChild(confirm_value);} </script>
On my program i'm running a query, if there are no results then i display this "Dialog" box
I want to call the function immediately after getting the query results but my current code seems to be running it after everything instead of immediately.
If reader.read = false then
If Not Page.ClientScript.IsStartupScriptRegistered(Me.GetType(), "alertscript") Then
Page.ClientScript.RegisterStartupScript(Me.GetType(), "alertscript", "Confirm();", True)
End if
Dim confirmValue As String = Request.Form("confirm_value")
If confirmValue = "Yes" Then
'Do stuff here
End if
End if
To me, this request usually represents a misunderstanding of what's going on. At the time your VB.Net code is running, the javascript doesn't exist. All server event handlers result in a full postback. That means the entire page is recreated from scratch. The VB.Net code here is part of a process that is generating an entirely new HTML document. That will involve the entire page lifecycle, including your server's Page_Load code. When the event was raised, any html already rendered in the browser was destroyed to make way for your response to a whole new HTTP request.
If you want this to respond differently, you need to build your whole HTTP response with that in mind. That means either changing how the event is raised from the outset (calling a WebMethod or other ajax request) or setting your response to call your confirm method in the javascript page load event.

Window background turns gray when showing javascript alert message

I m using some serverside validation and if any problem comes I m showing a pop up message using javascript using
page.ClientScript.RegisterClientScriptBlock
but when my message is displayed the background of the window turns gray.
can any one help me to get rid of this gray window
public static class Alert
{
/// <summary>
/// Shows a client-side JavaScript alert in the browser.
/// </summary>
/// <param name="message">The message to appear in the alert.</param>
public static void Show(string message)
{
// Cleans the message to allow single quotation marks
string cleanMessage = message.Replace("'", "\\'");
string script = "<script type=\"text/javascript\">alert('" + cleanMessage + "');</script>";
// Gets the executing web page
Page page = HttpContext.Current.CurrentHandler as Page;
// Checks if the handler is a Page and that the script isn't allready on the Page
if (page != null && !page.ClientScript.IsClientScriptBlockRegistered("alert"))
{
page.ClientScript.RegisterClientScriptBlock(typeof(Alert), "alert", script);
}
}
}
I am using this Function
Since you are using the Javascript alert() function, you have absolutely no control over how the browser handles it. Each browser looks slightly different. However, you can expect that it will be a modal popup with your content, and a single "Ok" button. Beyond that, you have no control.
If you want something different, you'll have to use more complex javascript; perhaps using a jQuery plugin to display your message exactly how you want, or overriding the alert() function.

Hiding loading image on asp.net postback for file download

I have a button on my asp.net page that does a postback, creates an Excel file, clears the response stream and writes the file. The user can then open or save the file user the brower's standard dialog.
This works great, I based the code on this:
http://www.adventuresindevelopment.com/2009/05/27/how-to-export-data-to-excel-in-aspnet/
As the file to be created takes quite a long time I have created a loading panel, just a hidden DIV, and set this to visible when the button is clicked.
But my problem is how to hide this DIV when the export has finished? I just cannot find a way of doing it. I need something like an event that fires when the file has been completely transfered to the browser.
Is this possible? Any help most appreciated.
Thanks,
AJ
What I'd do, long story short :
When the user clicks the "Download" button, use AJAX to call a
processing page asynchronously. This page will generate your Excel
document and store it in a temporary location
When the AJAX request is done, hide the "Loading" panel, and
redirect the user to a download page. Ideally, you should redirect
to a generic (.ashx) handler that opens the file, sets some headers,
streams the temporary file to the user, and deletes the file
afterwards.
Now in more details :
For step one, you should have some temporary folder where you have read and write access. Using the system temp folder is fine, so you could use Path.GetTempFileName. Here is an example of what you could write in an ashx handler :
public class Handler1 : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
string fName = Path.GetTempFileName();
context.Response.ContentType = "text/plain";
try
{
// Generate the Excel document
GenerateExcelInFile(fName);
// Store the file name in session for later use
context.Session["ExcelGeneratorFileName"] = fName;
// Send confirmation to the client
context.Response.Write("ok");
}
catch (Exception e)
{
context.Response.Write("error");
// TODO : Do some logging
}
}
// SNIP : IsReusable
}
After that, use your favorite JS framework to request that handler, and test the returned string. If it is "ok", you call the part two handler :
public class Handler2 : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/excel";
// Make sure the browser will show a "save as" dialog to the user
context.Response.AddHeader("content-disposition", "attachment; filename=Export.pdf");
string fName = context.Session["ExcelGeneratorFileName"] as String;
if (fName != null && File.Exists(fName))
{
// Stream the excel file to the response
context.Response.WriteFile(fName);
// Remove the file
File.Delete(fName);
}
}
// SNIP : IsReusable
}
You can call this page in javascript simply using a window.location = url. The content-disposition header will tell the browser that this URL should not be displayed, only downloaded, so your user should stay on the download page.

Categories