dinsdag 10 februari 2009

jQuery delete link with downlevel support: my version

Phil Haack recently blogged on using jQuery for creating a delete link in ASP.NET MVC which uses ajax when available, while still using conventional form posts when needed. One of the comments was about using the same html link in both cases opposed to changing from a html link to a submit button and vice versa. One advantage of that is that you enable a common case when deleting an item: a confirmation dialog/screen.
It just so happens that I recently implemented a very crude version of this in my pet project.

First off, I’d like to mention that I left out some of the implementation details, as that would cloud the example. Things like anti forgery tokens and such are your own responsibility. Ok, let’s get started.

The HTML rendered looks like this, more or less:

<table class=”gridview”>
<tr>
<th>field1</th>
<th>field2</th>
<th>actions</th>
</tr>
<tr>
<td>fieldvalue1</td>
<td>fieldvalue2</td>
<td><a href=”/MyController/Delete/1” class=”delete-link”>delete</a>
</tr>
</table>


When this renders, it will show a simple grid, with a delete link on the data row. Each additional data row follows the same pattern, obviously. The route on the link leads to the following method on the controller:



[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Delete(int? id)
{
ViewData["id"] = id;
return View();
}


Simple enough, it renders a view called delete.aspx, which will render our confirmation form. I accept a nullable int here, I’ll explain why later on. The view rendered outputs the a form in this fashion:



<form action=”/MyController/Delete/1”>
<input type=”submit” value=”yes I’m sure!” />
</form>


It takes the id for the route from the viewdata, nothing more, nothing less. When submitted, it leads to this method on the controller:



[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(int id)
{
// delete your entity here, then check if it’s ajax, if not, redirect to your list overview or something
return RedirectToAction(“list”);
}


Now, this is why I accepted a nullable int as an argument for the confirmation form. Because I needed an int on both the post- and the get-action, I wanted two different methods. However, I can’t have two methods on the same class which have the same signature. By changing one of the ints to nullable I have two different methods, with the same name and almost the same signature. Close enough to allow the same route to lead to both methods if needed. By distinguishing on HTTP verbs I won’t get an exception about ambigious routes.



Now, for the jQuery ajax magic, I added a little script to the top of the page, which does little more than add an onclick event to the delete links. It’s not much different from Phil’s code:



$(".gridview .delete").click(function()
{
if(confirm("Are you really sure?"))
{
$.post(this.href);
}
return false;
});


There you have it. When javascript is turned off, the delete link leads to a confirmation page showing a form with a confirmation button. Click the button and the delete function is called, redirecting to the list view after deleting the item. When javascript IS available, a confirm dialog pops up, and it will delete the item when you click ‘Ok’. Now you will have to fill in the blanks, like reloading your list view when an item is deleted or something like that.

Geen opmerkingen: