简体   繁体   中英

How to handle an edit and delete button on the same form in ASP.NET MVC?

Consider the following markup:

<h2>Edit SAS Program</h2>
@using (Html.BeginForm("Edit", "SasProgram", FormMethod.Post))
{
    <label for="Name">Name</label>
    @Html.TextBoxFor(model => model.Name)

    using (Html.BeginForm("Delete", "SasProgram", FormMethod.Post))
    {
        <input type="submit" class="button" value="Delete" />
    }
    <input type="submit" class="button" value="Save Changes" />
}

I'd like to have the Delete button on the same view as the Edit . However, it's not letting me have nested forms. What is the appropriate way to handle this situation?

I tried leveraging this answer, How to handle nested forms in ASP.NET MVC , but it's a broken link now.

I would use different values for button name in the same form:

@using (Html.BeginForm("Edit", "SasProgram", FormMethod.Post))
{
    <label for="Name">Name</label>
    @Html.TextBoxFor(model => model.Name)

    <button name="action" value="delete">Delete</button>
    <button name="action" value="save">Save Changes</button>
}

and then switch in controller:

[HttpPost]
public ActionResult Edit( SomeModel model, string action )
{
    switch( action ) {
        case "delete":
            // delete action
            break;
        case "save":
            // save action
            break;
    }
}

The code is written from memory but it works in production. Note that buttons are of default type - submit.

The best and easiest way would be to use two forms but don't nest them:

<h2>Edit SAS Program</h2>
@using (Html.BeginForm("Edit", "SasProgram", FormMethod.Post))
{
    <label for="Name">Name</label>
    @Html.TextBoxFor(model => model.Name)

    <input type="submit" class="button" value="Save Changes" />
}

@using (Html.BeginForm("Delete", "SasProgram", FormMethod.Post))
{
    <input type="submit" class="button" value="Delete" />
}

This way you have:

  • Two separate forms
  • No GET requests
  • The delete button below the edit button, which makes more sense when you're on a view that allows you to edit something.

First of all. Every modification request should be use the post method.
I make some R&D and build the basics of a multi submit button handler in a wiki A clean solution to use multiple submit button in ASP.NET MVC .
I think it could solve your problem.

First, you cannot nest <form> element. The specification doesn't allow it. Since you are using the MVC pattern I have two options that came to my mind:

  1. You can retain the save button as the submit button of the form, and make the delete button a HTML link. Then the delete button will target to a different route, it could be something like: GET /program/delete/{id} .

  2. You can have two buttons inside the same form, then with JavaScript after clicking one of the buttons you will change the action attribute of the form.

Update

There is a third option, that is more clean: using two submit buttons with same name attribute and different values .

Your form will have two buttons:

public ActionResult MyAction(string submitButton) {
    switch (submitButton) {
        case "save":
            // ...
        case "delete":
            // ...
    }
}

For more details check this answer: https://stackoverflow.com/a/443047/439427

You can also use html 5 feature to target a form from an input button. Below I have created both a delete and save form and have the submit buttons outside of the forms but targeting them via the form attribute.

I think most browsers support this except IE.

No javascript required.

@using (Html.BeginForm("Edit", "SasProgram", FormMethod.Post, new { id = "editForm" }))
{
    <label for="Name">Name</label>
    @Html.TextBoxFor(model => model.Name)
}

@using (Html.BeginForm("Delete", "SasProgram", FormMethod.Post, new { id = "deleteForm" }))
{
    <input type="submit" class="button" value="Delete" />
}

<input type="submit" class="button" value="Save" form="editForm"/>
<input type="submit" class="button" value="Delete" form="deleteForm" />

This allows for a nice button layout without any fancy javascript or css styling.

The OLD way to do this but still applicable is to have one form tag and change the action with multiple submit buttons.

<input class="btn btn-default" type="submit" value="Save" />
<input class="btn btn-default" type="submit" value="Delete" onclick="this.form.action='/SasProgram/delete/@Model.Id';" />

Edit : Here's how to do it with ajax using an HttpPost.

//
// POST: /Divisions/Delete
[HttpPost, ActionName("Delete"), Authorize]
public ActionResult DeleteConfirmed(int id)
{
    Division division = _db.Divisions.Single(x => x.DivisionId == id);

    string errorMessage;
    if (DbRelationEnforcer.CanDelete(_db, division, out errorMessage))
    {
        division.SetDeleted(User.Identity.Name);
        _db.SaveChanges();
        return Json(new JsonResponseCreatePartial { Success = true }, JsonRequestBehavior.AllowGet);
    }

    return Json(new JsonResponseCreatePartial { Success = false, Message = errorMessage }, JsonRequestBehavior.AllowGet);
}

Then, on the view, you must use the <input type="submit">Save changes</input> to save your changes (within the form), and a simple link/button to delete, like this:

<h2>Edit SAS Program</h2>
@using (Html.BeginForm("Edit", "SasProgram", FormMethod.Post))
{
    <label for="Name">Name</label>
    @Html.TextBoxFor(model => model.Name)

    <input id='delete-btn' type="button" class="button" value="Delete" />
    <input type="submit" class="button" value="Save Changes" />
}

Finally, you have to use JS to post to your action from the view, when the user clicks on Delete.

<script type='text/javascript'>
    $(function() {
        $("input#delete-btn").click(function(){
            $.post('@Url.Action("Delete")', '@Model.Id', function(data) {
                if(data.Success) {
                    ' ... handle the success case
                } else {
                    ' ... error management
                }
            });
        });
    });
</script>

This will work, but in order to have a better UX, it would be preferable to have the Delete button from the Index/list view, and using a JQuery UI dialog to confirm before doing the ajax post. This will skip having to load the Edit page if/when you want to delete multiple items one after the other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM