Dynamic Data – Customizing the Delete Confirmation Dialog

I spent some time customizing the delete confirmation dialog in the Dynamic Data site I have been blogging about recently. Specifically, I looked at …

  • replacing the browsers default confirm dialog with a jquery thickbox
  • displaying a confirmation message that includes contextual information regarding the row being deleted

Below is a screen shot showing how it turned out. You can read on for the details, or you can download the site and browse the code for yourself. Hopefully DiscountASP will get upgraded to .Net 3.5 SP1 soon so I can get back to providing demos as well …

Download

image

The Default Confirmation Dialog

If you use the Dynamic Data Web Site template to create your DD web site, the List.aspx page template will already include a default delete confirmation dialog that uses the browsers confirm dialog to prompt the user before allowing them to delete a record. Nothing too fancy here, the alert box just displays some static text (the same text is displayed for all rows). If the user clicks the OK button the record is deleted. Here is what that looks like …

image

And the markup for generating this dialog is also very straight forward …

Customizing the Confirmation Message

With just a small code change, we can make use of a few DD features to add some contextual information about the row being deleted to the confirmation message. You can ask DD to retrieve a display string for any of the rows that are bound to your grid. So, with a pretty simple change we can enhance our dialog to include the display string for the row being deleted. Here is a quick example of what this looks like …

image

And here is the markup for generating this …

Notice the change to OnClientClick. Instead of static text, I am asking DD’s MetaTable (the instance the grid is bound to) to retrieve the display string that corresponds to the rows data item. Simple.

So how does DD know what the display string is? Well, you have to tell it. And you have a couple of options when doing this …

  • Override the ToString property on your entity. Below is a partial class for the Northwind Employee entity. DD will detect that I have overridden the ToString method and will use it whenever the display name is requested for an Employee.
[MetadataType(typeof(EmployeeMetadata))]
public partial class Employee
{
    public override string ToString()
    {
        return string.Format("{0} {1}", this.FirstName, this.LastName);
    }
}

And this is how this shows up in the dialog …

image

  • Apply the DisplayColumn attribute to your entities metadata class. If you don’t need to do any computations or formatting and just want to return a column value you can apply the DisplayColumnAttribute to your entities meta-class and set the DisplayColumn value to the column value you want to use for display purposes. Below is a quick example where I am using the Customer’s ContactName column as the display value (line 5) …
[Category("People")]
[Description("You can use this page to find out what your customers are up to")]
[DisplayName("Customers")]
//  Use the ContactName column for the display name
[DisplayColumn("ContactName")]
public class CustomerMetadata
{
    [DisplayName("ID")]
    public object CustomerID { get; set; }
    [DisplayName("Company")]
    public object CompanyName { get; set; }
    [DisplayName("Name")]
    public object ContactName { get; set; }
    [DisplayName("Title")]
    public object ContactTitle { get; set; }

    //  Columns I want hidden
    [ScaffoldColumn(false)]
    public object Fax { get; set; }
    [ScaffoldColumn(false)]
    public object Phone { get; set; }
    [ScaffoldColumn(false)]
    public object PostalCode { get; set; }
    [ScaffoldColumn(false)]
    public object Country { get; set; }
    [ScaffoldColumn(false)]
    public object Orders { get; set; }
}

And this is how this shows up in the dialog …

image

The only caveat here is that if you have applied a custom format to the DisplayColumn using the DisplayFormat attribute, it doesn’t look like this custom formatting will be applied when the display string is retrieved. Probably not a big deal especially since you can apply formatting using the ToString method I mention above, but it is still interesting. Here is a quick example of what I mean …

I have added the DisplayColumn attribute to my Customer metadata class like so …

//  Use the ContactName column for the display name
[DisplayColumn("ContactName")]
public class CustomerMetadata {}

And applied the DisplayFormat attribute to the ContactName property like so …

[DisplayFormat(DataFormatString = "{0} testing")]
public object ContactName { get; set; }

Then when I request the DisplayString for the Customer rows, the testing suffix is not applied …

image

I didn’t expect that. But like I said, it really isn’t a huge deal because you can always use ToString to format the column value.

Plugging in jquery’s Thickbox

And finally, if you wish to use a different dialog box instead of the browsers default you can plug that into the List.aspx page template as well. I choose to use jquery’s thickbox, but if you prefer the AjaxControlToolkit’s ModalPopup you could easily implement that as well. Here is what I did to make use of the thickbox.

  • Add the markup for the grids ItemTemplate. There are 3 main controls in my template, a link that when clicked displays the thickbox, a hidden ASP button control that is used to force the postback that causes the row to be deleted and a hidden panel that displays the delete message for the row.

image

  • Next, I added a bit of code that runs as the grids rows are bound to the data items. I first extract the thickbox hyperlink, hidden delete button, the confirm button and the panel that contains the message. After I have all of these controls I populate the NavigateUrl property on the Hyperlink to include the correct options (including the ClientID of the rows confirmation message) and use the OnClientClick property of the Yes button to issue the delete by causing the hidden delete button to initiate a postback.
protected void RowDataBound(object sender, GridViewRowEventArgs args)
{
    if (!table.IsReadOnly && args.Row.RowType == DataControlRowType.DataRow)
    {
        //  track down the controls
        HyperLink deleteLink = (HyperLink)args.Row.FindControl("btnDelete");
        Button deleteCommand = (Button)args.Row.FindControl("deleteCommand");
        Button yes = (Button)args.Row.FindControl("yes");
        Panel deleteConfirm = (Panel)args.Row.FindControl("deleteConfirm");

        //  point the thickbox at the confirmation panel for this row
        const string thickBoxOptionsFormat = "#TB_inline?height=90&width=350&inlineId={0}&modal=true";
        deleteLink.NavigateUrl = string.Format(thickBoxOptionsFormat, deleteConfirm.ClientID);

        //  when the user clicks OK, locate the hidden Delete button
        //  and click it
        const string deleteFormat = "$('#{0}').click(); return false;";
        yes.OnClientClick = string.Format(deleteFormat, deleteCommand.ClientID);
    }
}

Conclusion

Again, I am pleased with the flexibility that Dynamic Data provides me. It’s these seemingly simple requirements of providing a custom delete message that I figured would be difficult to do with Dynamic Data.

That’s it. Enjoy!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

WP Like Button Plugin by Free WordPress Templates