In this article, I have explained how can show Bootstrap confirmation pop-up modal before deleting and item from list in ASP.NET MVC.

So here is the step by step procedure :

So here is the step by step procedure for uploading  files using Web Api :

1 .Create a new project in your Visual Studio(File-> New->Project->From web(Left pane)-> Select "Asp.Net Web Application"(right pane)) .  

    a) Enter a Name, Click "Ok"

   b) Select "MVC" template from project and click "Ok"

2. Before we begin you can use the below scripts to generate sample database and table which we will be using in this example.

USE [master]
GO
/****** Object:  Database [EmployeeDetails]    Script Date: 26/09/2019 14:17:29 ******/
CREATE DATABASE [EmployeeDetails]
 CONTAINMENT = NONE
 ON  PRIMARY 
( NAME = N'EmployeeDetails', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.SQLEXPRESS\MSSQL\DATA\EmployeeDetails.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB )
 LOG ON 
( NAME = N'EmployeeDetails_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.SQLEXPRESS\MSSQL\DATA\EmployeeDetails_log.ldf' , SIZE = 8192KB , MAXSIZE = 2048GB , FILEGROWTH = 65536KB )
GO
ALTER DATABASE [EmployeeDetails] SET COMPATIBILITY_LEVEL = 130
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [EmployeeDetails].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [EmployeeDetails] SET ANSI_NULL_DEFAULT OFF 
GO
ALTER DATABASE [EmployeeDetails] SET ANSI_NULLS OFF 
GO
ALTER DATABASE [EmployeeDetails] SET ANSI_PADDING OFF 
GO
ALTER DATABASE [EmployeeDetails] SET ANSI_WARNINGS OFF 
GO
ALTER DATABASE [EmployeeDetails] SET ARITHABORT OFF 
GO
ALTER DATABASE [EmployeeDetails] SET AUTO_CLOSE OFF 
GO
ALTER DATABASE [EmployeeDetails] SET AUTO_SHRINK OFF 
GO
ALTER DATABASE [EmployeeDetails] SET AUTO_UPDATE_STATISTICS ON 
GO
ALTER DATABASE [EmployeeDetails] SET CURSOR_CLOSE_ON_COMMIT OFF 
GO
ALTER DATABASE [EmployeeDetails] SET CURSOR_DEFAULT  GLOBAL 
GO
ALTER DATABASE [EmployeeDetails] SET CONCAT_NULL_YIELDS_NULL OFF 
GO
ALTER DATABASE [EmployeeDetails] SET NUMERIC_ROUNDABORT OFF 
GO
ALTER DATABASE [EmployeeDetails] SET QUOTED_IDENTIFIER OFF 
GO
ALTER DATABASE [EmployeeDetails] SET RECURSIVE_TRIGGERS OFF 
GO
ALTER DATABASE [EmployeeDetails] SET  DISABLE_BROKER 
GO
ALTER DATABASE [EmployeeDetails] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 
GO
ALTER DATABASE [EmployeeDetails] SET DATE_CORRELATION_OPTIMIZATION OFF 
GO
ALTER DATABASE [EmployeeDetails] SET TRUSTWORTHY OFF 
GO
ALTER DATABASE [EmployeeDetails] SET ALLOW_SNAPSHOT_ISOLATION OFF 
GO
ALTER DATABASE [EmployeeDetails] SET PARAMETERIZATION SIMPLE 
GO
ALTER DATABASE [EmployeeDetails] SET READ_COMMITTED_SNAPSHOT OFF 
GO
ALTER DATABASE [EmployeeDetails] SET HONOR_BROKER_PRIORITY OFF 
GO
ALTER DATABASE [EmployeeDetails] SET RECOVERY SIMPLE 
GO
ALTER DATABASE [EmployeeDetails] SET  MULTI_USER 
GO
ALTER DATABASE [EmployeeDetails] SET PAGE_VERIFY CHECKSUM  
GO
ALTER DATABASE [EmployeeDetails] SET DB_CHAINING OFF 
GO
ALTER DATABASE [EmployeeDetails] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) 
GO
ALTER DATABASE [EmployeeDetails] SET TARGET_RECOVERY_TIME = 60 SECONDS 
GO
ALTER DATABASE [EmployeeDetails] SET DELAYED_DURABILITY = DISABLED 
GO
ALTER DATABASE [EmployeeDetails] SET QUERY_STORE = OFF
GO
USE [EmployeeDetails]
GO
ALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = OFF;
GO
ALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 0;
GO
ALTER DATABASE SCOPED CONFIGURATION SET PARAMETER_SNIFFING = ON;
GO
ALTER DATABASE SCOPED CONFIGURATION SET QUERY_OPTIMIZER_HOTFIXES = OFF;
GO
USE [EmployeeDetails]
GO
/****** Object:  Table [dbo].[EmpDetails]    Script Date: 26/09/2019 14:17:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[EmpDetails](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[EmpName] [varchar](500) NULL,
	[EmpAge] [int] NULL,
	[EmpSalary] [int] NULL,
	[DeptName] [varchar](500) NULL,
	[IsDeleted] [bit] NULL,
 CONSTRAINT [PK_EmpDetails] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[EmpDetails] ON 

INSERT [dbo].[EmpDetails] ([Id], [EmpName], [EmpAge], [EmpSalary], [DeptName], [IsDeleted]) VALUES (1, N'Roshan', 25, 25000, N'Main', NULL)
INSERT [dbo].[EmpDetails] ([Id], [EmpName], [EmpAge], [EmpSalary], [DeptName], [IsDeleted]) VALUES (2, N'Praveen', 26, 25000, N'Main', NULL)
INSERT [dbo].[EmpDetails] ([Id], [EmpName], [EmpAge], [EmpSalary], [DeptName], [IsDeleted]) VALUES (3, N'Manish', 25, 25000, N'HR', 1)
SET IDENTITY_INSERT [dbo].[EmpDetails] OFF
USE [master]
GO
ALTER DATABASE [EmployeeDetails] SET  READ_WRITE 
GO

Sample database table looks like this with data.

table-emp-sample-min.png

3.  Now, as you can see we have some pre-generated template files, so we will be connecting our project with database using ADO.NET entity mode, I hope you have knowledge about this, if not, you can read this article "MVC tutorial part-2 connecting to database, fetching/inserting data" to know more about connecting project with database using Entity Framework and ADO.NET

Once we are connected, we will be using .edmx model to fetch data from database and delete data, so go to your HomeController.cs and in the Index ActionMethod use the code to fetch the list

 public ActionResult Index()
        {
            List<EmpDetail> list = new List<EmpDetail>();
            using (var context = new EmployeeDetailsEntities())
            {
                list = context.EmpDetails.Where(a => a.IsDeleted != true).ToList();
            }
             return View(list);
        }

Now, we need to create code to make IsDeleted Column to set to true when user confirms to delete any entry from the Emplyee lists.


        public JsonResult deleteEmployeeDetails(int Id)
        {

            using (var context = new EmployeeDetailsEntities())
            {
                var empDetail = context.EmpDetails.Where(a => a.Id == Id).FirstOrDefault();
                empDetail.IsDeleted = true;
                context.SaveChanges();
            }
            return Json(new { status = "Success" });

        }

So the complete code of your HomeController.cs would look like this

using DeleteOperationUsingBootstrap.Models;
using System.Collections.Generic;
using System.Data;
using System.Linq;

using System.Web.Mvc;

namespace DeleteOperationUsingBootstrap.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            List<EmpDetail> list = new List<EmpDetail>();
            using (var context = new EmployeeDetailsEntities())
            {
                list = context.EmpDetails.Where(a => a.IsDeleted != true).ToList();
            }
             return View(list);
        }

       

        public JsonResult deleteEmployeeDetails(int Id)
        {

            using (var context = new EmployeeDetailsEntities())
            {
                var empDetail = context.EmpDetails.Where(a => a.Id == Id).FirstOrDefault();
                empDetail.IsDeleted = true;
                context.SaveChanges();
            }
            return Json(new { status = "Success" });

        }
    }
}

This deleteEmployeeDetails returns status in Json Format.

4. Go to your Index.cshtml and use the below code to Show Employee Table and javascript code to show bootsrap confirmation pop-up modal

@model IEnumerable<DeleteOperationUsingBootstrap.Models.EmpDetail>
@{
    ViewBag.Title = "Index";
    
}



    <table class="table table-responsive">

        <tr>
            <th width="20%">Employee Id </th>
            <th width="20%">Employee Name</th>
            <th width="20%">Employee Age</th>
            <th width="20%">Employee Salary</th>
            <th width="20%">Department Name</th>
            <th width="20%">Action</th>
        </tr>
        <tbody>

            

                @foreach (var item in Model)
                {
                    <tr id="row_@item.Id">
                        <td width="20%">@item.Id</td>
                        <td width="20%">@item.EmpName</td>
                        <td width="20%">@item.EmpAge</td>
                        <td width="20%">@item.EmpSalary</td>
                        <td width="20%">@item.DeptName</td>
                        <td width="20%"><a href="#" class="btn btn-danger" onclick="ConfirmDelete(@item.Id)"><i class="glyphicon glyphicon-trash"></i> </a> </td>
                    </tr>
                }
            
        </tbody>
    </table>

    <div class="modal fade" id="myModal">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <a href="#" class="close" data-dismiss="modal">&times;</a>
                    <h3 class="modal-title">Delete Employee</h3>
                </div>
                <div class="modal-body">
                    <h4>Are you sure you want to Remove this Employee?</h4>

                  

                </div>
                <div class="modal-footer">
                    <a href="#" class="btn btn-default" data-dismiss="modal">Cancel</a>
                    <a href="#" class="btn btn-success" onclick="DeleteEmployee()">Confirm</a>
                </div>

            </div>

        </div>

    </div>


    @*hidden field for storing current employeeId*@
    <input type="hidden" id="hiddenEmployeeId" />


@section scripts{
<script>
   


        var ConfirmDelete = function (EmployeeId) {

            $("#hiddenEmployeeId").val(EmployeeId);
            $("#myModal").modal('show');

        }

        var DeleteEmployee = function () {

          

            var empId = $("#hiddenEmployeeId").val();

            $.ajax({

                type: "POST",
                url: "/Home/deleteEmployeeDetails",
                data: { Id: empId },
                success: function (result) {
                   
                    $("#myModal").modal("hide");
                    $("#row_" + empId).remove();

                }

            })

        }

  
    
</script>

}

Here, from the “Model“, data is displayed to user using  “for loop”  .

When we click “Delete Button”  we   pass   “EmployeeId” and save it to “Hidden Field”

As : <input type="hidden" id="hiddenEmployeeId" />.

Then , one “popup modal”  gets opened asking confirmation “ Confirm/Cancel”.

 If  “Confirm is selected delete method is called using ajax post call. After deleting the record

The selected row is deleted from the table.”

Once you build and run the project in the browser, you will see output as below:

confirm-delete-using-bootstrap-pop-up-modal-asp-net-mvc-min.png

Clicking Delete buttons shows confirmation pop-up as shown below

confirm-delete-using-bootstrap-pop-up-modal-asp-net-mvc-image-2-min.png

Here is the demo gif image:

pop-up-delete-confirmation-bootstrap-mvc.gif

That's it we are done, you can download the sample source code.

You may also like to read:

Validate Pop Up Modal using Ajax.Beginform in C# MVC

Export HTML to PDF in asp.net MVC using iTextSharp or Rotativa (Step by step explanation)