views:

1463

answers:

1

Here's the behavior I'm looking for:

  1. User selects a record from an index view, which redirects to that record's detail view.
  2. User clicks a link to delete the currently displayed record.
  3. A modal dialog asks for confirmation of the delete.
  4. User presses the Confirm button.
  5. The associated controller action method is executed, which is supposed to delete the record.
  6. User is returned to the index view, where the deleted record is no longer displayed.

I am using ASP.NET MVC 1.0 as the primary framework, the dialog component from the jQuery UI, and LINQ-to-SQL to handle database interaction. Steps one through four execute just fine. Step five, however, retrieves the record, but doesn't delete it. Step six executes, but the record is still displayed in the list.

Here is the code for the delete link:

<% if (Model.CanDelete())
   { %>
    <%= Html.ActionLink("Delete", "Delete", new { id = Model.Package_ID },
        new { onclick = string.Format("deletePackage({0}); return false;", Model.Package_ID) })%> |
<% } %>

Here is the code for the onclick handler:

function deletePackage(packageID) {
    createDialogContent();  // The HTML for the dialog content is set in this method
    $.getJSON('/Spectrum/Package/DetailsJSON/' + packageID, function(json) {
        $('p.message').html('Delete <strong>' + json.Description + '</strong>?');
    });
    $('div.confirm').attr('title', 'Delete Package');
    $('div.confirm').dialog({
        draggable: false,
        modal: true,
        overlay: {
            backgroundColor: '#000',
            opacity: 0.5
        },
        resizable: false,
        buttons: {
            'Confirm': function() {
                $(this).dialog('destroy').remove();
                $.post('/Spectrum/Package/Delete/' + packageID);
                // The next line used to be: $.get('/Spectrum/Package/Index');
                window.location.href = '/Spectrum/Package/Index';
            },
            Cancel: function() {
                $(this).dialog('destroy').remove();
            }
        }
    });
}

Here is the code for the delete controller method:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(int id)
{
    Package package = RepositoryManager.Package().GetPackage(id);
    PackageDeleteViewModel viewModel = new PackageDeleteViewModel
    {
        Package_ID = package.Package_ID
    };

    RepositoryManager.Package().PackageDelete(viewModel);  // see code below

    return new EmptyResult();
}

Finally, here is the repository method for the delete:

public void PackageDelete(PackageDeleteViewModel data)
{
    Package package = RepositoryManager.Package().GetPackage(data.Package_ID);

    if (package.BrokerageOrderPackages.Count == 0
        && package.ManagementOrderPackages.Count == 0
        && package.Seeds.Count == 0)
    {
        db.Packages.DeleteOnSubmit(package);  // This branch is being executed
        db.SubmitChanges();
    }
    else
    {
        throw new RulesException("Package cannot be deleted.", "PackageDelete");
    }
}

I don't think I'm pushing the envelope here or getting too fancy. One area of concern: In the Confirm button handler of the onclick method, the first version would delete the record successfully, but not redirect to the Index view. With the current version, the delete fails silently, but the redirection occurs. Firefox/Firebug reported 200's for the Index GET in both situations. The behavior is similar in both Firefox and IE.

Any advice or solutions will be greatly appreciated.

+1  A: 

$.post is an async ajax request, if you reload the page the call gets cancelled. You should reload the page on its callback function parameter:

$.post('/Spectrum/Package/Delete/' + packageID, 
       null, 
       function(json){ 
            if (json.success) {
                window.location.href = '/Spectrum/Package/Index';
            } else {
                // jquery dialog call or
                alert(json.errorMessage);
            }
       },
       'json');

And the controller code:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(int id)
{
   try {
      // Validation and deletion code
   } catch exception ex {
      return Json(new {errorMessage = ex.Message, success = false});
   }
   return Json(new {success = true});
}
bortao