This article was inspired by a friend of mine who wanted to implement a delete confirmation dialog in his website, and I thought it might be a useful little tutorial to write about.
These days, I like to use the excellent Colorbox for this sort of thing. In case you haven’t heard of it or used it before, it’s simply a brilliant jack-of-all-trades Javascript pop-up library based on the even more awesome jQuery. It can display anything in a pop-up, from arbitrary Html content, flash video and an image gallery depending on how you set it up. In the past I’ve used Thickbox for this sort of thing, but as it’s not maintained any more (not to mention Colorbox looks a lot nicer) I prefer this.
For this tutorial, imagine the following scenario:
- You have some sort of form you use to add/edit some data
- This form has the usual ‘Save’, ‘Cancel’ and ‘Delete’ buttons hanging off the bottom of it
- When the user clicks ‘Delete’, you want to show them a dialog asking the user if the really want to delete
For the delete confirmation you could just redirect the user to another page and show the confirmation there, but this method is cooler, not to mention ludicrously easy. Best of all, it doesn’t interfere too much with the .Net code you would have had to write anyway. So let’s get going.
1. Creating the Visual Studio Project
For this tutorial I am using the Asp.net Website project template from Visual Studio 2010. If you’re using VS2008, the website project template in there will also do fine, but you won’t get all the jQuery files you need. You can download them separately using the links below.
Create a standard Web Site project, choose a location to save your files and hit ‘Ok’:
2. Grab Colorbox & jQuery
Grab the latest version of Colorbox from their site (1.3.9 at the time of writing). Extract the archive to somewhere temporary on your hard-drive – the file structure inside the .zip file isn’t quite suited to just being plonked into a website, so we’ll need to sort that out first.
Basically for the purposes of this demo you will want to create a simple file layout for this stuff. As I’m using Visual Studio 2010 and the ‘Website’ project template, I already have a ‘Scripts’ folder set up for me. I’m just going to shove my Colorbox files in there in a sub-folder named ‘Colorbox’. I’ll put all the images and css files in there also. So, just grab the relevant files and folders from the archive you just downloaded and copy them into your website project so that you end up with a structure that looks like this:
You will also need to download jQuery, although if you’re using Visual Studio 2010 you will already have the appropriate libraries there ready for you when you create a new website project. If you need to download it, just save in the ‘Scripts’ folder as in the image above.
3. Register jQuery and Colorbox on the page
Now to register jQuery and Colorbox on our page. For now, I’m going to work entirely within Default.aspx, so we will just register our scripts in there instead of the master page (which is where this might normally go). Include jQuery, Colorbox and the Colorbox css files at the top of Default.aspx. Again, because I’ve used the new VS2010 website templates, it has already created me a nice project with a master page and so on. On Default.aspx, it’s also created references to content placeholders, including a HeadContent which will end up in the <head> tag on the page when it is rendered. I’m going to include my JS references in there, but really at the end of the day they just need to go somewhere on your page:
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent"> <script src="/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script> <script src="/Scripts/Colorbox/jquery.colorbox-min.js" type="text/javascript"></script> <link href="/Scripts/Colorbox/colorbox.css" rel="stylesheet" type="text/css" /> </asp:Content>
By the way, the paths here assume that you’re running the website outside of a virtual directory – Visual Studio has a habit of creating website projects in virtual directories and not at the root of the URL. If you fire up the article source code, load it into VS and find that none of the scripts can be found when you test it out, that’s probably why. Simply click on the website project node in Solution Explorer, hit the F4 key to bring up the properties window and set the VirtualPath setting to just ‘/’ (without the quotes).
4. Create the dummy form
Imagine here that we have a form which is set up to edit the details of a piece of fruit from market (for the sake of the demo). I’m going to have a field which allows the user to edit the name of the fruit, and two buttons which perform a Save and a Delete operation. The only thing which is of importance to this demo is the Delete button; the rest of it is just fluff that I’m adding to give more ambience to the demo.
The form which I have created looks like this (I just created this under all the stuff that VS2010 gives you by default on default.aspx when you create a new web site project):
<div> <asp:Label runat="server" AssociatedControlID="FruitNameTextbox">Fruit name:</asp:Label> <asp:TextBox runat="server" ID="FruitNameTextbox" /> </div> <div> <asp:Button Text="Save" ID="SaveButton" runat="server" /> <asp:Button Text="Delete" ID="DeleteButton" runat="server" ClientIDMode="Static" /> </div>
5. Create the Colorbox dialog
Now for the first meaty parts of the demo. To create the dialog which will be shown by Colorbox, we simply define an area of Html which is to be shown inside the dialog when it is opened, and wrap the whole thing inside a div tag with display: none defined as its style. This is so that the dialog will not be displayed when the page is being viewed under normal circumstances. Furthermore, we attribute this area of Html with an Id so that Colorbox can pick it out.
For our dialog demo, we’re just going to ask the user to make sure that they really want to delete this item of fruit:
<div style="display: none;"> <div id="dialog"> <h1>Are you sure?</h1> <p>Are you sure you want to delete this fruit?</p> <p><strong>Note:</strong> This cannot be undone!</p> <asp:Button Text="Delete" ID="ConfirmDeleteButton" runat="server" ClientIDMode="Static" /> <asp:Button Text="Cancel" Id="CancelDeleteButton" runat="server" ClientIDMode="Static" /> </div> </div>
In here you’ll notice that we’ve put another two buttons – one for actually deleting something, and one for cancelling the dialog. We’ve also given the inner div tag an ID of ‘dialog’ so that we can reference it when setting up Colorbox.
6. Making the buttons work!
Now that (almost!) everything is in place, we can work on the client-side stuff which will actually show the dialog and enable us to cancel out of it. First of all, showing the dialog takes only a few lines. Underneath the above code, we’ll open a new script tag and handle the click event of the DeleteButton to show the dialog box:
<script type="text/javascript"> $(function () { // 1. Wire up the delete button to show Colorbox: $("#DeleteButton").colorbox({ inline: true, href: "#dialog" }); // 2. Handle the 'actual' delete button: $("#ConfirmDeleteButton").click(function() { $.fn.colorbox.close(); }); // 3. Handle the dialog cancel button: $("#CancelDeleteButton").click(function() { $.fn.colorbox.close(); return false; }); }); </script>
Here I am using some jQuery to pick up the page’s ‘load’ event using the short-hand $(function() {} );. Next, I’m using the selector of #DeleteButton to assign Colorbox to, so when that button is clicked, it will activate the Colorbox dialog. You can see as one of the parameters I’m passing the ID of our dialog code and I’m also setting the inline property to ‘true’, meaning that we want Colorbox to display content which is inline with our page, and not a piece of content hosted elsewhere (another URL for example).
Next, in step 2 we’re wiring up the dialog’s Delete and Cancel buttons. The two handlers look very similar in that all they really do is close Colorbox. However, the fundamental difference is that the handler for the Cancel button returns ‘false’, preventing the default action from happening. The ConfirmDeleteButton however will continue on and the page will post back as normal and fire the click handler for that button (we will create this in a moment), whilst still closing the dialog.
A Quick Note
You’ll notice that the buttons are attributed with ClientIdMode=”Static”. In case you haven’t seen it before, this is a new feature in .Net 4 which allows us to ensure that the Html output for a .Net control will have the same ID value as the one we give it when writing the code. This means that .Net won’t ‘mangle’ the name when used inside naming containers any more, and we can safely use the control ID from client-side code. Scott Guthrie has a detailed account ClientIdMode on his tech blog.
If you are using .Net 3.5, change the jQuery selector to instead:
$("input[id$=_DeleteButton]")
.. which basically says “Select any input element whose ID attribute value ends with _DeleteButton”, and you will get the same reliable result. You will also need to follow this for the buttons in the next section, which deal with cancelling and closing the dialog. Rick Strahl writes more about this on his blog.
7. The ConfirmDeleteButton handler
The last thing we need to do is wire up a server-side event handler for the actual delete button. This is done as normal in your code-behind (or inline if you prefer) and is no different to how you would normally handle this elsewhere. For my demo, I don’t actually have anything to delete, but I will handle it just the same way.
If we step back to the ConfirmDeleteButton for a second, and modify the mark-up to add in the name of the click handler:
<asp:Button Text="Delete" ID="ConfirmDeleteButton" runat="server" ClientIDMode="Static" OnClick="ConfirmDeleteButton_Click" />
Then include the appropriate server-side handler in the code-behind:
protected void ConfirmDeleteButton_Click(object sender, EventArgs e) { Response.Write("Fruit deleted!"); }
In my case I’m not deleting anything, but in your case this would be the place to kick off any database deletes or file modifications/changes required, then redirect the user somewhere useful.
Now, if you run the application you should be able to click on the initial delete button, have the dialog appear to reveal another delete button and a cancel button. Clicking this delete button will close the dialog but also display a message at the top of the screen (thanks to the click handler being executed). Clicking the cancel button will also close the dialog but should not refresh the page or perform any server-side postback (thanks to the ‘return false;’ in the Javascript click handler.