bootstrap modal for delete confirmation mvc
Asked Answered
P

3

5

I'm developing an MVC 5 web application. Within one of my Razor Views I have a table which spits outs several rows of data.Beside each row of data is a Delete button. When the user clicks the delete button I want to have the Bootstrap Modal popup and ask the user to confirm their deletion.

  1. add line before foreach loop

    @Html.Hidden("item-to-delete", "", new {@id = "item-to-delete"})
    @foreach (var item in Model)
    {
        <td>
            <button type="" class="btn btn-sm blue deleteLead" 
                data-target="#basic" data-toggle="modal" 
                data-id="@item.bookid">delete</button>
        </td>
    }
    

2.and my modal

<div class="modal fade" id="basic" tabindex="-1" role="basic" aria-hidden="true" style="display: none;">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
                <h4 class="modal-title">book Delete Confirmation</h4>
            </div>
            <div class="modal-body">
                Are you Sure!!! You want to delete this Ad?
            </div>
            <div class="modal-footer">
                <button type="button" class="btn blue" id="btnContinueDelete">Continue</button>
                <button type="button" class="btn default" data-dismiss="modal">Cancel</button>
            </div>
        </div>
    </div>
</div>

script

<script>
    $(".deletebook").click(function(e) {
        e.preventDefault();
        var id = $(this).data('id');
        $('#item-to-delete').val(id);
    });
    $('#btnContinueDelete').click(function() {
        var id = $('#item-to-delete').val();
        $.post(@Url.Action("Deletebook", "book"), { id: id }, function(data) {
            alert("data deleted");
        });
    });
</script> 

in console i get => Empty string passed to getElementById().

Penna answered 4/3, 2015 at 10:57 Comment(2)
id from item-to-delete return nullHag
I know I am late to the game but the selector in code section 2 is class called "deleteLead" and the script is looking for $(".deletebook").click(....Recessive
H
8

Warning, its not safe to delete items via GET request!
Finally I found a way to use bootstrap modal dialog to confirm delete list item:

<tbody>
    @foreach (var item in Model)
    {
        <tr>
            <td>
                <a id="deleteItem" class="deleteItem" data-target="#basic" 
                    data-toggle="modal" 
                    data-path="@Url.Action("Delete", "MyController", new { id = @item.id })">Delete</a>
            </td>
            <td>@Html.DisplayFor(modelItem => item.name)</td>
        </tr>
    }
</tbody>

This is my modal html

<div class="modal fade" id="basic" tabindex="-1" role="basic" aria-hidden="true" style="display: none;">
<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
            <h4 class="modal-title">Delete Confirmation</h4>
        </div>
        <div class="modal-body">
            Are you sure you want to delete this item?
        </div>
        <div class="modal-footer">
            <button data-dismiss="modal" type="button" class="btn btn-default">Cancel</button>
            <button id="btnContinueDelete" type="button" class="btn btn-primary">Delete</button>
        </div>
    </div>
</div>

And the javascript part

<script>
    var path_to_delete;

    $(".deleteItem").click(function(e) {
        path_to_delete = $(this).data('path');
    });

    $('#btnContinueDelete').click(function () {
        window.location = path_to_delete;
    });
</script>

Here it is controller action

// GET: MyController/Delete
[HttpGet]
public ActionResult Delete(int id)
{
    var model = Context.my_models.Where(x => x.id == id).FirstOrDefault();
    if (model != null)
    {
        Context.my_models.DeleteOnSubmit(model);
        Context.SubmitChanges();

        return RedirectToAction("List");
    }

    return new HttpNotFoundResult();
}
Hag answered 19/2, 2016 at 15:39 Comment(2)
The modal works fine, but one problem I see with the solution is it is using http Get to delete an item which is potentially dangerous. http Get only used for getting data without any side effects.Changing the controller action method to be http Post will fix the problem.Berkelium
here you go pal :)Hag
C
2

I have a different take on doing this. Not that the previous ones were bad, but I think this approach is better, and very easy.

<script>
    var path_to_delete;
    var root = location.protocol + "//" + location.host;

    $("#deleteItem").click(function (e) {
        path_to_delete = $(this).data('path');
        $('#myform').attr('action', root + path_to_delete);
    });
</script>
<table class="table table-hover" id="list">
    <thead class="bg-dark text-white">
        <tr>

            <th>
                Edit
            </th>
            <th>
                Employee
            </th>
            <th>
                Effective Date
            </th>
            <th>
                ST/OT/DT
            </th>
            <th>
                Other Pay
            </th>
            <th>
                Job
            </th>
            <th>
                Pending?
            </th>
            <th>
                Delete
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    <a class="btn btn-sm" href="~/Employees/TerminationEdit/@item.Employee_Termination_Info_Id">
                        <i class="fa fa-lg fa-pencil-alt text-dark"></i>
                    </a>
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Employee_Name_Number)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Effective_Date)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Employee_Time)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Employee_Other_Pay)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Job_Name)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Pending)
                </td>
                <td>
                    <a id="deleteItem" class="btn btn-sm" data-toggle="modal" data-target="#deleteModal"
                       data-path="/Employees/TerminationDelete/@item.Employee_Termination_Info_Id">
                        <i class="fa fa-lg fa-trash-alt text-danger"></i>
                    </a>
                </td>
            </tr>
        }
    </tbody>
</table>


<!-- Logout Modal-->
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">Are you sure?</h5>
                <button class="close" type="button" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">×</span>
                </button>
            </div>
            <div class="modal-body">Are you sure you want to delete this termination record? <br /><span class="text-danger">This cannot be undone.</span></div>
            <div class="modal-footer">
                <button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
                @using (Html.BeginForm("TerminationDelete", "Employees", FormMethod.Post, new { id = "myform", @class = "" }))
                {
                    @Html.AntiForgeryToken()
           
                    <input type="submit" value="Delete" id="submitButton" class="btn btn-danger" />
                }
            </div>
        </div>
    </div>
</div>

So what happens here, is that the page will cycle through the model and draw the delete button (using font awesome). Note that here is is setting the data-path attribute for later use. When the button is clicked, it sets the form action for the button on the modal popup immediately. This is important, since it has a form around the delete button, it will send it to a POST and not a GET, as Rasika and Vasil Valchev pointed out. Plus, it has the benefit of the anti-forgery token.

Canberra answered 14/3, 2019 at 16:31 Comment(1)
I didn't go through the code but this seems to be a high quality first post. Welcome to SO!Majunga
B
0

The problem is in this line:

$.post(@Url.Action("Deletebook", "book"), { id: id }, function(data) {
    alert("data deleted");
});

The @Url.Action() bit compiles into this:

$.post(/book/Deletebook, { id: id }, function(data) {
    alert("data deleted");
});

You need to have @Url.Action enclosed in single quotation marks, or else the browser does not know how to interpret the /book/Deletebook argument.

Bligh answered 10/6, 2015 at 15:58 Comment(1)
problem is in the id param which is nullHag

© 2022 - 2025 — McMap. All rights reserved.