CRUD Operation Using Partial View In MVC With Modal Popup


In my previous article, we discussed how to perform Insert, Update, and Delete operations using jQuery AJAX and Modal Popup in MVC. In this post, we will focus on adding and editing records using partial views, jQuery, and Bootstrap modal popups in ASP.NET MVC.

 Download Source Code

So, let's begin step by step to learn. In this post, we will create a Home View where the admin can manage the teacher’s records.

We will create a table grid that will include basic operations such as adding, updating, and deleting rows using the JavaScript confirmation alert dialog.

Step-1 : Create a database named “DotNetPeTips” in your local SQL server.

I have created a table named Teacher with columns Id, Teacher_Name, Teacher_Email, Teacher_ContactNo, Teacher_Department, and Teacher_Address. You can execute the script below to create this table for practice purposes.

Table Script

CREATE TABLE [dbo].[Teacher](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Teacher_Name] [nvarchar](100) NULL,
[Teacher_Email] [nvarchar](max) NOT NULL,
[Teacher_ContactNo] [nvarchar](14) NULL,
[Teacher_Department] [nvarchar](100) NOT NULL,
[Teacher_Address] [nvarchar](100) NOT NULL,
CONSTRAINT [PK__Teacher__3214EC077B0B6A86] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

Step-2 : Add empty MVC project

Create An Mvc Project

Step-3 : Add EntityFramework in the project


namespace PartialViewCrud.Models
{
using System;
using System.Collections.Generic;
    
public partial class Teacher
    {
public int Id { get; set; }
public string Teacher_Name { get; set; }
public string Teacher_Email { get; set; }
public string Teacher_ContactNo { get; set; }
public string Teacher_Department { get; set; }
public string Teacher_Address { get; set; }
    }
}

we will use this model clas for binding our view.

Step 4. Creating Controller

Now let’s add a controller for return view, Add a controller named “Teacher”, Right-click on the Controller folder in the project, and click on add an empty controller.

Create a Controller

TeacherController.cs

using PartialViewCrud.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace PartialViewCrud.Controllers
{
public class TeacherController : Controller
    {
// GET: Teacher
private DotNetPeTipsEntities db = new DotNetPeTipsEntities();
public ActionResult Index()
        {
return View();
        }
        
protected override void Dispose(bool disposing)
        {
if (disposing)
            {
                db.Dispose();
            }
base.Dispose(disposing);
        }
    }
}

Step 5. Creating View

Now Right-click on Index ActionMethod, add empty View.

addindexview

please make sure to check “Use a Layout page” option. it will create the layout and Bootsrap files for our project.

AddIndexView-1

addindexview_2
Step 6. Now let’s add partial view for performing add and edit operations

Just Right click on Shared folder(inside views folder) and add=>view

  • checkmark “create a partial view” option ,
  • named “_AddTeacher”.

similarly add view for updating the records.

add_pertailview

If you are an asp.net web developer, you will recognize that partial views in MVC are alike to user controls in .net web forms.

Partial views are used to encapsulate re-usable view logic and are a great tool to simplify the complexity of views.

These partial views can be used on multiple views, where we require similar visual logic. If you are using the webform view engine, then partial views have an extension of .ascx.

If the visual engine is the razor and the programming language is c #, then partial views have an extension of .cshml.

On the other hand, if the programming language is Visual Basic, the extension is .vbhtml. Please note that partial views can be added to a “shared” folder or to a specific view folder.

Partial views inside the shared folder are available for all views in the project, you can say that partial views inside shared are Global Views. where partial views in a specific folder are only available for views inside that folder which means limited to the specific folder.

Step 7 : Open teacher controller and copy paste the below code

TeacherController.cs

  • Index(): This method returns a view, likely for displaying a list of teachers.
  • GetAllTeachers(): Returns a JsonResult containing a list of all teachers from the database.
  • LoadEditTeacherPopup(int TeacherId): Retrieves details of a teacher with the specified ID and returns a partial view "_UpdateTeacher" populated with the teacher's data for editing.
  • LoadaddTeacherPopup(): Returns a partial view "_AddTeacher" for adding a new teacher.
  • AddTeacher(Teacher teachers): Receives a Teacher object as a parameter, attempts to add it to the database, and returns a JsonResult indicating success or failure.
  • UpdateTeacher(Teacher teacher): Receives a Teacher object as a parameter, updates it in the database, and returns a JsonResult indicating success or failure.
  • DeleteTeacher(int TeacherId): Deletes a teacher from the database based on the provided ID and returns a JsonResult indicating success or failure.
  • Dispose(bool disposing): Overrides the Dispose method to release resources when the controller is disposed.

The controller interacts with the database (assuming DotNetPeTipsEntities is a DbContext) using Entity Framework. It implements CRUD (Create, Read, Update, Delete) operations for managing teacher records. Additionally, error handling is implemented within each method to handle exceptions that may occur during database operations.


using PartialViewCrud.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace PartialViewCrud.Controllers
{
public class TeacherController : Controller
    {
// GET: Teacher
private DotNetPeTipsEntities db = new DotNetPeTipsEntities();
public ActionResult Index()
        {
return View();
        }
public JsonResult GetAllTeachers()
        {
return Json(db.Teachers.ToList(), JsonRequestBehavior.AllowGet);
        }
public ActionResult LoadEditTeacherPopup(int TeacherId)
        {
try
            {
var model = db.Teachers.Where(a => a.Id == TeacherId).FirstOrDefault();
return PartialView("_UpdateTeacher", model);
            }
catch (Exception ex)
            {
return PartialView("_UpdateTeacher");
            }
        }

public ActionResult LoadaddTeacherPopup()
        {
try
            {
return PartialView("_AddTeacher");
            }
catch (Exception ex)
            {
return PartialView("_AddTeacher");
            }
        }

public JsonResult AddTeacher(Teacher teachers)
        {
string status = "success";
try
            {
                db.Teachers.Add(teachers);
                db.SaveChanges();
            }
catch (Exception ex)
            {
                status = ex.Message;
            }
return Json(status, JsonRequestBehavior.AllowGet);

        }
public JsonResult UpdateTeacher(Teacher teacher)
        {

string status = "success";
try
            {
                db.Entry(teacher).State = EntityState.Modified;
                db.SaveChanges();

            }
catch (Exception ex)
            {
                status = ex.Message;

            }
return Json(teacher, JsonRequestBehavior.AllowGet);
        }
public JsonResult DeleteTeacher(int TeacherId)
        {
string status = "success";
try
            {

var pateint = db.Teachers.Find(TeacherId);
                db.Teachers.Remove(pateint);
                db.SaveChanges();

            }
catch (Exception ex)
            {
                status = ex.Message;

            }
return Json(status, JsonRequestBehavior.AllowGet);
        }
protected override void Dispose(bool disposing)
        {
if (disposing)
            {
                db.Dispose();
            }
base.Dispose(disposing);
        }
    }
}

Step 8: Change RouteConfig.cs

change defaults controller name to “Teacher

routeconfig

Now Open Index.cshtml and Copy paste the below code

Index.cshtml

 


@{
    ViewBag.Title = "Index";
}

<h2>Teacher Record</h2>
@* Table for showing the list of teachers from the database *@
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal" onclick="OpenAddPopup();">Add New Teacher</button><br /><br />
<table class="table table-bordered table-hover">
    <thead>
        <tr>
            <th>
                ID
            </th>
            <th>
                Name
            </th>
            <th>
                Email
            </th>
            <th>
                Number
            </th>
            
            <th>
                Address
            </th>
            <th>
                Department
            </th>
            <th>
                Action
            </th>
        </tr>
    </thead>
    <tbody class="tbody"></tbody>
</table>
<div id="divcontent">

</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script type="text/javascript">
    $(document).ready(function () {
        BindteacherData();
    });
    function BindteacherData() {
        $.ajax({
            url: "/Teacher/GetAllTeachers",
            type: "GET",
            contentType: "application/json;charset=utf-8",
            dataType: "json",
            success: function (result) {
if (result) {
//itetrate thorugh each record and bind it to td
var html = '';
                    $.each(result, function (key, item) {
                        html += '<tr>';
                        html += '<td>' + item.Id + '</td>';
                        html += '<td>' + item.Teacher_Name + '</td>';
                        html += '<td>' + item.Teacher_Email + '</td>';
                        html += '<td>' + item.Teacher_ContactNo + '</td>';
                        html += '<td>' + item.Teacher_Address + '</td>';
                        html += '<td>' + item.Teacher_Department + '</td>';
                        html += '<td><a href="#" onclick="return OpenUpdatePopup(' + item.Id + ')">Edit</a> | <a href="#" onclick="DeleleTeacher(' + item.Id + ')">Delete</a></td>';
                        html += '</tr>';
                    });
                    $('.tbody').html(html);
                }

            },
            error: function (errormessage) {
                alert(errormessage.responseText);
            }
        });
    }
    function OpenAddPopup()
    {
        $.ajax({
            url: '/Teacher/LoadaddTeacherPopup',
            contentType: 'application/html; charset=utf-8',
            type: 'GET',
            dataType: 'html',
            success: function (result) {
                $('#divcontent').empty();
                $('#divcontent').html(result);
                $('#AddUpdateModelPopup').modal('show');
            },
            error: function (xhr, status) {
                alert(status);
            }
        })
    }

    function OpenUpdatePopup(Id) {
        $.ajax({
            url: '/Teacher/LoadEditTeacherPopup?TeacherId=' + Id,
            contentType: 'application/html; charset=utf-8',
            type: 'GET',
            dataType: 'html',
            success: function (result) {
                $('#divcontent').empty();
                $('#divcontent').html(result);
                $('#AddUpdateModelPopup').modal('show');
//$('#btndivuserguidemodel').trigger('click');
            },
            error: function (xhr, status) {
                alert(status);
            }
        })
    }


//Add Data Function
    function AddTeacher() {
var res = ValidateForm();
if (res == false) {
return false;
        }
var TeacherObj = {
            Id: $('#Id').val(),
            Teacher_Name: $('#Teacher_Name').val(),
            Teacher_Email: $('#Teacher_Email').val(),
            Teacher_ContactNo: $('#Teacher_ContactNo').val(),
            Teacher_Department: $('#Teacher_Department').val(),
            Teacher_Address: $('#Teacher_Address').val(),
        };
        $.ajax({
            url: "/Teacher/AddTeacher",
            data: JSON.stringify(TeacherObj),
            type: "POST",
            contentType: "application/json;charset=utf-8",
            dataType: "json",
            success: function (result) {
//populate table with new record
                BindteacherData();
                $('#AddUpdateModelPopup').modal('hide');
            },
            error: function (errormessage) {
                alert(errormessage.responseText);
            }
        });
    }

//function for updating Patient record
    function UpdateTeacher() {
var res = ValidateForm();
if (res == false) {
return false;
        }
var TeacherObj = {
            Id: $('#Id').val(),
            Teacher_Name: $('#Teacher_Name').val(),
            Teacher_Email: $('#Teacher_Email').val(),
            Teacher_ContactNo: $('#Teacher_ContactNo').val(),
            Teacher_Department: $('#Teacher_Department').val(),
            Teacher_Address: $('#Teacher_Address').val(),
        };
if (!TeacherObj.Id || TeacherObj.Id <= 0) {
            alert("Invalid Id!");
return false;
        }
        $.ajax({
            url: "/Teacher/UpdateTeacher",
            data: JSON.stringify(TeacherObj),
            type: "POST",
            contentType: "application/json;charset=utf-8",
            dataType: "json",
            success: function (result) {
                BindteacherData();
                $('#AddUpdateModelPopup').modal('hide');
            },
            error: function (errormessage) {
                alert(errormessage.responseText);
            }
        });
    }


//function for deleting Teacher's record
    function DeleleTeacher(ID) {
var ans = confirm("Are you sure you want to delete?");
if (ans) {
            $.ajax({
                url: "/Teacher/DeleteTeacher?TeacherId=" + ID,
                type: "POST",
                contentType: "application/json;charset=UTF-8",
                dataType: "json",
                success: function (result) {
                    BindteacherData();
                },
                error: function (errormessage) {
                    alert(errormessage.responseText);
                }
            });
        }
    }

    function ValidateForm() {
var isValid = true;
if ($('#Teacher_Name').val().trim() == "") {
            $('#Teacher_Name').css('border-color', 'Red');
            isValid = false;
        }
else {
            $('#Teacher_Name').css('border-color', 'lightgrey');
        }
if ($('#Teacher_Email').val().trim() == "") {
            $('#Teacher_Email').css('border-color', 'Red');
            isValid = false;
        }
else {
            $('#Teacher_Email').css('border-color', 'lightgrey');
        }
if ($('#Teacher_ContactNo').val().trim() == "") {
            $('#Teacher_ContactNo').css('border-color', 'Red');
            isValid = false;
        }
else {
            $('#Teacher_ContactNo').css('border-color', 'lightgrey');
        }
if ($('#Teacher_Department').val().trim() == "") {
            $('#Teacher_Department').css('border-color', 'Red');
            isValid = false;
        }
else {
            $('#Teacher_Department').css('border-color', 'lightgrey');
        }

if ($('#Teacher_Address').val().trim() == "") {
            $('#Teacher_Address').css('border-color', 'Red');
            isValid = false;
        }
else {
            $('#Teacher_Address').css('border-color', 'lightgrey');
        }
return isValid;
    }
</script>

list

_AddTeacher.cshtml

 

@model PartialViewCrud.Models.Teacher
<div class="modal fade" id="AddUpdateModelPopup" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">×</button>
                <h4 class="modal-title" id="AddUpdateModelLabel">Add Records</h4>
            </div>
            <div class="modal-body">
                @using (Html.BeginForm())
                {
                    @Html.AntiForgeryToken()

                    <div class="form-horizontal">
                        <hr />
                        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

                        @* Hidden filed for storing Id of teacher need to be updated *@

                        @Html.HiddenFor(model => model.Id)
                        <div class="form-group">
                            @Html.LabelFor(model => model.Teacher_Name, htmlAttributes: new { @class = "control-label col-md-4" })
                            <div class="col-md-8">
                                @Html.EditorFor(model => model.Teacher_Name, new { htmlAttributes = new { @class = "form-control" } })
                                @Html.ValidationMessageFor(model => model.Teacher_Name, "", new { @class = "text-danger" })
                            </div>
                        </div>

                        <div class="form-group">
                            @Html.LabelFor(model => model.Teacher_Email, htmlAttributes: new { @class = "control-label col-md-4", })
                            <div class="col-md-8">
                                @Html.EditorFor(model => model.Teacher_Email, new { htmlAttributes = new { @class = "form-control", @type = "email" } })
                                @Html.ValidationMessageFor(model => model.Teacher_Email, "", new { @class = "text-danger" })
                            </div>
                        </div>

                        <div class="form-group">
                            @Html.LabelFor(model => model.Teacher_ContactNo, htmlAttributes: new { @class = "control-label col-md-4" })
                            <div class="col-md-8">
                                @Html.EditorFor(model => model.Teacher_ContactNo, new { htmlAttributes = new { @class = "form-control" } })
                                @Html.ValidationMessageFor(model => model.Teacher_ContactNo, "", new { @class = "text-danger" })
                            </div>
                        </div>

                        <div class="form-group">
                            @Html.LabelFor(model => model.Teacher_Department, htmlAttributes: new { @class = "control-label col-md-4" })
                            <div class="col-md-8">
                                @Html.EditorFor(model => model.Teacher_Department, new { htmlAttributes = new { @class = "form-control" } })
                                @Html.ValidationMessageFor(model => model.Teacher_Department, "", new { @class = "text-danger" })
                            </div>
                        </div>

                        <div class="form-group">
                            @Html.LabelFor(model => model.Teacher_Address, htmlAttributes: new { @class = "control-label col-md-4" })
                            <div class="col-md-8">
                                @Html.EditorFor(model => model.Teacher_Address, new { htmlAttributes = new { @class = "form-control" } })
                                @Html.ValidationMessageFor(model => model.Teacher_Address, "", new { @class = "text-danger" })
                            </div>
                        </div>
                    </div>
                }
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary" id="btnUpdateteacher" onclick="return AddTeacher();">Add Teacher</button>
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>

add

_UpdateTeacher.cshtml

@model PartialViewCrud.Models.Teacher
<div class="modal fade" id="AddUpdateModelPopup" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">×</button>
                <h4 class="modal-title" id="AddUpdateModelLabel">Update Records</h4>
            </div>
            <div class="modal-body">
                @using (Html.BeginForm())
                {
                    @Html.AntiForgeryToken()

                    <div class="form-horizontal">
                        <hr />
                        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                        
                        @* Hidden filed for storing Id of teacher need to be updated *@

                        @Html.HiddenFor(model => model.Id)
                        <div class="form-group">
                            @Html.LabelFor(model => model.Teacher_Name, htmlAttributes: new { @class = "control-label col-md-4" })
                            <div class="col-md-8">
                                @Html.EditorFor(model => model.Teacher_Name, new { htmlAttributes = new { @class = "form-control" } })
                                @Html.ValidationMessageFor(model => model.Teacher_Name, "", new { @class = "text-danger" })
                            </div>
                        </div>

                        <div class="form-group">
                            @Html.LabelFor(model => model.Teacher_Email, htmlAttributes: new { @class = "control-label col-md-4", })
                            <div class="col-md-8">
                                @Html.EditorFor(model => model.Teacher_Email, new { htmlAttributes = new { @class = "form-control", @type = "email" } })
                                @Html.ValidationMessageFor(model => model.Teacher_Email, "", new { @class = "text-danger" })
                            </div>
                        </div>

                        <div class="form-group">
                            @Html.LabelFor(model => model.Teacher_ContactNo, htmlAttributes: new { @class = "control-label col-md-4" })
                            <div class="col-md-8">
                                @Html.EditorFor(model => model.Teacher_ContactNo, new { htmlAttributes = new { @class = "form-control" } })
                                @Html.ValidationMessageFor(model => model.Teacher_ContactNo, "", new { @class = "text-danger" })
                            </div>
                        </div>

                        <div class="form-group">
                            @Html.LabelFor(model => model.Teacher_Department, htmlAttributes: new { @class = "control-label col-md-4" })
                            <div class="col-md-8">
                                @Html.EditorFor(model => model.Teacher_Department, new { htmlAttributes = new { @class = "form-control" } })
                                @Html.ValidationMessageFor(model => model.Teacher_Department, "", new { @class = "text-danger" })
                            </div>
                        </div>

                        <div class="form-group">
                            @Html.LabelFor(model => model.Teacher_Address, htmlAttributes: new { @class = "control-label col-md-4" })
                            <div class="col-md-8">
                                @Html.EditorFor(model => model.Teacher_Address, new { htmlAttributes = new { @class = "form-control" } })
                                @Html.ValidationMessageFor(model => model.Teacher_Address, "", new { @class = "text-danger" })
                            </div>
                        </div>
                    </div>
                }
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary" id="btnUpdateteacher" onclick="return UpdateTeacher();">Update Teacher</button>
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>

Updtae

delete

  •  Add New Teacher Button: This button triggers a Bootstrap modal popup for adding a new teacher record. It is styled with Bootstrap classes and contains an onclick event to execute the OpenAddPopup() JavaScript function.
  • Table for Teacher Records: This table displays teacher records fetched from the database. It includes columns for ID, Name, Email, Number, Address, Department, and an additional column for actions (Edit and Delete).
  • Bootstrap Modal Popup: This modal popup provides input fields for adding or updating teacher records. It includes fields for Teacher Name, Email, Contact Number, Department, and Address. It also includes buttons for creating or updating a teacher record, as well as a button to close the modal.
  • JavaScript Functions: These functions utilize AJAX to interact with the server-side controller methods for CRUD operations:
  • BindteacherData(): Retrieves teacher data from the server and populates the table with it.
  • OpenAddPopup(): Opens the modal popup for adding a new teacher record.
  • OpenUpdatePopup(Id): Opens the modal popup for updating a teacher record with the specified ID.
  • AddTeacher(): Validates user input, sends the data to the server for adding a new teacher record, and updates the table with the new record.
  • UpdateTeacher(): Validates user input, sends the updated data to the server for updating a teacher record, and refreshes the table with the updated record.
  • DeleleTeacher(ID): Confirms deletion of a teacher record and sends a request to the server to delete it.
  • ValidateForm(): Validates user input for required fields and highlights any missing inputs.

A user interface for managing teacher records with features for adding, editing, and deleting records using AJAX requests to communicate with server-side controller methods.