ASP MVC – Delete confirmation with Ajax & jQuery UI Dialog

In this post I will show you how I implemented a delete confirmation implementation for MVC using the jQuery UI Dialog control. I have done this by adding virtually no customization to the templates generated ASP.Net MVC, and aiming the functionality to be as reusable as possible.

Our Objective

When a user clicks the “Delete” button on a list (or elsewhere), we are going to show a confirmation dialog. If the user confirms, the record will be deleted. If he/she cancels, no action will be taken. In essence, this is what we are trying to do:

Requirements

To implement this solution you will need to have the jQuery and jQueryUI libraries.

Approach

1. Modify the repeater.

We will start by reviewing the code for a strongly-typed view for the “List” content; the repeater part looks like this:

<% foreach (var item in Model) { %>
<tr >
<td><%: item.Name %></td>
<td>
<%: Html.ActionLink(“Edit”“Edit”new {  id=item.Id  }) %> |
<%: Html.ActionLink(“Delete”“Delete”new { id = item.Id }, new { @class = “delete-link” })%>
</td>
</tr>
<%%>

This is pretty much what is automatically generated, with the difference that I have added a class to the delete action link (bolded above). These will help me identify the object with jQuery.

The repeater above generates the following HTML:

<tr>
   <td>Item 1td>
   <td>
      <a href="/Brand/Edit/18">Edit</a> |
      <a class="delete-link" href="/Brand/Delete/18">Delete</a>
    </td>
</tr>    

Notice that the Delete link is already pointing to the Controller/Action we want.

2. Add the confirmation message

You will need to add a div tag with the confirmation message to display, simply add this:

<div id="delete-dialog" title="Confirmation">
<p>Are you sure you want to delete this Brand?</p>
</div>		

You can change the title of the confirmation box by changing the “Title” property on the div.

3. Add the jQuery

This jQuery can be added in individual pages, in my case I added it on the Master Page so it would be reusable across many pages.

Let’s go by steps; first we need to override the delete link behaviour. Here is how:

var deleteLinkObj;
// delete Link
$('.delete-link').click(function () {
    deleteLinkObj = $(this);  //for future use
    $('#delete-dialog').dialog('open');
    return false; // prevents the default behaviour
});

The snippet above is basically overriding the default functionality of all objects that have the class “delete-link”. Now, instead of directing to the specific controller/action, it will open a dialog (with ID “delete-dialog” -> the div we added on step 2).

Notice we are storing the clicked object on a variable; this is so the dialog knows which link was the one clicked.

Now we need to initialize the Dialog and its behaviour. Here we go:

$('#delete-dialog').dialog({
  autoOpen: false, width: 400, resizable: false, modal: true, //Dialog options
  buttons: {
     "Continue"function () {
          $.post(deleteLinkObj [0].href, function (data) {  //Post to action
             if (data == '<%= Boolean.TrueString %>') {
                deleteLinkObj.closest("tr").hide('fast'); //Hide Row
                //(optional) Display Confirmation
             }
             else {
                //(optional) Display Error
             }
            });
          $(this).dialog("close");
       },
      "Cancel"function () {
          $(this).dialog("close");
          }
      }
 });

Let’s brake it down to the important parts:

$.post(linkObj[0].href, function (data) {…

What we are doing here is posting into the objects href attribute which is something like /Brand/Delete/18. So we are posting to the Delete action of the Brand controller with an specific ID. The controller as we will see next, will return on the data either True or False, indicating success/failure.

When the post is successful, we now need to remove the item from the list. We do it with this simple line:

linkObj.closest(“tr”).hide(‘fast’);

What we are doing is locating the closes tr parent, and hiding it… Simple! (You’ve got to love jQuery).

4. Prepare the controller

Your page is now ready, but we need to add the logic on the controller action; there is not view related to the delete action, so you only need to implemented the HttpPost action. This is actually very simple, in my case, here is how I do it:

[HttpPost]
        public ActionResult Delete(int id)
        {
            try
            {
                BrandRepostory rep = new BrandRepostory ();
                rep.DeleteById(id);
                return Content(Boolean.TrueString);
            }
            catch
            {//TODO: Log error				
                return Content(Boolean.FalseString);
            }
        }

That is it! This implementation is highly reusable, just remember to:

  1. Mark the delete button with the class
  2. Add the div for the confirmation message
  3. Make sure the javascript code is available for the pages you need.
  4. Implement the controller action

Hope this helps.. Get Source Code

UPDATE! Related Post: Editing rows with the jQueryUI Dialog Form and Ajax

Author: ricardocovo

Senior Software Architect/Developer with extensive experience in web related technologies.

69 thoughts on “ASP MVC – Delete confirmation with Ajax & jQuery UI Dialog”

  1. What version of JQuery you are using? I am using the default one created with MVC project (1.3.2) and it doesn’t seem like that the dialog is a property of the $. I get run time error for your code.

    Any ideas?

  2. This is close to what I need. Instead of deleting, I have a link on my list to copy the item. I want the confirmation box to open and allow the user to enter a value. The controller action will then take the id of the entry and the value entered on the confirmation dialog and create copies of that item.

    Thanks

    1. Do you mean if there is an error with the delete action? I would just return a third value from the web service, and have the javascript handle it.

  3. Could you please show us how we could modify this code to do the same with the submit buttons of the forms?

    Thanks, your sample were very usefull.

  4. A little question: In this example, the controller returns Content(Boolean.TrueString);

    What if i’m returning a View() function because I want to redirect to some page when success? With your sample the returned view will be stored into the ‘Data’ variable of your javascript and the redirection will not be done.

    Sorry if i’m doing too many questions. I’m really newby.

    Thanks Again.

  5. Well, if you know htat “True” is a success, then you can do the redirection by doing something like:

    if(data==”True”) window.location = ‘someurl’;

  6. I am using Webgrid.Now the data is getting deleted from database but the webgrid is not getting refeshed automatically.I need to do it manually.

    1. Hi,

      I haven’t used WebGrid, but what I would recommend is to see the HTML and check how the row is constructred. The line of code that hides the row after deletion is this:

      deleteLinkObj.closest("tr").hide('fast');

      As you can see, is looking for the closest

      , is that assumption still valid in the html output of a webgrid?

      I hope that helps,
      -Ricardo

  7. Hi, Ricardo,

    This is a splendid example to understand how to use jQuery. Especially, thanks for your sample Visual Studio solution.

    Thanks.

  8. Hi, Ricardo, thanks for your sample

    How can i show an error message in the same modal window when you can not delete the record? //(optional) Display Error

    like this “Could not delete the record”

    blessings

  9. @Cadavid,

    Here is how I do it:

    1. Change the message on the dialog, all you need to do is change the dialog HTML: $(“#delete-dialog”).html(‘an error occurred’);

    2. Make sure you only close the dialog on success.

    3. When an error occurrs, disable the first button (“Continue”) from the dialog:
    $(“:button:contains(‘Continue’)”).attr(“disabled”,”disabled”).addClass(“ui-state-disabled”);

    Hope this helps,
    -Ricardo

  10. yo modifique tu codigo para mostrar error cuando no se puede eliminar un registro y no me funciona bien, puedes ayudarme?

    buttons: {
    “Continue”: function () {
    $.post(deleteLinkObj [0].href, function (data) { //Post to action
    if (data == ”) {
    deleteLinkObj.closest(“tr”).hide(‘fast’); //Hide Row
    //(optional) Display Confirmation
    }
    else {
    $(“#delete-dialog”).html(‘an error occurred’);
    $(“:button:contains(‘Continue’)”).attr(“disabled”,”disabled”).addClass(“ui-state- disabled”);

    //(optional) Display Error
    }
    });
    $(this).dialog(“close”);
    },
    “Cancel”: function () {
    $(this).dialog(“close”);
    }
    }

    1. I modified your code to display error when can not delete a record and I do not work well, can help me?

      buttons: {
      “Continue”: function () {
      $.post(deleteLinkObj [0].href, function (data) { //Post to action
      if (data == ”) {
      deleteLinkObj.closest(“tr”).hide(‘fast’); //Hide Row
      //(optional) Display Confirmation
      }
      else {
      $(“#delete-dialog”).html(‘an error occurred’);
      $(“:button:contains(‘Continue’)”).attr(“disabled”,”disabled”).addClass(“ui-state- disabled”);

      //(optional) Display Error
      }
      });
      $(this).dialog(“close”);
      },
      “Cancel”: function () {
      $(this).dialog(“close”);
      }
      }

  11. mandame un correo a covosoft [at] gmail.com y yo te mando un codigo para lo que tu estas haciendo.

  12. IN case anyone else is having problems display an error, here is one way to do it (this code is inside the $.post:


    if (data == 'True') {
    // ...nothing changed here
    }
    else {
    //Show the errror on the dialog content.
    $("#delete-dialog > p").html("Ooops... Something failed. Please try again.");
    //Hide confirmation button
    $(":button:contains('Continue')").css("display","none");

    }

    You would have to re-set the original message everytime the dialog is opened:

    $('.delete-link').click(function () {
    $("#delete-dialog > p").html("Are you sure you want to delete this?");
    //...Existing code
    });

    Hope this helps,
    -Ricardo

    1. Jagner, all the code is in the source code. but basically:

      • add a div as follow: <div id=”commonMessage”></div>
      • When you need to show the message, call it with jquery:
        $('#commonMessage').html("Update Complete");
        $('#commonMessage').delay(400).slideDown(400).delay(3000).slideUp(400);

      The style for this DIV, would be something like this:

      #commonMessage {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 70px;
      font-size:28px;
      line-height: 70px;
      text-align: center;
      color: #000;
      background: #fff;
      border-bottom: 1px solid #ddd;
      filter:alpha(opacity=92);
      -moz-opacity: 0.92;
      opacity: 0.92;
      display: none; /* LEAVE THIS IN*/
      }

      Hope this helps,

  13. Hi Sir Covo! This is a really cool tutorial! Thank you very much!
    I have one question, though. I’m trying to work around your javascript to include an Insert functionality but I’m currently having a hard time since i’m not really very familiar with javascript. What I want to do is to insert the fields on the HTML table after I click on the Update button from the pop-up. I already have both your delete and edit but I can’t seem to make my own Insert to work. Can you point me to the right direction to get this working? Thank you!!

  14. Hi, Thank you for the wonderfull information. If I want use these steps, what should I put as BrandRepostory rep = new BrandRepostory (); for my project?

  15. I am so sorry I ask for more explanations , I am so new to .net and mvc. I just added steps 1 to 3 to my code but for step 4, I added a new control and I added your code to my control. But I get an error on BrandRepositry and I don’t know what to put instead of it.

  16. thanks for your usefull reply. I am facing one more problem today, i want to upload files from Ajax.BeginForm() using file upload control but i am finding HttpPostedFileBase object is null on controller. is there is any method to upload files from AJAX Form.

    Thanks

  17. Hi Ricardo,

    I have a related question, i learn ms-mvc now and don´t have some know-how to use a combination of elements you have showed here.
    I work on show dialog with a condition in controller method,i shave to show on view, but supose if i need to show condictionally, autoopen:false and now how i need to trigger this dialog if controller method have a one condition and another continues executing code. How to make this?

  18. I did exactly the same thing, but I got error: Uncaught TypeError: Object [object Object] has no method ‘dialog’.. I am using MVC4 with VS2010 VWD (.NET 4.0). I used google CDN to add jquery amd jqueryui. I have a ajax call that works perfectly, but this keeps giving me this error, it seems it could not find jqueryui.js. Not sure whay, anything to do with MVC4?

  19. am getting error in deleteById()………. like missing using directive or any assembly reference or doesnot contaon definition for deleteById().

  20. Thanks for sharing! Just wanted to add, that this code does not seem to work when the Delete Action has the ValidateAntiForgeryToken Attribute. Took me a while to figure that out 😉 !

    1. Hi Diego,

      When I originally posted this code, the AntiForgeryToken had not been introduced. If you want to use it, you would have to:

      1. Render the token on the page (hidden input)
      2. Make sure you send tne token into the action on the post data

      Hope this helps,
      -Ricardo

  21. I have a image in the controller, on clicking that image in the controller i should display this dialog box in the same page without redirecting to other page, how do i do that?

  22. Hi, I am trying to implement this but the buttons don’t show up (Continue and Cancel). You don’t show them in your markup. Are they dynamically created through one of the jquery libraries?

    1. Look at step 3, is where the dialog is setup. Bare in mind that this post is quite old and the jquery.ui controls might have changed.

      1. Ok cool I got it to work. My post works and I am able to delete out of the dbase. One more question please. These lines of code… $.post(deleteLinkObj[0].href, function (data) { //Post to action
        if (data == ”) {
        deleteLinkObj.closest(“tr”).hide(‘fast’); //Hide Row
        //(optional) Display Confirmation
        alert(‘test’);
        }
        it never hits deleteLinkObj or the alert and I get no errors. The syntaxt for Boolean.TrueString looks like asp.net but I am working in Razor. Do you know how to convert it to work in mvc razor?

  23. Hello Sir ,

    How It Is Possible in Ajax Hyper Link

    @grid.GetHtml(
    tableStyle:”gridtable”,
    selectedRowStyle: “select”,
    alternatingRowStyle : “alternate”,
    columns:grid.Columns(
    grid.Column(header:”Country Id”,columnName:”countryid”),
    grid.Column(header:”Country Name”, canSort:true ,columnName:”country_name”),
    grid.Column(header:”Country Code”,columnName:”country_code”),

    //grid.Column(format: (item) => Html.ActionLink(“Edit”, “editcountry”, new { param1 =@item.countryid, parma2=”optional” })),

    grid.Column(header:”Edit”, format: (item) => @Ajax.ActionLink(“Edit”,
    “EditRecord”,null,
    new { recordID = @item.countryid, @id=”div2″},
    new AjaxOptions { InsertionMode = InsertionMode.Replace,
    UpdateTargetId = “lowerright”, }

    )),

    grid.Column(header:”Delete”, format: (item) => @Ajax.ActionLink(“Delete”,
    “DeleteRecord”,

    new { recordID = @item.countryid },
    new AjaxOptions { InsertionMode = InsertionMode.Replace,
    UpdateTargetId = “lowerleft” }
    )

    )))

    Thanks and Regards
    vishal mahajan

    vishalmahajan51@yahoo.com

  24. If you want to customise the text in the confirmation dialog with table row data e.g. “Are you sure you want to delete Joe Blogs?” use the following.

    1. In the View:
    @Html.ActionLink(“Delete”, “Delete”, new { id = item.UserId }, new { @class = “delete-link”, name=item.Username})

    This will set the Name attribute to the data you want (in this case the Username.

    2. In the script, modify:
    $(‘.delete-link’).click(function () {
    deleteLinkObj = $(this); //for future use
    var deletionTarget = deleteLinkObj[0].name;
    $(“#delete-dialog > p”).html(“Are you sure you want to delete ” + deletionTarget + “?”);
    $(‘#delete-dialog’).dialog(‘open’);

    This will dynamically modify the dialog box text with a more meaningful message.

  25. I’m not sure why but this site is loading extremely slow for me.
    Is anyone else having this issue or is it a issue on my end?

    I’ll check back later and see if the problem still exists.

  26. thanks A lot U made my day.I used it for Ajax.actionLink.changed click event to “Live” and this line linkObj.closest(“tr”).hide(‘fast’); to deleteLinkObj.closest(“tr”).remove(); .thanks a lot thanks a lot

  27. Hi,
    How to customize this for a “display details” scenario: I am in an Index view, and for given record I want to go to view Details.
    But before this I want a popup confirmation (Are you sure that you want to go forward? yes/no ).
    If yes go to ActionResult Details(int? id) in Controller, if no Stay in Index. In index view I have a
    @Html.ActionLink(” Detalii …”, “Details”, “Candidates”, new { id = item.IdCV }, new { @class = “btn btn-default fa fa-link details-link” })
    Eventually to display in popup some values that normally in ActionResult Details() I obtain from AspNetUsers for the current user. (“You have (x) credits and you will consume (y) credits! Are you sure that you want to go forward? yes/no)

  28. I am able to get this working but css of the modal dialog box is not loading. I am using jquery 1.4 and for css I am using twitter bootstrap 3.3.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: