Wednesday, December 2, 2009

Adding HTML/Javascript block scripts

For quite a long time I wanted to know how could I include HTML / JavaScript / Visual Basic scripts (including their original editor colors) into my blog. I looked up on the internet for the answer finding nothing useful. Finally, I got this:

Somewhere I found that I needed a third party program that could do the translation job. This is the one I use now:

http://www.stevetrefethen.com/highlighter/default.aspx


However, there are also some others that I haven't try yet. You can find more information here:

http://stackoverflow.com/questions/557961/html-examples-syntax-highlighting-and-encoding-for-blog-posts

Tuesday, December 1, 2009

Identifying if a page is called from a popup

Situation:
I need to identify whether a page has been redirected from a popup window or it has been redirected from a full page, in order for me to perform a Redirect to "Main Menu" or "Close" from a button.

Solution:
1. Create two buttons (one that performs a PostBackUrl="/") and another one that executes (window.close() javascript event)

1 <asp:Button ID="cmdBackToMenu" runat="server" PostBackUrl="/" Text="Back to Main Menu" />
2 <asp:Button ID="cmdClose" runat="server" Text="Close" OnClientClick="window.close();"/>


2. Create a javascript event that will be called in the form.onload event.

1 <body bgcolor="#CCCCCC" onload="SettingButton();">



3. The javascript event should be able to identify whether a page was redirected from a popup window or from a full page and depending on the situation make visible or invisible the buttons created in the first step.

1 function SettingButton() {
2
3 if (opener) {
4 document.form1.cmdClose.style.visibility = "visible";
5 document.form1.cmdBackToMenu.style.visibility = "hidden";
6 }
7 else {
8 document.form1.cmdClose.style.visibility = "hidden";
9 document.form1.cmdBackToMenu.style.visibility = "visible";
10 }
11 }

Thursday, November 12, 2009

Cancelling default buttons when keypress enter

The javascript code :


1 function SaveTerms() {
2 if (window.event.keyCode == 13
) {
3 window.event.cancelBubble = true
;
4 window.event.returnValue = false
;
5 document.getElementById('ctl00_ContentPlaceHolder1_cmdSaveTerms'
).click();
6
}
7 }<




The button :

1 <asp:textbox id="txtPerc1" runat="server" cssclass="textbox_enabled2" readonly="False" width="58px" onkeypress="javascript:SaveTerms();"></asp:TextBox>

Tuesday, October 20, 2009

JavaScript

Some Javascript scripts that are always useful:

1) Disabling an item in a dropdown list:



2) Restriction in number of characters or lines in a multiline textbox



3) Blocking the right click / left click



To call it:
onMouseDown="whichButton(event)"

4) Cleaning the clipboard:

Encoding Problems

Sometimes we have trouble handling strange characters that must be transferred from one page to another. In general, should we have the habit of transferring strings using encode. In ASP.Net we do so like this:



To Recover this value, we do not need to do anything special just:



References:
http://msdn.microsoft.com/en-us/library/zttxte6w.aspx
http://www.w3.org/International/tutorials/tutorial-char-enc/

Friday, July 17, 2009

External Stylesheets issue in Telerik Reporting

Situation:
I was able to create an stylesheet, exported into an xml file and then referenced it into another report and even though I could see the styles in the designer, when I run my project the styles simply disappeared.

Solution 1:
In the page where the report is called add the following code (replace the path properly):


Dim ess As New Telerik.Reporting.Drawing.ExternalStyleSheet("..\StyleSheets\TahomaSmall.xml")
myReport.ExternalStyleSheets.Add(ess)
Me.ReportViewer1.Report = myReport


Solution 2:
Replace the path properly in the rpt.designer.vb
Me.ExternalStyleSheets.Add(New Telerik.Reporting.Drawing.ExternalStyleSheet("..\StyleSheets\TahomaSmall.xml"))


Issue cause:
Even though the report has a reference to the external stylesheet in its vb code if your report is not in the same directory as your stylesheet it has to be estated like that in the reference.

Telerik Reporting Report

Issue when deploying a report. If the error shows sth like this inside, just add this into the web.config file



Wednesday, July 15, 2009

Issues with generated WebProject dll

When I try to build my solution I often get this error:
Unable to copy file "obj\Debug\MyProjectXXX.dll" to "bin\Debug\MyProjectXXX.dll". The process cannot access the file 'bin\Debug\MyProjectXXX.dll' because it is being used by another process.
The project it's trying to build is a class library referenced by a couple of other projects in the solution.

Solution

1. Delete whatever files exist in obj/Debug (just files)
2. Add these two lines to the "Pre-build event command line" in the MyProjectXXX properties:

if exist "$(TargetPath).locked" del "$(TargetPath).locked"
if exist "$(TargetPath)" if not exist "$(TargetPath).locked" move "$(TargetPath)" "$(TargetPath).locked"

1. Build the project again.


Reference:
http://social.msdn.microsoft.com/Forums/en-US/csharpide/thread/68648642-08d8-4cff-b0c3-c2782f010589

Wednesday, July 8, 2009

Telerik Reporting

This is up to the moment the best Alternative to SRS.

Advantages over SRS:
1. It doesn't need to work with SQL Server, thus it doesn't depend on any SQL upgrade.
2.Since it doesn't need SQL Server information, the program (VStudio) can perfectly send a dataset which will be directly read by the telerik reporting report control.
3.We can easily define user functions using vb sintaxis and everything we are used to use in VStudio.
4.Stylesheets are easy to implement.


Using stylesheets in Telerik Reporting Reports
To use stylesheets in a Telerik reporting report you just need to do this two steps:
1. Define your own styles for a report (template report)
2. Export your styles to a xml file in order to be called from other reports.
http://www.telerik.com/help/reporting/style-exportingand-reusing-style-sheets.html

How to send a Telerik Reporting Report by email?

I will explain it step by step following the architecture I have here, which is one complete project for all the application reports, so that all the reports will be stored in only one place and called from wherever is needed.

MyWebProject - Architecture

rptFilters.aspx.- It contains the report filters (user input to get the data). These pages are created by report.

ReportPreview.aspx.- It contains the ReportViewer control. It is only one ReportPreview page for all the report filters pages because the filter page from it gets the data is a parameter.

Report.vb.- This is the report.

 

Report.vb code extract

Getting the information from a dll method (the hatParams table has been filled in the rptFilters.aspx.vb page)

Public Sub New(ByVal strParams As String, ByVal strUser As String, ByVal strServer As String, ByVal strPort As String, ByVal intComp As Integer, ByVal strLang As String)
    Dim cSynergy As DLLSynReports.clsReports
    Dim hatParams As Hashtable = Nothing
    Dim dsData As System.Data.DataSet = Nothing
    Dim iResult As Integer
    cSynergy = New DLLSynReports.clsReports(strUser, strServer, strPort, intComp, strLang, strPath, strModName)
    hatParams = FillHashTableByReports(strUser, "rptOrderStatus", strParams)
    InitializeComponent()
    Try
        iResult = cSynergy.GetUnicSOReport(CType(hatParams("WhseFrom"), Integer), _
                            CType(hatParams("WhseTo"), Integer), CType(hatParams("ReqDateFrom"), Integer), _
                            CType(hatParams("ReqDateTo"), Integer), CType(hatParams("PlantDateFrom"), Integer), _
                            CType(hatParams("PlantDateTo"), Integer), CType(hatParams("ShipDateFrom"), Integer), _
                            CType(hatParams("ShipDateTo"), Integer), hatParams("ProductFrom").ToString, _
                            hatParams("ProductTo").ToString, CType(hatParams("GroupProdFrom"), Integer), _
                            CType(hatParams("GroupProdTo"), Integer), CType(hatParams("ShipToFrom"), Integer), _
                            CType(hatParams("ShipToTo"), Integer), CType(hatParams("Dept"), Integer), _
                            CType(hatParams("SalesManFrom"), Integer), CType(hatParams("SalesManTo"), Integer))
        Me.DataSource = dsData
    Catch ex As System.Exception
        'An error has occurred while filling the data set. Please check the exception for more information.
        System.Diagnostics.Debug.WriteLine(ex.Message)
    End Try
End Sub

ReportPreview.aspx.vb

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim datInfo As Data.DataSet = Nothing
    Dim strParams As String
    Dim strReports As String
    Dim strEmailReports As String
    Dim hatParams As Hashtable
    Dim strFormat As String
    Try
        If Not Page.IsPostBack Then
            datInfo = cUtil.GetSpecificTable("Synergy_session", "", "SYSE_SEQ = '" & strSYSE_SEQ & "' ", "")
            strReports = datInfo.Tables(0).Rows(0).Item("SYSE_PARAM1").ToString
            strEmailReports = datInfo.Tables(0).Rows(0).Item("SYSE_PARAM2").ToString
            strParams = datInfo.Tables(0).Rows(0).Item("SYSE_PARAM3").ToString
            strReportName = "RPT" & strSYSE_SEQ
            hatParams = ConfigReports(strReports, strParams)
            If hatParams.Item("Reports").ToString = "0" Then
                lblError.Text = GetCommonMessage(strGlobalUser, "NoRecord", "en")
            Else
                lblError.Text = ""
                strFormat = Request.QueryString("EmailFormat")
                If strFormat = "" Then
                    strFormat = "PDF"
                End If
                If strEmailReports = "True" Then
                    SendReportTelerik(strGlobalUser, strFormat, CType(ReportViewer1.Report, Telerik.Reporting.Report), hatParams, strReportPath, strReportName, strLang)
                End If
            End If
        End If
    Catch ex As Exception
        Call ManageError(strGlobalUser, strModName, strModName, "Page_Load", intGlobalMain, Err, strGlobalPathError, ApplicationType.Web)
    Finally
        If Not datInfo Is Nothing Then
            datInfo.Dispose()
            datInfo = Nothing
        End If
        cUtil = Nothing
    End Try
End Sub
Private Function ConfigReports(ByVal strReports As String, ByVal strParams As String) As Hashtable
    Dim cSynergy As DLLSynReports.clsReports
    Dim hatParams As Hashtable = Nothing
    'Dim intUnicId As Integer
    Dim strRpt As String
    Try
        hatParams = FillHashTableByReports(strGlobalUser, strReportName, strParams)
        hatParams.Add("User", strGlobalUser)
        hatParams.Add("Reports", 999)
        strRpt = ""
        Select Case strReports
            Case "rptGlobalInv.aspx"
                Dim myReport As New GlobalInv(strParams, strGlobalUser, strGlobalServer, strGlobalPort, intGlobalComp, strLang)
                myReport.ReportParameters(0).Value = "Danstar"
                myReport.ReportParameters(1).Value = hatParams.Item("User").ToString()
                myReport.ReportParameters(2).Value = hatParams.Item("DateFrom").ToString()
                myReport.ReportParameters(3).Value = hatParams.Item("WhseFrom").ToString()
                myReport.ReportParameters(4).Value = hatParams.Item("WhseTo").ToString()
                myReport.ReportParameters(5).Value = hatParams.Item("Whse1").ToString()
                myReport.ReportParameters(6).Value = hatParams.Item("Whse2").ToString()
                 Me.ReportViewer1.Report = myReport
            Case "rptOrderStatus.aspx"
                Dim myReport As New OrderPrice(strParams, strGlobalUser, strGlobalServer, strGlobalPort, intGlobalComp, strLang)
                myReport.ReportParameters(0).Value = "Danstar"
                myReport.ReportParameters(1).Value = hatParams.Item("User").ToString()
                myReport.ReportParameters(2).Value = hatParams.Item("WhseFrom").ToString()
                myReport.ReportParameters(3).Value = hatParams.Item("WhseTo").ToString()
                myReport.ReportParameters(4).Value = hatParams.Item("ReqDateFrom").ToString()
                myReport.ReportParameters(5).Value = hatParams.Item("ReqDateTo").ToString()
                myReport.ReportParameters(6).Value = hatParams.Item("PlantDateFrom").ToString()
                myReport.ReportParameters(7).Value = hatParams.Item("PlantDateTo").ToString()
                myReport.ReportParameters(8).Value = hatParams.Item("ShipDateFrom").ToString()
                myReport.ReportParameters(9).Value = hatParams.Item("ShipDateTo").ToString()
                myReport.ReportParameters(10).Value = hatParams.Item("ProductFrom").ToString()
                myReport.ReportParameters(11).Value = hatParams.Item("ProductTo").ToString()
                myReport.ReportParameters(12).Value = hatParams.Item("GroupProdFrom").ToString()
                myReport.ReportParameters(13).Value = hatParams.Item("GroupProdTo").ToString()
                myReport.ReportParameters(14).Value = hatParams.Item("ShipToFrom").ToString()
                myReport.ReportParameters(15).Value = hatParams.Item("ShipToTo").ToString()
                myReport.ReportParameters(16).Value = hatParams.Item("Dept").ToString()
                myReport.ReportParameters(17).Value = hatParams.Item("SalesManFrom").ToString()
                myReport.ReportParameters(18).Value = hatParams.Item("SalesManTo").ToString()
                myReport.ReportParameters(19).Value = hatParams.Item("PriceType").ToString()
                Me.ReportViewer1.Report = myReport
            Case Else
        End Select
        If strRpt <> "" Then
            hatParams.Add("rpt", strRpt)
        End If
        ConfigReports = hatParams
    Catch ex As Exception
        hatParams.Add("User", strGlobalUser)
        hatParams.Add("Reports", 0)
        ConfigReports = hatParams
        Call ManageError(strGlobalUser, strModName, strModName, "ConfigReports (" & strReports & ")", intGlobalMain, Err, strGlobalPathError, ApplicationType.Web)
    Finally
        cSynergy = Nothing
    End Try
End Function
Public Sub SendReportTelerik(ByVal strUser As String, ByVal strFormat As String, _
                      ByVal report As Telerik.Reporting.Report, ByVal hatParams As Hashtable, ByVal strReportPath As String, _
                      ByVal strReportName As String, ByVal strLang As String)
    Dim strReports As String
    Dim strResult As String
    Try
        strReports = CreateTelerikReports(strUser, strFormat, report, strReportName, strReportPath, hatParams)
        strResult = EmailReports(strUser, strReports, "", strReportName)
    Catch ex As Exception
        Call ManageError(strUser, strAppName, strModName, "SendReport", intGlobalMain, Err, strGlobalPathError, ApplicationType.Web)
    End Try
End Sub
Public Function CreateTelerikReports(ByVal strUser As String, ByVal strFormat As String, ByVal report As Telerik.Reporting.Report, ByVal strReportName As String, ByVal strReportPath As String, _
                          ByVal hatParams As Hashtable) As String
    Dim bytResult As Byte() = Nothing
    Dim strOutputPath As String
    Dim strDevInfo As String
    Dim strEncoding As Text.Encoding = Nothing
    Dim strMimeType As String = ""
    Dim strExtension As String = ""
    Try
        strOutputPath = "\Reports\" & Mid(strUser, 5)
        strDevInfo = "<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>"
        Try
            bytResult = Telerik.Reporting.Processing.ReportProcessor.Render("PDF", report, Nothing, strMimeType, strExtension, strEncoding)
        Catch exSoap As SoapException
            Call ManageError(strUser, strAppName, strModName, "CreateTelerikReports", intGlobalMain, Err, strGlobalPathError, ApplicationType.Web)
        End Try
        Select Case strFormat
            Case "PDF"
                strExtension = ".pdf"
            Case "MHTML"
                strExtension = ".mht"
            Case "EXCEL"
                strExtension = ".xls"
        End Select
        Call CreateStreamFile(strUser, bytResult, strReportName & strExtension, strOutputPath)
        CreateTelerikReports = strOutputPath & "\" & strReportName & strExtension
    Catch ex As Exception
        CreateTelerikReports = ""
        Call ManageError(strUser, strAppName, strModName, "CreateTelerikReports", intGlobalMain, Err, strGlobalPathError, ApplicationType.Web)
    End Try
End Function
Public Function EmailReports(ByVal strUser As String, ByVal strReports As String, _
                        ByVal strCC As String, ByVal strSubject As String) As String
    Dim cMail As New DLLLallemand.cBIZExchange(strUser, DLLLallemand.DataConnection.Lallemand, ApplicationType.Web)
    Dim cUdtMail As New DLLLallemand.clsUDTMail
    Try
        cUdtMail.strMAIL_FROM = "BatchReports@aaa.com"
        cUdtMail.strMAIL_SUBJECT = strSubject
        cUdtMail.strMAIL_MESSAGE = "Look at the atttachement for your requested Reports !"
        cUdtMail.strMAIL_URL = ""
        cUdtMail.colMAIL_TO.Add(strUser & "@aaa.com")
        cUdtMail.colMAIL_CC.Add(strCC)
        cUdtMail.colMAIL_ATTACHEMENT.Add(System.Web.HttpContext.Current.Request.MapPath("~") & strReports)
        EmailReports = cMail.SendMail(strUser, cUdtMail)
    Catch ex As Exception
        EmailReports = "error"
        Call ManageError(strUser, strAppName, strModName, "EmailReports", intGlobalMain, Err, strGlobalPathError, ApplicationType.Web)
    End Try
End Function

Wednesday, July 1, 2009

SRS

Making operations with agrupated fields:

http://msdn.microsoft.com/en-us/library/ms157274(SQL.90).aspx

Monday, June 29, 2009

Telerik Reporting Issues when Publishing

I got to face two issues when publishing my Telerik Reporting Project:

1. I received a "The folder '/' is marked executable" error message when I tried to publish the project and upload the dlls into the bin sub directory of my project.

Solution:
http://support.microsoft.com/kb/219110


2. Once the first issue was solved and each time I tried to see a page in my project, I receipt a configuration error saying that the site was not able to find:


However, I was able to run my project without any error in a local mode (my local machine). It was only at the moment of publishing the project (in a remote server) that I got that error, so I compared what I have in my local GAC with what I have in the remote server GAC and of course there were some differences. Regarding the Telerik Reporting think, there were not in the remote server, so I made them similar and it worked.

To register dlls in the GAC:
http://support.microsoft.com/kb/315682

Normally the GAC is located in:
C:\WINDOWS\assembly

Friday, May 15, 2009

Custom Validators: How to have Custom Validation and Required Field Validation

JavaScript functions will show the error message always in the same label, that will be placed somewhere in the screen, as the user wants and not in the custom validator place.

JavaScript Functions to be called from a DataGrid or RadGrid
function ClientValidateIni(source, arguments) {
if (arguments.Value.length == 0) {
arguments.IsValid = false;
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value += 'I';
displayMessage(arguments)
}
else {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value = document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.replace('I', '');
displayMessage(arguments)
}
}
function ClientValidateWeight(source, arguments) {
if ((arguments.Value.length == 0) && (document.getElementById("ctl00_ContentPlaceHolder1_txtUsine").value == '600')) {
arguments.IsValid = false;
}
else {
if ((parseInt(arguments.Value) == 0) && (document.getElementById("ctl00_ContentPlaceHolder1_txtUsine").value == '600')) {
arguments.IsValid = false;
}
else
{ arguments.IsValid = IsNumeric(arguments.Value); }
}
if (arguments.IsValid == false) {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value += 'W';
displayMessage(arguments)
}
else {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value = document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.replace('W', '');
displayMessage(arguments)
}
}
function ClientValidateQty(source, arguments) {
if ((arguments.Value.length == 0) && (document.getElementById("ctl00_ContentPlaceHolder1_txtUsine").value == '600')) {
arguments.IsValid = false;
}
else {
if ((parseInt(arguments.Value) == 0) && (document.getElementById("ctl00_ContentPlaceHolder1_txtUsine").value == '600')) {
arguments.IsValid = false;
}
else
{ arguments.IsValid = IsNumeric(arguments.Value); }
}
if (arguments.IsValid == false) {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value += 'Q';
displayMessage(arguments)
}
else {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value = document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.replace('Q', '');
displayMessage(arguments)
}
}

function ClientValidateTemp(source, arguments) {
arguments.IsValid = IsNumeric(arguments.Value);
if (arguments.IsValid == false) {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value += 'T';
displayMessage(arguments)
}
else {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value = document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.replace('T', '');
displayMessage(arguments)
}
}
function IsNumeric(input) {
var RE = /^-{0,1}\d*\.{0,1}\d+$/;
return (RE.test(input));
}
function displayMessage(arguments) {
document.getElementById("ctl00_ContentPlaceHolder1_lblErrorGrid1").innerHTML = '';
if (document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.indexOf('I') >= 0)
{ document.getElementById("ctl00_ContentPlaceHolder1_lblErrorGrid1").innerHTML = document.getElementById("ctl00_ContentPlaceHolder1_cvtInitial").value + '
'; }
if (document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.indexOf('W') >= 0) {
document.getElementById("ctl00_ContentPlaceHolder1_lblErrorGrid1").innerHTML = document.getElementById("ctl00_ContentPlaceHolder1_cvtWeight").value + '
';
}
if (document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.indexOf('Q') >= 0)
{ document.getElementById("ctl00_ContentPlaceHolder1_lblErrorGrid1").innerHTML = document.getElementById("ctl00_ContentPlaceHolder1_cvtQty").value + '
'; }
if (document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.indexOf('T') >= 0)
{ document.getElementById("ctl00_ContentPlaceHolder1_lblErrorGrid1").innerHTML = document.getElementById("ctl00_ContentPlaceHolder1_cvtTemp").value + '
'; }
}


ASPX - HTML portion code


The output message label:



The Custom Validator and the ControltoValidate (portion of a Grid)


' MaxLength="5">
ClientValidationFunction="ClientValidateTemp"
ControlToValidate="txtTemp" ValidateEmptyText="True" SetFocusOnError="True"
CssClass="error2" Display="Dynamic" ErrorMessage="*">



The hidden controls needed for the example:











Master Page - Comunication between Contents - VB

Example:

MasterPage.aspx


#Region "Public Delegates"

' Expose delegates for Master Page Events
Public Delegate Sub MasterPageMenuClickHandler(ByVal sender As Object, ByVal e As System.EventArgs)

#End Region

#Region "Public Properties"

Private _currentButton As String

Public Property CurrentButton() As String
Get
Return _currentButton
End Get
Set(ByVal value As String)
_currentButton = value
End Set
End Property
#End Region

#Region "Public Events"
Public Event MenuButton As MasterPageMenuClickHandler
#End Region

#Region "Page Events"
Protected Sub cboLang_Click(ByVal sender As Object, ByVal e As System.EventArgs)
_currentButton = cboLang.SelectedValue

Select Case cboLang.SelectedValue
Case "fr"
Call DLLLallemand.WriteCookies(strGlobalUser, "fr", strAppName)
Case Else
Call DLLLallemand.WriteCookies(strGlobalUser, "en", strAppName)
End Select

OnMenuButton(e)
End Sub
#End Region


#Region "Virtual Methods"
Protected Sub OnMenuButton(ByVal e As EventArgs)
'Invokes the delegates
RaiseEvent MenuButton(Me, e)
End Sub
#End Region



ContentPage.aspx

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
AddHandler Master.MenuButton, New Master_Synergy1.MasterPageMenuClickHandler
(AddressOf Master_MenuButton)

Catch ex As Exception

Finally
End Try
End Sub



Public Sub Master_MenuButton(ByVal sender As Object, ByVal e As System.EventArgs)
strLang = Master.CurrentButton.ToString()
Call MultiLanguage(strLang)
wdgInactiveYeast.Rebind()
End Sub



Reference
http://blogs.claritycon.com/blogs/steve_holstad/archive/2006/03/04/266.aspx

AJAX - Panel

There is no doubt that the easiest way to implement AJAX in a Web Page is by using UpdatePanel, but is this way efficient? If you have a simple page, then you can use UpdatePanel and maybe you will have no issue on ussing that - DO NOT say it is fine to use it, I just said you will find no javascript error; However, nowadays most of us use MasterPages to build complete applications and there you will find issues. Let's see an example:

MasterPage.aspx

<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>

<asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
</asp:ContentPlaceHolder>




This master page has two ContentPlaceHolder, so the Page that will use it will have two Contents too.




Default.aspx


<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">



</asp:Content>



<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" Runat="Server">

</asp:Content>








Now, if we try to put one Panel Control for both Content, we realize almost inmediately that we are not allowed to do so. No other alternative, just put a PanelControl in the first Content, now our code will look like this:


<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

            <asp:UpdatePanel ID="UpdatePanel1" runat="server">


            <ContentTemplate>



            </ContentTemplate>

           </asp:UpdatePanel>                 
</asp:Content>








Everything works fine except that you have no control on the other content controls, so we add a new Panel for the the second Content.


<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

            <asp:UpdatePanel ID="UpdatePanel1" runat="server">


            <ContentTemplate>



            </ContentTemplate>

           </asp:UpdatePanel>                 
</asp:Content>




<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" Runat="Server">



    <asp:UpdatePanel ID="UpdatePanel2" runat="server">



    <ContentTemplate>

    <asp:Button ID="cmdQuit" runat="server" OnClick="cmdQuit_Click"


        Style="position: static; height: 28px;" Text="Quit" UseSubmitBehavior="True"


        Width="100px" />

             </ContentTemplate>


           </asp:UpdatePanel>                 


</asp:Content>







Now, you have control on the other content's controls. That was pretty easy!, However, Imagine you have a Quit button in the second content, and it needs to do a redirect to another page in order to quit the option, but not the application. Sooner you will realize that;

Response.redirect doesn't work now, there is a JavaScript issue, so our Response.redirect which is in the server side never gets executed. That has also a solution. You just need to add this into your config.web page.



<httpModules>

  <add type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="ScriptModule" />


</httpModules>




Now it works. However, there is something that cannot convince me at the end. The reason is here: http://encosia.com/2007/07/11/why-aspnet-ajax-updatepanels-are-dangerous/
and I pretty agree with this, so now I will be working on find a more efficient way of doing the same.

Wednesday, April 29, 2009