Ketone Cops

August 21, 2009

Modal Popup with Progress

Filed under: Ajax,ASP.NET 2.0,Javascript,programming — delroger @ 12:42 pm

I was interested in using a Modal Popup to prevent trigger-happy clicking by impatient users when my web app was doing a processing job for a few seconds.  I came across Matt Berseth’s excellent work here http://mattberseth.com/blog/2007/07/modalpopup_as_an_ajax_progress.html and decided that it would be useful to make a class file for Sample 3 on that page.  So here it is…

This assumes that you have a modal popup extender and a panel on your page that will display the animated gif.  This is the code for mine (almost identical to Matt Berseth’s):

<ajaxToolKit:ModalPopupExtender
ID=”mdlPopup” runat=”server” TargetControlID=”pnlPopup”
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/ajax-loader.gif” />
<span>Processing…</span>
</div>
</asp:Panel>

The class file then looks like the code below. It contains one Sub that takes the name of your modal popup and the delay before displaying it (in milliseconds) as parameters, injecting the necessary javascript into your page for displaying the modal popup/progress when processing is occurring.

Public Class clsModalProgress
Public Shared Sub DoModalProgress(ByVal mdl As AjaxControlToolkit.ModalPopupExtender, ByVal delay As Integer)
Dim pg As Page = HttpContext.Current.Handler
If Not pg Is Nothing Then
If Not pg.ClientScript.IsStartupScriptRegistered(“progressScript”) Then
Dim t As Type
t = pg.GetType()
pg.ClientScript.RegisterStartupScript(t, “progressScript”, _
“Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequest);” & Environment.NewLine & _
“Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);” & Environment.NewLine & _
“var count;” & Environment.NewLine & _
“function beginRequest(sender, args){” & Environment.NewLine & _
”  count = setTimeout(“”showProgress()””, ” & delay & “);” & Environment.NewLine & _
“}” & Environment.NewLine & _
“function showProgress(){” & Environment.NewLine & _
”  $find(‘” & mdl.ClientID & “‘).show();” & Environment.NewLine & _
“}” & Environment.NewLine & _
“function endRequest(sender, args) {” & Environment.NewLine & _
”  clearTimeout(count);” & Environment.NewLine & _
”  $find(‘” & mdl.ClientID & “‘).hide();” & Environment.NewLine & _
“}”, True)
End If
End If
End Sub
End Class

You can simply call it in the Page_Load or Page_Prerender subs like this:

clsModalProgress.DoModalProgress(mdlPopup, 100)

In this case, the modal popup will display if processing take longer than one-tenth of a second.

Advertisements

February 10, 2009

Programmatically open and close Accordion Panes

Filed under: Ajax,ASP.NET 2.0 — delroger @ 1:47 pm

If you have an AJAX page in ASP.NET that contains an Accordion control, you may find you want to open and close the different panes from events other than clicking on the header. You can set the SelectedIndex property of the Accordion in your code-behind, but this does not use smooth transitions. However, you can use javascript to invoke the set_SelectedIndex method, which will contract the currently-expanded pane and expand the new one. Tip 3 on this page…

http://www.dotnetcurry.com/ShowArticle.aspx?ID=215

…shows you how to do that.

However, if you are using Master pages, the ID of the Accordion control will be different and so you will need to set this programmatically in code. Create a Sub like this…

Private Sub AccordionTransition()
If Not Page.ClientScript.IsClientScriptBlockRegistered(“changeSelectedScript”) Then
Dim t As Type
t = Me.GetType() ‘type of page
Page.ClientScript.RegisterClientScriptBlock(t, “changeSelectedScript”, _
”  function changeSelected(idx) {” & Environment.NewLine & _
”   $find(‘” & Me.MyAccordion.ClientID & “_AccordionExtender’).set_SelectedIndex(idx);” & Environment.NewLine & _
“}”, True)
End If
End Sub

… and then call this sub in your Page_Load. Note that my Accordion control is called ‘MyAccordion’ and will need to be changed, or you can make this sub more generic and pass the control ID in like this:

Private Sub AccordionTransition(ByVal ctlAccordion As WebControl)
If Not Page.ClientScript.IsClientScriptBlockRegistered(“changeSelectedScript”) Then
Dim t As Type
t = Me.GetType() ‘type of page
Page.ClientScript.RegisterClientScriptBlock(t, “changeSelectedScript”, _
”  function changeSelected(idx) {” & Environment.NewLine & _
”   $find(‘” & ctlAccordion.ClientID & “_AccordionExtender’).set_SelectedIndex(idx);” & Environment.NewLine & _
“}”, True)
End If
End Sub

Finally, to use this on your webpage, you will need to add an OnClientClick event to whichever control(s) you want to invoke the Accordion expension/contraction. So for instance, with a button you would need:

<asp:Button ID=”Button1″ runat=”server” Text=”Accordion Change” OnClientClick=”changeSelected(1); ” />

The number that is passed into the changeSelected function is the index of the accordion pane you wish to expand. The selected pane expands and any further processing you have set up for that button will continue in the code-behind. If you did not want anything else to occur in the code-behind, you would return a false event value in the click event as well:

<asp:Button ID=”Button2″ runat=”server” Text=”Accordion Change” OnClientClick=”changeSelected(1); event.returnValue=false; return false;” />

Finally, you can also set up the click event in the code behind by adding attributes to the control at Page_Load, such as:

Button2.Attributes.Add(“onclick”, “javascript: changeSelected(1);”)

This could give you more control, for instance if you were using a gridview and wanted to set particular actions for each row.

August 6, 2008

Creating javascript alerts in ASP.NET with UpdatePanel (or without)

Filed under: Ajax,ASP.NET 2.0,Javascript,programming,UpdatePanel — delroger @ 8:33 pm

Just thought I’d share a couple of simple methods for creating javascript alert messages from an ASP.NET webpage, both when you are using AJAX (and an update panel) or just from a standard page.

In a standard page, you can easily create an alert message in the code-behind like this: 

ClientScript.RegisterClientScriptBlock(Me.GetType(), “yourkeyname”, “alert(‘hello’);”, True)

The parameters that are passed in are the System.Type (the Page type in this case), an arbitrary name for your script ‘key’, the javascript itself as a string, and a boolean indicating whether to add the script tags – i.e., <script type=”javascript”></script> – which you might as well use since it shortens the script itself.

Likewise, creating an alert when you are using an UpdatePanel is slightly different, but simpler than you might think – you just need to make sure the System.Type is the UpdatePanel type, and use the ScriptManager rather than the ClientScript like so:

ScriptManager.RegisterStartupScript(Me.UpdatePanel1, Me.UpdatePanel1.GetType(), “yourkeyname”, “alert(‘hello’);”, True)

This is much the same as before except you are passing in the ID of your UpdatePanel along with the other parameters.

Now, since this is code that you are likely to want to re-use throughout an application, it makes sense to create a Class file for it with a couple of generic methods, like this:

Imports Microsoft.VisualBasic
Imports System.Web
Imports System.Web.UI
Public Class Messages
    Public Shared Sub CreateMessageAlertInUpdatePanel(ByVal up As UpdatePanel, ByVal strMessage As String)
        Dim strScript As String = “alert(‘” & strMessage & “‘);”
        Dim guidKey As Guid = Guid.NewGuid()
        ScriptManager.RegisterStartupScript(up, up.GetType(), guidKey.ToString(), strScript, True)
    End Sub
    Public Shared Sub CreateMessageAlert(ByVal strMessage As String)
        Dim guidKey As Guid = Guid.NewGuid()
        Dim pg As Page = HttpContext.Current.Handler
        Dim strScript As String = “alert(‘” & strMessage & “‘);”
        pg.ClientScript.RegisterStartupScript(pg.GetType(), guidKey.ToString(), strScript, True)
    End Sub
End Class

(We’re just using the Guid for the script key to ensure a new key each time we create an alert)

And that’s it! You can now create alert messages from any of your webpages simply by using:

CreateMessageAlertInUpdatePanel(Me.UpdatePanel1, “hello”)
or

CreateMessageAlert(“hi”)

March 26, 2008

Ajax, an update panel and opening a new window

Filed under: Ajax,ASP.NET 2.0,programming,UpdatePanel — delroger @ 1:51 pm

Since this post is getting quite a few views, just thought I’d add a quick summary of this article if you don’t want to read it all. So here you go: if you want to open a new window from the code-behind page when your function or sub is being called from an AJAX Update Panel, you can do it like this (here your Update Panel is called UpdatePanel1 and you’re opening a PDF)…

ScriptManager.RegisterClientScriptBlock(Me.UpdatePanel1, Me.UpdatePanel1.GetType(), "AnyScriptNameYouLike", "window.open('http://www.yourwebsite.com/YourFolder/YourDocumentOrWebpage.pdf');", True)

And here’s the rest of the original post…

I recently found a problem when using an Ajax Update Panel when I wanted to open a PDF document from the code-behind page.  Without the Ajax, I could simply have added a Response.Write with a javascript window.open function, or I could have used a Literal and written the javascript in much the same way, like this:

Response.Write("<script language='javascript'> window.open('http://website/folder/newdocument.pdf'); </script>")

or this (assuming a Literal control called ltlOpenPdf):

ltlOpenPdf.Text = "<script language=""javascript"">window.open('http://website/folder/newdocument.pdf');</script>"

However, the Response.Write is forbidden in Ajax and produces an error, while the Literal apparently did nothing at all.

Finally I worked out that I could open the new document by using a RegisterClientScriptBlock, most importantly passing the Update Panel as the first parameter where the Page is expected, and the Update Panel’s type as the second parameter, as you will see below.

The Update Panel is called UpdatePanel1. A new PDF has been created and saved to a folder called ‘pdffolder’ and the name of the PDF is dynamically created. The root of the website is also being added dynamically so that it will work equally on the development and the production server. (In reality, the name of the folder that contains the PDFs is also dynamically set, captured from the web.config file using System.Configuration.ConfigurationManager.AppSettings)

Dim docGuid As String = Guid.NewGuid().ToString()
'Do pdf creation stuff here...
Dim sb As StringBuilder = New StringBuilder("")
Dim strRoot As String
strRoot = Request.Url.GetLeftPart(UriPartial.Authority)
sb.Append("window.open('" + strRoot + "/pdffolder/" + docGuid + ".pdf" + "');")
ScriptManager.RegisterClientScriptBlock(Me.UpdatePanel1, Me.UpdatePanel1.GetType(), "NewClientScript", sb.ToString(), True)

The only thing to watch out for with this is that it may be classified as a popup by some blockers and prevented from opening, but then that’s almost inevitable with a window created in code.

Blog at WordPress.com.