It is always important that a Delete button asks the user to confirm that the delete should take place or not. It is furthermore important that the delete button visually works as the user expects it to and doesn’t accidently delete everything in the grid. But we digress…
Displaying a message to the user can simply be done by utilising the JavaScript confirm or alert boxs… eek! I believe that this method is lazy and is frowned upon by users, although I have definitely used this method countless times before. It is also simply not retina friendly which is the current web trend to conform to.
To overcome this obstacle, I have decided to implement prettified modals with the help of ColorBox and jQuery and so far it is working quite nicely. My solution allows me to display pretty looking modals with HTML messages, a UI icon to visually depict the modal type as well as provide the ability to inject ASP.NET or HTML buttons which allows me to write server-side or client-side code for the logic required.

An example of a confirmation modal. If the user clicks Yes the page can post back and execute the click event of the server control button although I have implemented jQuery Ajax calls throughout my applications.
Source Code
You can access my project source code by right-clicking on the Source Code link and saving it to your hard drive. Please rename the file from PDF to ZIP as WordPress has limitations with the file types that can be uploaded. Source Code (Website Solution – created in Visual Studio 2012).
The Implementation
First you need to download the jQuery and ColorBox files and copy them to your website. Note: I used Example 1 of the ColorBox demo.
Once you have referenced the jQuery and ColorBox JavaScript files as well as the ColorBox StyleSheet, you are ready to rock ‘n roll!
I am going to start with the modal UI structure. If you have a look at the example figure above, you will notice a heading, icon, message and buttons. This structure is created in HTML on the master page and is hidden for standard browsing. When the ColorBox is called, the div’s HTML will be updated with the necessary values and the resulting HTML will be injected into the ColorBox to give us the final result. Note: this step can be skipped if you would prefer the HTML can be created on the fly when calling the modal.
<div class="hidden">
<div id="msg" class="modal">
<h5><span id="heading"></span></h5>
<span id="icon" class="error"></span>
<span id="message"></span>
<div id="buttons"></div>
</div>
</div>
<style type="text/stylesheet">
.hidden {display:none;}
</style>
If you preview the ColorBox demo that I used (Example 1), you will notice that the close button is at the bottom right corner of the modal by default. I decided to follow a lifelong Microsoft standard where the close button is on the top right corner of the box. To do so I had to alter the #cboxClose ID in the ColorBox stylesheet. I changed the bottom to top as indicated below.
#cboxClose{position:absolute; top:0; right:0; background:url(images/controls.png) no-repeat -25px 0; width:25px; height:25px; text-indent:-9999px;}
In order for your #msg div to be visually appealing within the modal, you will need to style it. I created modals for alert, error, question and successful messages each with their own icons which I downloaded through IconFinder. The CSS I used to style my modal is provided below:
#msg { padding: 0px 10px; padding-bottom: 0px; margin-bottom: 0px; }
#msg #heading { margin: 0px; font-size: 1.5em; }
#msg #icon { display: inline-block; float: left; width: 48px; height: 48px; margin-right: 10px; margin-bottom: 10px; }
#msg #icon.icon-alert { background-image: url(../img/modal_alert.png); }
#msg #icon.icon-error { background-image: url(../img/modal_error.png); }
#msg #icon.icon-question { background-image: url(./img/modal_question.png); }
#msg #icon.icon-success { background-image: url(../img/modal_success.png); }
#msg #buttons { clear: both; text-align: center; margin-top: 20px; margin-bottom: 10px; }
#msg #buttons input { padding: 3px 20px; }
To show the modal a showMsg function is created which requires the heading (eg. Confirm Delete), message, icon (the style of the icon eg. icon-alert) and buttons to be passed through. For the modal to work effectively (allowing the Yes button in a confirmation box to be able to execute server-side or client-side (ajax) code) it needs a div.hidden (resides on the calling page and wraps the buttons that needs to display in the modal) to be passed through. If the user sends through undefined or a blank string, the modal will display a button labeled Okay which will close the modal.
function showMsg(heading, msg, icon, buttons) {
$("#msg #heading").text(heading);
$("#msg #icon").removeClass().addClass(icon);
$("#msg #message").html(msg);
if (buttons == undefined || buttons == '') {
$("#msg #buttons").html("<input type='button' value='Okay' onclick='$.colorbox.close();' />")
} else {
if ($(buttons).html() == "") {
$("#msg #buttons").html(buttons);
} else {
$("#msg #buttons").html($(buttons).html());
}
}
if (!$("#msg").is(":visible")) {
$.colorbox({ html: $("#msg").parent().html(), width: "450px" });
} else {
$.colorbox.close();
}
}
To simplify the modal calls, I created 4 JavaScript functions which I would use throughout my application to call the modal I required. This way I could also minimise the repetition of the icon-style which needs to be passed to showMsg.
function showAlert(heading, msg, buttons) {
showMsg(heading, msg, "icon-alert", buttons);
}
function showQuestion(heading, msg, buttons) {
showMsg(heading, msg, "icon-question", buttons);
}
function showSuccess(heading, msg, buttons) {
showMsg(heading, msg, "icon-success", buttons);
}
function showError(heading, msg, buttons) {
showMsg(heading, msg, "icon-error", buttons);
}
Usage
Now that the scripts and styles are implemented, it is ready for use within our ASPX pages. Below I have created a simple grid with a delete button template field, a #pConfirmDeleteFruitButtons.hidden containing the buttons to be injected (I used client-side but you can use <asp:Button /> or simply add runat=”server” and implement the code-behind logic for server-side functionality). The confirmDeleteFruit function displays the confirm modal which will inject the #pConfirmDeleteFruitButtons div HTML. When the user clicks on the Yes button another function is fired. Note: This function can either be client or server-side depending on the application requirement.
<asp:GridView ID="gvFruit" runat="server" AutoGenerateColumns="false" DataKeyNames="Key">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="hypDelete" runat="server" Text="Delete"></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Name" DataField="Key" />
<asp:BoundField HeaderText="Description" DataField="Value" />
</Columns>
</asp:GridView>
<div id="pConfirmDeleteFruitButtons" class="hidden">
<input type="button" value="Yes" onclick="deleteFruit();" />
<input type="button" value="No" onclick="$.colorbox.close();" />
<asp:HiddenField ID="hFruitID" runat="server" />
</div>
<script type="text/javascript">
function confirmDeleteFruit(id, name) {
showQuestion('Confirm Delete', 'Are you sure you want to delete this fruit (' + name + ')?', $("#pConfirmDeleteFruitButtons"));
$('input[id$="hFruitID"]').val(id);
}
function deleteFruit() {
var id = $('input[id$="hFruitID"]').val();
showSuccess("Successful", "This fruit was successfully deleted.", undefined);
$("tr[fruit='" + id + "']").hide();
}
</script>
The VB.NET Code
I have bound the onclick and href attributes on the RowDataBound event of the GridView as indicated below.
Protected Sub gvFruit_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles gvFruit.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
'Set the row to contain a key attribute with value
e.Row.Attributes.Add("fruit", gvFruit.DataKeys()(e.Row.RowIndex)("Key").ToString())
Select Case e.Row.RowState
Case DataControlRowState.Normal, DataControlRowState.Alternate
'Configure the delete button
CType(e.Row.FindControl("hypDelete"), HyperLink).NavigateUrl = "javascript:void(0);"
CType(e.Row.FindControl("hypDelete"), HyperLink).Attributes.Add("onclick", String.Format("confirmDeleteFruit('{0}','{0}'); return false;", gvFruit.DataKeys()(e.Row.RowIndex)("Key").ToString()))
'Remember to check the string for any JavaScript unsafe characters that may break the generated script like a single '
End Select
End If
End Sub