Open an Url on Asp.Net ModalPopupExtender Ajax Toolkit And Alternative Approaches


Traditional javascript using window.open(url) function to open an Url on new browser window.
Developers can post a form to new window or build a data entry page. window.open(url) function is simple but if it opens new browser several times then overall application could become overwhelming.

We can use ModalPopupExtender instead of window.open function. ModalPopupExtender is an Ajax Control Toolkit to create a modal popup. Modal popup is a dialog box that always on top of a page. You cannot access parent page if modal popup still appear so you need to close it first.
I already have a blog post explaining and showing example about ModalPopupExtender, please follow this Create a PopUp Dialog with ModalPopupExtender AjaxControlToolkit

ModalPopupExtender usually has a Panel Control and inside this Panel we can have any control like label, textbox, button etc. ModalPopupExtender usually has an OK and Cancel button inside Panel.
Those OK and Cancel buttons actually close the modal popup.

The question is how can we open an Url and show it inside Modal Popup? We can just fill in the Url’s HTML source code string into Panel inside the Modal Popup.
So that we can have dynamic content on that modal popup

One way to get Url’s HTML source code is using WebRequest Class. This WebRequest Class can get the response stream of Url and we convert it to string using StreamReader Class.

As a usual, to use ModalPopupExtender we need to add ToolkitScriptManager and register AjaxControlToolkit Assembly on Page Directive.

I have an example, a button opens a modal dialog and this dialog opens an HTML page. Please see snapshot:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
   
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server" >
        </ajaxToolkit:ToolkitScriptManager>

        <asp:Button ID="btnopen" runat="server" Text="Open A Page Dialog" /> 
        <asp:HiddenField ID="hidopenmodal" runat="server" />
        <asp:Label ID="lbl" runat="server"></asp:Label>
        <asp:Panel ID="pnlmodal" runat="server" BorderColor="ActiveBorder" BorderWidth="2px" style="padding:5px 5px 5px 5px" >
            <asp:Panel ID="pnlinner" runat="server"></asp:Panel><br />
            <asp:Button id="btnok" runat="server" Text="OK" />
        </asp:Panel>

        <ajaxToolkit:ModalPopupExtender ID="modalpopup1" runat="server" TargetControlID="hidopenmodal" PopupControlID="pnlmodal"
         OkControlID="btnok" >
        
        </ajaxToolkit:ModalPopupExtender>
    </div>
    </form>
</body>
</html>

I have inner Panel Control contains nothing. This inner Panel will be filled in a HTML. OK Button is inserted in the beginning.
So ModalPopupExtender can register OKControlID and on fact that we always need OK/Cancel button on every modal popup.
The Modal Popup example will open an arbitrary Url like i.e “somepage.aspx” or “somepage.htm”.

Panel Control as a modal popup will contains that Url’s HTML source string programmatically by using a Literal Control

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="somepage.aspx.vb" Inherits="somepage" %>
<h3>Page Header</h3>
<span style="background-color: Yellow;"><b>Title</b></span>
<p>Description here</p>
<table border="1">
<tr><td>Product ID</td><td>PR0001</td></tr>
<tr><td>Name</td><td>Product No 1</td></tr>
</table>

For recap I use WebRequest class to get a response from Url and convert it to string using StreamReader class. Also I use LiteralControl to fill in result of HTML source string to Panel Control.
Code behind file:

Imports System.IO
Imports System.Net
Imports System.Text
Partial Class _Default
    Inherits System.Web.UI.Page

    Protected Sub btnopen_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnopen.Click
        Dim strhtml As String
        strhtml = HTMLPage()
        
        pnlinner.Controls.Add(New LiteralControl(strhtml))
        modalpopup1.Show()
    End Sub
    Protected Function HTMLPage() As String
        Dim responsefromservr As String

        Dim request As WebRequest = WebRequest.Create("http://localhost/ModalPopupWebRequest/somepage.aspx")
        Request.Credentials = CredentialCache.DefaultCredentials
        Dim response As HttpWebResponse = CType(Request.GetResponse(), HttpWebResponse)
        Dim dataStream As Stream = Response.GetResponseStream()

        Dim reader As New StreamReader(dataStream)
        responsefromservr = reader.ReadToEnd()
        reader.Close()
        dataStream.Close()
        Response.Close()
        
        Return responsefromservr
    End Function    
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        
    End Sub
End Class

HTMLPage() methods has WebRequest & StreamReader to get string of Url’s HTML source. After that, at btnopen click event, inner Panel adds a HTML LiteralControl.

Basically I have dynamic content of an Url on modal popup.

Alternative Solution Beside of Opening an Url

Personally, although above method is applicable, sometimes I prefer not to use above method like opening an Url and getting its HTML source string in Modal Popup using WebRequest. I more like to use StringBuilder Class to store a HTML source string.
This way is more straight forward than opening an Url because of basically, I want to get string of HTML source so I think it is better to store it in StringBuilder.
To demonstrate this please change the HTMLPage function with below:

Protected Function HTMLPage() As String
        Dim sb As New StringBuilder()
        sb.Append("<h3>Page Header</h3>")
        sb.AppendLine("<span style=""background-color: Yellow;""><b>Title</b></span>")
        sb.AppendLine("<p>Description here</p>")
        sb.AppendLine("<table border=""1"">")
		sb.AppendLine("<tr><td>Product ID</td><td>PR0001</td></tr>")
		sb.AppendLine("<tr><td>Name</td><td>Product No 1</td></tr>")
		sb.AppendLine("</table>")

        Return sb.ToString()
    End Function

Run the website again and you should see same result. I do not have to have another html/aspx file just write them on some functions or classes with this way.
Off course, If I want to get content from third party’s page then I need to use WebRequest.

Data Entry Form Using ModalPopupExtender Example

In this example, I have Northwind sample Database and Employee Data on ListView control. I can edit current and insert new Employee via Modal Popup after user clicks related links / button.

Inside Modal Popup Panel, I have inner Panel Control pnlform (Panel Form) to be filled in a HTML source string. Save and Cancel button is inserted from beginning so I do not have to create those buttons on HTML page/string.
Also I have a Select link button in ListView to open a modal popup in edit mode and it contains selected employee data in textboxes.
Add New Employee button opens a modal popup in insert mode. It contains emtpy textboxes.

All UI controls contained in UpdatePanel so that page request and response are not refreshing the whole page. Note: ListView ClientIDMode attribute must be set to AutoID to enable partial reload on ListView Control.

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Employee.aspx.vb" Inherits="Employee" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <link href="StyleSheet1.css" rel="Stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
        </ajaxToolkit:ToolkitScriptManager>

        <asp:UpdatePanel ID="updatepanel1" runat="server">
        <ContentTemplate>            
        <asp:ListView runat="server" ID="lstview" ClientIDMode="AutoID" >
            <LayoutTemplate>
                <table>
                    <thead>
                        <tr>
                            <th>First Name</th>
                            <th>Last Name</th>
                            <th>Title</th>
                            <th>Hire Date</th>
                            <th>Address</th>
                            <th>City</th>
                            <th>&nbsp;</th>
                        </tr>
                    </thead>
                    <tbody>
                        <asp:PlaceHolder ID="itemplaceholder" runat="server"></asp:PlaceHolder>
                    </tbody>
                </table>
                
            </LayoutTemplate>
            <ItemTemplate>
                <tr>
                <td><%# Eval("FirstName") %></td>
                <td><%# Eval("LastName")%></td>
                <td><%# Eval("Title")%></td>
                <td><%# Eval("HireDate")%></td>
                <td><%# Eval("Address")%></td>
                <td><%# Eval("City")%></td>
                <td><asp:LinkButton ID="lnk" runat="server" CommandName="Select" CommandArgument='<%# Eval("EmployeeID") %>' Text="Select"></asp:LinkButton></td>
                </tr>
            </ItemTemplate>
        </asp:ListView>
        <asp:Button ID="btnadd" runat="server" Text="Add New Employee" />

        <asp:HiddenField ID="hiddenmdl" runat="server" />
        <asp:Panel ID="pnlselect" runat="server" CssClass="modalpopup">
            <asp:Panel ID="pnlform" runat="server"></asp:Panel>
            <asp:Button ID="btnsave" runat="server" Text="Save" /> &nbsp;
            <asp:Button ID="btncancel" runat="server" Text="Cancel" />
        </asp:Panel>
         <ajaxToolkit:ModalPopupExtender ID="mdlopopup" runat="server" TargetControlID="hiddenmdl" PopupControlID="pnlselect"
          CancelControlID="btncancel" Y="100" BackgroundCssClass="modalbackground">
        </ajaxToolkit:ModalPopupExtender>

        </ContentTemplate>
        </asp:UpdatePanel>       
    </div>
    </form>
</body>
</html>

This example shows ListView Control, LinkButton control inside ListView to open modal popup with Edit mode and Add New button to Add Employee data.
I have to bind the ListView Control with data from SQL Server using ADO.NET SQlConnection, SQLDataAdapter and also DataTable object as a data source of ListView.

I set this LinkButton’s CommandName attribute value “Select” and CommandArgument refers to Employee ID. I catch the ‘Select’ command at lstview_ItemCommand method and then generate Data Entry HTML form.

Code behind file:

Imports System.Data
Imports System.Data.SqlClient
Partial Class Employee
    Inherits System.Web.UI.Page
    Dim connectionstring As String
    Dim cmdType As CommandType
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        connectionstring = "Data Source=.\SQLExpress;Initial Catalog=Northwind;Integrated Security=true"
        If Not Page.IsPostBack Then
            BindListView()
        End If
        
    End Sub
    Protected Sub BindListView()
        Dim dbconn As New SqlConnection(connectionstring)
        dbconn.Open()
        Dim query As String
        query = "select * from Employees"
        Dim da As New SqlDataAdapter(query, dbconn)
        Dim dt As New DataTable
        da.Fill(dt)
        dbconn.Close()

        lstview.DataSource = dt
        lstview.DataBind()
    End Sub
    Protected Sub lstview_ItemCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewCommandEventArgs) Handles lstview.ItemCommand
        If e.CommandName = "Select" Then
            cmdType = CommandType.Edit
            Dim dbconn As New SqlConnection(connectionstring)
            dbconn.Open()
            Dim query As String
            query = "select * from Employees where employeeid=" & e.CommandArgument.ToString()
            Dim da As New SqlDataAdapter(query, dbconn)
            Dim dt As New DataTable
            da.Fill(dt)
            dbconn.Close()

            Dim strhtml As String = EmployeeFormHTML(dt)
            pnlform.Controls.Clear()
            pnlform.Controls.Add(New LiteralControl(strhtml))
            mdlopopup.Show()

        End If
    End Sub

    Protected Function EmployeeFormHTML(ByVal Employeedt As DataTable) As String
        Dim sb As New StringBuilder()
        sb.Append("<input type='hidden' name='employeeid' value='" & Employeedt(0)("EmployeeID").ToString() & "'>")
        sb.Append("<table>")
        sb.AppendLine("<tr><td>First Name</td><td><input type='text' name='firstname' value='" & Employeedt(0)("FirstName").ToString() & "'></td></tr>")
        sb.AppendLine("<tr><td>Last Name</td><td><input type='text' name='lastname' value='" & Employeedt(0)("LastName").ToString() & "'></td></tr>")
        sb.AppendLine("<tr><td>Title</td><td><input type='text' name='title' value='" & Employeedt(0)("Title").ToString() & "'></td></tr>")
        sb.AppendLine("<tr><td>Hire Date</td><td>")
        sb.AppendLine("<select name='hiremonth'><option value=''>Month</option>")
        For i As Integer = 1 To 12
            sb.AppendLine("<option value='" & i & "' ")
            If Month(Convert.ToDateTime(Employeedt(0)("HireDate"))) = i Then
                sb.Append("selected")
            End If
            sb.Append(">" & MonthName(i) & "</option>")
        Next
        sb.AppendLine("</select> / ")
        sb.AppendLine("<select name='hireday'><option value=''>Day</option>")
        For i As Integer = 1 To 31
            sb.AppendLine("<option value='" & i & "'")

            If Day(Convert.ToDateTime(Employeedt(0)("HireDate"))) = i Then
                sb.Append("selected")
            End If
            sb.Append(">" & i & "</option>")
        Next
        sb.AppendLine("</select> / ")
        sb.AppendLine("<select name='hireyear'><option value=''>Year</option>")
        For i As Integer = 1990 To 2012
            sb.AppendLine("<option value='" & i & "'")
            If Year(Convert.ToDateTime(Employeedt(0)("HireDate"))) = i Then
                sb.Append("selected")
            End If
            sb.Append(">" & i & "</option>")
        Next
        sb.AppendLine("</select>")
        sb.AppendLine("<tr><td>Address</td><td><input type='text' name='address' value='" & Employeedt(0)("Address").ToString() & "'></td></tr>")
        sb.AppendLine("<tr><td>City</td><td><input type='text' name='city' value='" & Employeedt(0)("City").ToString() & "'></td></tr>")
        sb.AppendLine("</table>")

        Return sb.ToString()
    End Function

    Protected Function EmployeeFormHTML() As String
        Dim sb As New StringBuilder()
        sb.Append("<table>")
        sb.AppendLine("<tr><td>First Name</td><td><input type='text' name='firstname' value=''></td></tr>")
        sb.AppendLine("<tr><td>Last Name</td><td><input type='text' name='lastname' value=''></td></tr>")
        sb.AppendLine("<tr><td>Title</td><td><input type='text' name='title' value=''></td></tr>")
        sb.AppendLine("<tr><td>Hire Date</td><td>")
        sb.AppendLine("<select name='hiremonth'><option value=''>Month</option>")
        For i As Integer = 1 To 12
            sb.AppendLine("<option value='" & i & "'>" & MonthName(i) & "</option>")
        Next
        sb.AppendLine("</select> / ")
        sb.AppendLine("<select name='hireday'><option value=''>Day</option>")
        For i As Integer = 1 To 31
            sb.AppendLine("<option value='" & i & "'>" & i & "</option>")
        Next
        sb.AppendLine("</select> / ")
        sb.AppendLine("<select name='hireyear'><option value=''>Year</option>")
        For i As Integer = 1990 To 2012
            sb.AppendLine("<option value='" & i & "'>" & i & "</option>")
        Next
        sb.AppendLine("</select>")
        sb.AppendLine("</td></tr>")
        sb.AppendLine("<tr><td>Address</td><td><input type='text' name='address' value=''></td></tr>")
        sb.AppendLine("<tr><td>City</td><td><input type='text' name='city' value=''></td></tr>")
        sb.AppendLine("</table>")

        Return sb.ToString()
    End Function


    Protected Sub lstview_SelectedIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewSelectEventArgs) Handles lstview.SelectedIndexChanging

    End Sub

    Protected Sub btnadd_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnadd.Click
        cmdType = CommandType.Add
        Dim strhtml As String = EmployeeFormHTML()
        pnlform.Controls.Clear()
        pnlform.Controls.Add(New LiteralControl(strhtml))
        mdlopopup.Show()
    End Sub

    Protected Sub btnsave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnsave.Click
        mdlopopup.Hide()

        Dim employeeid As String = Request.Form("employeeid")
        Dim firstname As String = Request.Form("firstname")
        Dim lastname As String = Request.Form("lastname")
        Dim title As String = Request.Form("title")
        Dim hiredate As String = Request.Form("hiremonth") & "/" & Request.Form("hireday") & "/" & Request.Form("hireyear")
        Dim address As String = Request.Form("address")
        Dim city As String = Request.Form("city")

        Dim query As String
        Select Case cmdType
            Case CommandType.Add
                query = "insert into Employees (FirstName, LastName, Title, HireDate, Address, City) values ('" & firstname & "','" & _
                    lastname & "','" & title & "','" & hiredate & "','" & address & "','" & city & "')"
            Case CommandType.Edit
                query = "update Employees Set FirstName='" & firstname & "', LastName='" & lastname & "', Title='" & title & "', HireDate='" & hiredate & "', " & _
                        "Address='" & address & "', City='" & city & "' Where EmployeeID=" & employeeid
        End Select
        

        Dim dbconn As New SqlConnection(connectionstring)
        dbconn.Open()
        Dim comm As New SqlCommand(query, dbconn)
        comm.ExecuteNonQuery()
        comm.Dispose()
        dbconn.Close()

        Response.Redirect("Employee.aspx")
    End Sub
End Class

Enum CommandType
    Edit
    Add
End Enum

Same as previous, I am using StringBuilder Class and LiteralControl to fill in HTML string into Panel Form / pnlform.

If user clicks Save button, modal popup become hidden and process continues to save the form data into database. Response.Redirect function is needed to refresh the page after change has been made.

Regards,
Agung Gugiaji

Advertisements

One response to “Open an Url on Asp.Net ModalPopupExtender Ajax Toolkit And Alternative Approaches

  1. Thx for the info mate. I was very struggling while coding this. This gonna help me so much . BOokmarked!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s