1.17. Adding a Delete Confirmation Pop Up

Problem

You want to add to a DataGrid row a confirmation pop up that appears whenever a user tries to delete a row in the DataGrid.

Solution

Add a Select button to each row of the DataGrid and a Delete button below the DataGrid. Whenever the Delete button is clicked, execute some client-side script that displays the confirmation pop up, followed by some server-side code that performs the actual deletion.

In the .aspx file:

  1. Create an extra button column in the DataGrid to display a Select button.

  2. Add a Delete button below the DataGrid.

In the code-behind class for the page, use the .NET language of your choice to:

  1. Register the client-side script to be executed when the Delete button is clicked.

  2. Add an attribute to the Delete button that calls the delete script when the Delete button is clicked.

Figure 1-21 shows a DataGrid with this solution implemented. Example 1-48 through Example 1-50 show the .aspx and code-behind files for the application that produces this result.

Confirmation pop up before deletion in a DataGrid output

Figure 1-21. Confirmation pop up before deletion in a DataGrid output

Discussion

To display a confirmation pop up when a user attempts to delete a row in a data table, create a DataGrid in the same way you have done so throughout this chapter, except that you add a button column to allow for row selection. Setting the ButtonType to "LinkButton" outputs a hyperlink for selecting the row. (The ButtonType can instead be set to "PushButton" to output an HTML button.) The CommandName defines the action to be taken when the button is clicked, and the Text attribute defines the text that will be output for the button. (Note that the “select anywhere approach” described in Recipe 1.16 can been used here instead.)

<Columns>
  <asp:ButtonColumn ButtonType="LinkButton" 
                                   CommandName="Select" 
                                   Text="Select" 
                                   ItemStyle-HorizontalAlign="Center" />
      ...
</Columns>

From here on, it’s easiest to explain the remaining steps of this recipe in the context of our actual example application. In the Page_Load method of the code-behind, the client-side script block that is to be executed when the Delete button is clicked is created and registered with the page. The IsClientScriptBlockRegistered method is used to ensure that the script block is not registered more than once on the page. The RegisterClientScriptBlock method is used to output the script block in the page when the page is rendered. This method causes the script to output immediately after the opening Form tag. If you prefer the script to be output immediately before the Form end tag, the RegisterStartupScript method can be used instead. The client-side script that is output to the browser is shown here:

<script language='javascript'>
<!--
function beforeDelete( )
{return(confirm('Are you sure you want to delete the selected item?'));}
//-->
</script>

Warning

The code that outputs the client-side script block must be executed every time the page is rendered, including postbacks, because the registered script blocks are not persisted in the Page object.

After creating and registering the client script block, an attribute is added to the Delete button control to cause the client script block to be executed when the button is clicked. The resulting HTML for the delete button is shown here:

<input type="image" name="btnDelete" id="btnDelete" 
       OnClick="return(beforeDelete( ))"
       src="/ASPNetBook/VBExamples/images/buttons/button_delete.gif"
       border="0" />

When the user clicks the Delete button, the beforeDelete function is called in the client-side code. The beforeDelete function outputs a standard HTML confirmation dialog box with the message, “Are you sure you want to delete the selected item?” If the user clicks the Cancel button, the function returns False, effectively canceling the postback of the page. If the user clicks the OK button, the function returns True, allowing the page to be posted back to the server.

A server-side event handler (btnDelete_Click) is added to the code-behind to handle the Delete button’s server-side click event. In this method, a check is performed to ensure a row is selected, and then the required deletion code for your application is processed.

Tip

The JavaScript registered in the code-behind and the attribute added to the Delete button can also be placed directly in the .aspx file. This was not done in this example, though, in the spirit of keeping all code in the code-behind and all presentation aspects in the .aspx file, a highly recommended practice. In addition, a library of client-side scripts can be created once and used many times throughout your applications.

Warning

Using a radio button for row selection instead of a Select button would be preferable, but a bug in release 1.0 and 1.1 of ASP.NET makes it very difficult. The problem is caused by a unique name and group name being generated for every control in the grid, thus placing the radio buttons on each row in a different group. This has the unfortunate consequence of being able to select multiple radio buttons at the same time. For details of the bug, see Knowledge Base article Q316495 on Microsoft’s MSDN web site (http://msdn.microsoft.com).

See Also

Recipe 1.16

Example 1-48. Confirmation pop up before deletion in a DataGrid (.aspx)

<%@ Page Language="vb" AutoEventWireup="false" 
  Codebehind="CH01DatagridWithConfirmBeforeDeleteVB.aspx.vb" 
  Inherits="ASPNetCookbook.VBExamples.CH01DatagridWithConfirmBeforeDeleteVB" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <title>DataGrid With Confirmation Popup Before Delete</title>
    <link rel="stylesheet" href="css/ASPNetCookbook.css">
  </head>
  <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0">
    <form id="frmDatagrid" method="post" runat="server">
      <table width="100%" cellpadding="0" cellspacing="0" border="0">
        <tr>
          <td align="center">
            <img src="images/ASPNETCookbookHeading_blue.gif">
          </td>
        </tr>
        <tr>
          <td class="dividerLine">
            <img src="images/spacer.gif" height="6" border="0"></td>
        </tr>
      </table>
      <table width="90%" align="center" border="0">
        <tr>
          <td><img src="images/spacer.gif" height="10" border="0"></td>
        </tr>
        <tr>
          <td align="center" class="PageHeading">
            DataGrid With Confirmation Popup Before Delete (VB)
          </td>
        </tr>
        <tr>
          <td><img src="images/spacer.gif" height="10" border="0"></td>
        </tr>
        <tr>
          <td align="center">
            <asp:DataGrid 
                                id="dgBooks" 
                                runat="server" 
                                BorderColor="000080" 
                                BorderWidth="2px"
                                AutoGenerateColumns="False"
                                width="100%">

                                <HeaderStyle 
                                  HorizontalAlign="Center" 
                                  ForeColor="#FFFFFF" 
                                  BackColor="#000080" 
                                  Font-Bold=true
                                  CssClass="TableHeader" /> 

                                <ItemStyle
                                  BackColor="#FFFFE0" 
                                  cssClass="TableCellNormal" />

                                <AlternatingItemStyle 
                                  BackColor="#FFFFFF" 
                                  cssClass="TableCellAlternating" />

                                <SelectedItemStyle 
                                  BackColor="#cccccc"
                                  cssClass="TableCellAlternating" />
                                

                                <Columns>
                                  <asp:ButtonColumn ButtonType="LinkButton"
                                                    CommandName="Select" 
                                                    Text="Select" 
                                                    ItemStyle-HorizontalAlign="Center" />
                                  <asp:BoundColumn HeaderText="Title" DataField="Title" />
                                  <asp:BoundColumn HeaderText="Publish Date" 
                                                   DataField="PublishDate" 
                                                   ItemStyle-HorizontalAlign="Center"
                                                   DataFormatString="{0:MMM dd, yyyy}" />
                                  <asp:BoundColumn HeaderText="List Price" 
                                                   DataField="ListPrice" 
                                                   ItemStyle-HorizontalAlign="Center"
                                                   DataFormatString="{0:C2}" />
                                </Columns>
                              </asp:DataGrid>
          </td>
        </tr>
        <tr>
          <td><img src="images/spacer.gif" height="10" border="0"></td>
        </tr>
        <tr>
          <td align="center">
            <table width="100%">
              <tr>
                <td width="18%">&nbsp;</td>
                <td width="15%" align="center">
                  <asp:ImageButton id="btnAdd" runat="server" 
                       ImageUrl="images/buttons/button_add.gif" /></td>
                <td width="10%">&nbsp;</td>
                <td width="15%" align="center">
                  <asp:ImageButton id="btnEdit" runat="server" 
                       ImageUrl="images/buttons/button_edit.gif" /></td>
                <td width="10%">&nbsp;</td>
                <td width="15%" align="center">
                  <asp:ImageButton id="btnDelete" runat="server" 
                                         ImageUrl="images/buttons/button_delete.gif" /></td>
                <td width="17%">&nbsp;</td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </form>
  </body>
</html>

Example 1-49. Confirmation pop up before deletion in a DataGrid code-behind (.vb)

Option Explicit On 
Option Strict On
'-----------------------------------------------------------------------------
'
'   Module Name: CH01DatagridWithConfirmBeforeDeleteVB.aspx.vb
'
'   Description: This class provides the code behind for
'                CH01DatagridWithConfirmBeforeDeleteVB
'
'*****************************************************************************
Imports Microsoft.VisualBasic
Imports System
Imports System.Configuration
Imports System.Data
Imports System.Data.OleDb

Namespace ASPNetCookbook.VBExamples
  Public Class CH01DatagridWithConfirmBeforeDeleteVB
    Inherits System.Web.UI.Page

    'controls on form
    Protected WithEvents btnAdd As System.Web.UI.WebControls.ImageButton
    Protected WithEvents btnEdit As System.Web.UI.WebControls.ImageButton
    Protected WithEvents btnDelete As System.Web.UI.WebControls.ImageButton
    Protected WithEvents dgBooks As System.Web.UI.WebControls.DataGrid

    '*************************************************************************
    '
    '   ROUTINE: Page_Load
    '
    '   DESCRIPTION: This routine provides the event handler for the page load
    '                event.  It is responsible for initializing the controls 
    '                on the page.
    '-------------------------------------------------------------------------
    Private Sub Page_Load(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) _
            Handles MyBase.Load

      Dim scriptBlock As String

      If (Not Page.IsPostBack) Then
        bindData( )
      End If

      'NOTE: The following code must be processed for every rendering of the 
                        '      page or the client script will not be output when server click
                        '      events are processed.

                        'create the script block that will execute when the delete
                        'button is clicked and register it
                        scriptBlock = "<script language='javascript'>" & vbCrLf & _
                                      "<!--" & vbCrLf & _
                                      "function beforeDelete( )" & vbCrLf & _
                                      "{return(confirm('Are you sure you want to delete " & _
                                      "the selected item?'));}" & vbCrLf & _
                                      "//-->" & vbCrLf & _
                                      "</script>" & vbCrLf
                        If (Not IsClientScriptBlockRegistered("deletePromptScript")) Then
                          RegisterClientScriptBlock("deletePromptScript", _
                                                    scriptBlock)
                        End If

                        'add an attribute to the delete button that will cause the 
                        'script above to be executed when the button is clicked
                        btnDelete.Attributes.Add("OnClick", _
                                                 "return(beforeDelete( ))")

    End Sub  'Page_Load

    '*************************************************************************
    '
    '   ROUTINE: btnAdd_Click
    '
    '   DESCRIPTION: This routine is the event handler that is called when 
    '                the Add button is clicked.
    '-------------------------------------------------------------------------
    Private Sub btnAdd_Click(ByVal sender As Object, _
                             ByVal e As System.Web.UI.ImageClickEventArgs) _
                Handles btnAdd.Click

      'place code here to perform Add operations
    End Sub  'btnAdd_Click

    '*************************************************************************
    '
    '   ROUTINE: btnEdit_Click
    '
    '   DESCRIPTION: This routine is the event handler that is called when 
    '                the Edit button is clicked.
    '-------------------------------------------------------------------------
    Private Sub btnEdit_Click(ByVal sender As Object, _
                              ByVal e As System.Web.UI.ImageClickEventArgs) _
                Handles btnEdit.Click

      'place code here to perform Edit operations
    End Sub  'btnEdit_Click

    '*************************************************************************
    '
    '   ROUTINE: btnDelete_Click
    '
    '   DESCRIPTION: This routine is the event handler that is called when 
    '                the Delete button is clicked.
    '-------------------------------------------------------------------------
    Private Sub btnDelete_Click(ByVal sender As Object, _
                                                  ByVal e As System.Web.UI.ImageClickEventArgs) _
                                  Handles btnDelete.Click

                        'make sure an item is selected
                        If (dgBooks.SelectedIndex >= 0) Then
                          'place code here to perform Delete operations
                        End If
                      End Sub  'btnDelete_Click

    '*************************************************************************
    '
    '   ROUTINE: bindData
    '
    '   DESCRIPTION: This routine queries the database for the data to 
    '                displayed and binds it to the datagrid
    '-------------------------------------------------------------------------
    Private Sub bindData( )
      Dim dbConn As OleDbConnection
      Dim da As OleDbDataAdapter
      Dim ds As DataSet
      Dim strConnection As String
      Dim strSQL As String

      Try
        'get the connection string from web.config and open a connection 
        'to the database
        strConnection = _
            ConfigurationSettings.AppSettings("dbConnectionString")
        dbConn = New OleDb.OleDbConnection(strConnection)
        dbConn.Open( )

        'build the query string and get the data from the database
        strSQL = "SELECT Title, PublishDate, ListPrice " & _
                 "FROM Book " & _
                 "ORDER BY Title"

        da = New OleDbDataAdapter(strSQL, dbConn)
        ds = New DataSet
        da.Fill(ds)

        'preselect the first item in the datagrid
        dgBooks.SelectedIndex = 0

        'set the source of the data for the datagrid control and bind it
        dgBooks.DataSource = ds
        dgBooks.DataBind( )

      Finally
        'cleanup
        If (Not IsNothing(dbConn)) Then
          dbConn.Close( )
        End If
      End Try
    End Sub  'bindData

  End Class  'CH01DatagridWithConfirmBeforeDeleteVB
End Namespace

Example 1-50. Confirmation pop up before deletion in a DataGrid code-behind (.cs)

//----------------------------------------------------------------------------
//
//   Module Name: CH01DatagridWithConfirmBeforeDeleteCS.aspx.cs
//
//   Description: This class provides the code behind for
//                CH01DatagridWithConfirmBeforeDeleteCS.aspx
//
//****************************************************************************
using System;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ASPNetCookbook.CSExamples
{
  public class CH01DatagridWithConfirmBeforeDeleteCS : System.Web.UI.Page
  {
    // controls on form
    protected System.Web.UI.WebControls.ImageButton btnAdd;
    protected System.Web.UI.WebControls.ImageButton btnEdit;
    protected System.Web.UI.WebControls.ImageButton btnDelete;
    protected System.Web.UI.WebControls.DataGrid dgBooks;

    //************************************************************************
    //
    //   ROUTINE: Page_Load
    //
    //   DESCRIPTION: This routine provides the event handler for the page
    //                load event.  It is responsible for initializing the
    //                controls on the page.
    //------------------------------------------------------------------------
    private void Page_Load(object sender, System.EventArgs e)
    {
      String scriptBlock;

      // wire the item data bound and button events
      this.btnAdd.Click +=
        new ImageClickEventHandler(this.btnAdd_Click);
      this.btnEdit.Click +=
        new ImageClickEventHandler(this.btnEdit_Click);
      this.btnDelete.Click +=
        new ImageClickEventHandler(this.btnDelete_Click);

      if (!Page.IsPostBack)
      {
        bindData( );
      }

      // NOTE: The following code must be processed for every rendering of the
                        //       page or the client script will not be output when server click
                        //       events are processed.

                        // create the script block that will execute when the delete
                        // button is clicked and register it
                        scriptBlock = "<script language='javascript'>\n" +
                                      "<!--\n" +
                                      "function beforeDelete( )\n" +
                                      "{return(confirm('Are you sure you want to delete " +
                                      "the selected item?'));}\n" +
                                      "//-->\n" +
                                      "</script>\n";
                        if (!IsClientScriptBlockRegistered("deletePromptScript"))
                        {
                          RegisterClientScriptBlock("deletePromptScript", 
                                                    scriptBlock);
                        }

                        // add an attribute to the delete button that will cause the
                        // script above to be executed when the button is clicked
                        btnDelete.Attributes.Add("OnClick", 
                                                 "return(beforeDelete( ))");

    }  // Page_Load

    //************************************************************************
    //
    //   ROUTINE: btnAdd_Click
    //
    //   DESCRIPTION: This routine is the event handler that is called when
    //                the Add button is clicked.
    //------------------------------------------------------------------------
    private void btnAdd_Click(Object sender,
      System.Web.UI.ImageClickEventArgs e)
    {
      // place code here to perform Add operations
    }  // btnAdd_Click

    //************************************************************************
    //
    //   ROUTINE: btnEdit_Click
    //
    //   DESCRIPTION: This routine is the event handler that is called when
    //                the Edit button is clicked.
    //------------------------------------------------------------------------
    private void btnEdit_Click(Object sender,
      System.Web.UI.ImageClickEventArgs e)
    {
      // place code here to perform Edit operations
    }  // btnEdit_Click

    //************************************************************************
    //
    //   ROUTINE: btnDelete_Click
    //
    //   DESCRIPTION: This routine is the event handler that is called when
    //                the Delete button is clicked.
    //------------------------------------------------------------------------
    private void btnDelete_Click(Object sender,
                        System.Web.UI.ImageClickEventArgs e)
                      {
                        // place code here to perform Delete operations
                      }  // btnDelete_Click

    //************************************************************************
    //
    //   ROUTINE: bindData
    //
    //   DESCRIPTION: This routine queries the database for the data to
    //                displayed and binds it to the repeater
    //------------------------------------------------------------------------
    private void bindData( )
    {
      OleDbConnection dbConn = null;
      OleDbDataAdapter da = null;
      DataSet ds = null;
      String strConnection = null;
      String strSQL =null;

      try
      {
        // get the connection string from web.config and open a connection 
        // to the database
        strConnection = 
          ConfigurationSettings.AppSettings["dbConnectionString"];
        dbConn = new OleDbConnection(strConnection);
        dbConn.Open( );

        // build the query string and get the data from the database
        strSQL = "SELECT Title, PublishDate, ListPrice " +
                 "FROM Book " +
                 "ORDER BY Title";

        da = new OleDbDataAdapter(strSQL, dbConn);
        ds = new DataSet( );
        da.Fill(ds);

        // preselect the first item in the datagrid
        dgBooks.SelectedIndex = 0;

        // set the source of the data for the datagrid control and bind it
        dgBooks.DataSource = ds;
        dgBooks.DataBind( );
      }  // try

      finally
      {
        // clean up
        if (dbConn != null)
        {
          dbConn.Close( );
        }
      }  // finally
    }  // bindData
  }  // CH01DatagridWithConfirmBeforeDeleteCS
}

Get ASP.NET Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.