Stop Accidental Deletions

Use confirmation boxes to make sure your users aren’t deleting data they need tokeep.

Hot Tip

LANGUAGE: C#

ASP.NET VERSIONS: 1.0 | 1.1

 

Stop Accidental Deletions

Use confirmation boxes to make sure your users aren't deleting data they need to keep.

 

By Jeff Prosise

 

It's easy -too easy - to put Delete buttons in a DataGrid. Here's a DataGrid that displays records from SQL Server's Pubs database and uses a ButtonColumn to create a column of Delete buttons. Clicking one of the Delete buttons "deletes" the corresponding record from the database:

 

<%@ Import Namespace="System.Data" %>

<%@ Import Namespace="System.Data.SqlClient" %>

<html>

  <body>

    <form runat="server">

      <asp:DataGrid RunAt="server" ID="MyDataGrid"

        AutoGenerateColumns="false" CellPadding="2"

        Width="100%" Font-Name="Verdana" Font-Size="8pt"

        OnItemCommand="OnDeleteRecord">

        <Columns>

          <asp:ButtonColumn Text="Delete"

            ItemStyle-HorizontalAlign="center"

            ButtonType="PushButton"

            CommandName="Delete" />

          <asp:BoundColumn HeaderText="Item ID"

             DataField="title_id" />

          <asp:BoundColumn HeaderText="Title"

            DataField="title" />

          <asp:BoundColumn HeaderText="Price"

            DataField="price"

            DataFormatString="{0:c}"

            ItemStyle-HorizontalAlign="right" />

        </Columns>

        <HeaderStyle BackColor="teal" ForeColor="white"

          Font-Bold="true" HorizontalAlign="center" />

        <AlternatingItemStyle BackColor="beige" />

      </asp:DataGrid>

      <asp:Label ID="Output" RunAt="server" />

    </form>

  </body>

</html>

<script language="C#" runat="server">

void Page_Load (Object sender, EventArgs e)

{

    if (!IsPostBack) {

        SqlConnection connection = new SqlConnection

             ("server=localhost;database=pubs;uid=sa");

        try {

            connection.Open ();

            SqlCommand command = new SqlCommand

                 ("select * from titles where price != 0",

                connection);

            SqlDataReader reader = command.ExecuteReader ();

            MyDataGrid.DataSource = reader;

            MyDataGrid.DataBind ();

        }

        finally {

            connection.Close ();

        }

    }

}

void OnDeleteRecord (Object sender,

    DataGridCommandEventArgs e)

{

    if (e.CommandName == "Delete") {

         Output.Text = "Deleted \"" +

            e.Item.Cells[2].Text + "\"";

    }

}

</script>

 

Unfortunately, code like this is an accident waiting to happen. A user can too easily delete a record by accident. When you deploy a DataGrid with Delete buttons, go the extra mile and inject some client-side script that pops up a confirmation dialog before proceeding with a record deletion. The ItemCreated events that a DataGrid fires as it renders its rows are the perfect place to attach a snippet of JavaScript to each Delete button. To demonstrate, the following page is functionally equivalent to the one above, but the postbacks generated by the Delete buttons are suppressed unless the user answers in the affirmative when prompted "Are you sure?" The changes are highlighted in bold:

 

<%@ Import Namespace="System.Data" %>

<%@ Import Namespace="System.Data.SqlClient" %>

<html>

  <body>

    <form runat="server">

      <asp:DataGrid RunAt="server" ID="MyDataGrid"

        AutoGenerateColumns="false" CellPadding="2"

         Width="100%" Font-Name="Verdana" Font-Size="8pt"

        OnItemCreated="OnAttachScript"

        OnItemCommand="OnDeleteRecord">

        <Columns>

          <asp:ButtonColumn Text="Delete"

            ItemStyle-HorizontalAlign="center"

            ButtonType="PushButton"

            CommandName="Delete" />

          <asp:BoundColumn HeaderText="Item ID"

            DataField="title_id" />

          <asp:BoundColumn HeaderText="Title"

            DataField="title" />

          <asp:BoundColumn HeaderText="Price"

            DataField="price"

            DataFormatString="{0:c}"

            ItemStyle-HorizontalAlign="right" />

        </Columns>

        <HeaderStyle BackColor="teal" ForeColor="white"

          Font-Bold="true" HorizontalAlign="center" />

         <AlternatingItemStyle BackColor="beige" />

      </asp:DataGrid>

      <asp:Label ID="Output" RunAt="server" />

    </form>

  </body>

</html>

<script language="C#" runat="server">

void Page_Load (Object sender, EventArgs e)

{

    if (!IsPostBack) {

         SqlConnection connection = new SqlConnection

             ("server=localhost;database=pubs;uid=sa");

        try {

            connection.Open ();

            SqlCommand command = new SqlCommand

                 ("select * from titles where price != 0",

                connection);

            SqlDataReader reader = command.ExecuteReader ();

            MyDataGrid.DataSource = reader;

            MyDataGrid.DataBind ();

        }

        finally {

            connection.Close ();

        }

    }

}

void OnAttachScript (Object sender, DataGridItemEventArgs e)

{

    if (e.Item.ItemType == ListItemType.Item ||

        e.Item.ItemType == ListItemType.AlternatingItem) {

            WebControl button =

                 (WebControl) e.Item.Cells[0].Controls[0];

            button.Attributes.Add ("onclick",

                "return confirm (\"Are you sure?\");");

    }

}

void OnDeleteRecord (Object sender,

    DataGridCommandEventArgs e)

{

    if (e.CommandName == "Delete") {

        Output.Text = "Deleted \"" +

             e.Item.Cells[2].Text + "\"";

    }

}

</script>

 

The OnAttachScript method, which is called for each and every row the DataGrid renders, reaches into the row just rendered, finds the Delete button, and adds an onclick attribute that references the following piece of JavaScript:

 

return confirm ("Are you sure?");

 

A JavaScript-enabled browser will execute this script any time a Delete button is clicked. The confirm function displays the "Are you sure?" dialog and returns true or false indicating the user's response. Returning true from the onclick handler allows the postback to go through, but returning false prevents the postback from happening, and therefore prevents ASP.NET from knowing that the Delete button was clicked.

 

Remember, an ounce of prevention is worth a pound of cure. Not only might this technique save you some headaches, it might prevent a lawsuit, too!

 

Jeff Prosise is author of several books, including Programming Microsoft .NET (Microsoft Press). He also is a co-founder of Wintellect (http://www.wintellect.com), a software consulting and education firm that specializes in .NET. Contact Jeff at [email protected].

 

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish