Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Insert, Update and Delete MVC WebGrid Data using JQuery

0.00/5 (No votes)
13 Feb 2015 1  
How to insert, update and delete MVC WebGrid data using JQuery

Introduction

If you are an ASP .NET developer, you are familiar with editing (Insert, Update and Delete) GridView’s row data using Item Template and Edit Template. You will be surprised, when you find that WebGrid of MVC does not have Edit Template and does not allow user to edit row data of WebGrid.

Using JQuery, you can allow user to edit data in WebGrid. In this topic, I will walk you through:

  • How to populate data in WebGrid
  • Using JQuery, edit data in WebGrid

Please note that I am concentrating on the functionality instead of making it nice. In this demonstration, I am going to use Student object for student information.

1.0 Create MVC 4 Web Application

Using Visual Studio 2012, create a new project with MVC 4 Web Application. Select the template either Internet or Intranet application. I have selected the Internet Application Template. Make sure Razor is selected in the View Engine.

By default, Visual Studio creates several files for Controllers, Models and Views. In this tutorial, you are going to modify the landing page of the application. In other words, you are going to use the Index.cshtml view to display Student data.

2.0 Add JQuery Scripts to Project

Open the _Layout.cshtml from the Views->Shared folder and add the following JQuery references just before the end tag (</head>) of Head.

JavaScript
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery-ui-1.8.24.min.js"></script>

3.0 Create Data Model (Student)

From the Solution Explorer, right click on the Models and select Add option from context menu. Then select Class option and name it Student. Now, the Models folder should have the Student.cs class.

Open Student.cs and add fields as shown below. You may add validation and others attribute. To concentrate only on the editing, keep it simple.

C#
namespace DrillDownDemo.Models
{
    public class Student
    {
        public int ID { get; set; }
        public String Name { get; set; }
        public String email { get; set; }    
    }
}

4.0 Add Style Sheet for WebGrid

In this demonstration, you will use different background color for WebGrid’s alternate rows and footer. To accomplish this, you are going to use the CSS file. Right click on the Content folder and select New Item from the Add context menu. Select Style Sheet from the Add New Item dialog box. Name it Student and click on Add button.

Open the Student.css file and add the following CSS statements in the Student.css file:

CSS
.oddRowStyle
{
    background-color: #00CCFF;
    color: #FFFFFF;
}
.evenRowStyle
{
    background-color: #CCCCCC;
}
.tfootrow
{
    background-color: #3366CC;
    color: #FFFFFF;
}
    .tfootrow a
    {
        color:#FFFFFF;
    }

After saving the Student.css file, add the CSS link in the _Layout.cshtml so that all pages can use the style sheet. Add the following lines inside the HEAD tag of _Layout.cshtml file.

HTML
<link href="~/Content/Student.css" rel="stylesheet" />

5.0 Modify Controller (HomeController)

For this demo application, as you are using the landing page, modify HomeController. In real life application, you may need to display the data in different view. In that case, you will need to add/modify the corresponding controller.

For simplicity, use static data, instead of using backend data storage. Add a static list of Student object in the HomeController.

C#
public static List<Models.Student> Students = new List<Models.Student>()
            {
                new Models.Student { 
                    ID = 1, 
                    Name = "Adam Worth", 
                    email = "adam.worthh@abc.edu", 
                },
                new Models.Student { 
                    ID = 2, 
                    Name = "John Doe",  
                    email = "john.doe@abc.edu", 
                },
                new Models.Student { 
                    ID = 3, 
                    Name = "Gorge Klene", 
                    email = "gorge.klene@abc.edu", 
                }
            };

To send the Students list to the Index view, modify the Index() method and return the Students in the view. The line of code is as follows:

C#
public ActionResult Index()
        {
            return View(Students);
        }

6.0 Modify the View (index.cshtml)

6.1 Display Data using WebGrid

Open Index.cshtml file from the Views->Home folder. You need to specify the Data Model for this view. At the first line of the Index.cshtml file, add the following:

C#
@model IEnumerable<ManipulateWebGridDemo.Models.Student>

This updates the Model property of the associated System.Web.Mvc.ViewDataDictionary with the list of student objects. The Model property will be used in the WebGrid constructor as a parameter.

If you like, you may add the ViewBag.Title as follows:

HTML
@{
    ViewBag.Title = "Manipulate WebGrid Data";
} 

Now, you need to add the code for WebGrid. Define a <div> with ID and refer the div’s id in the ajaxUpdateContainerId attribute of WebGrid control that will allow WebGrid to update data asynchronously using Ajax. As there are only 3 records of Student in the data and if you would like to see the behavior of the WebGrid in different page, define the rowsPerPage with value 2.

HTML
<div id="ajaxgrid">
@{
        var grid = new WebGrid(Model, ajaxUpdateContainerId: "ajaxgrid", 
                               rowsPerPage: 2);
}
</div>

Next, you need to define the columns. In the first column, define different Actions (Edit, Save, Cancel and Delete). There are two different modes for view – one to display and another to edit. Hence, you can see Edit and Delete actions have “display” in the class attribute and Save and Cancel action has “edit” in the class attribute. Those classes will be used in JQuery to determine the active mode.

To capture user’s click event of action buttons, define another class attribute (e.g., XXXXXX-btn). Please, note that those classes do not need to be in the CSS file. Those are only used in the JQuery to find controls and capture the event.

JavaScript
IEnumerable<WebGridColumn> cols = 
            new List<WebGridColumn> {
                new WebGridColumn{
                    Format = 
                       @<text>
                       <a href='#' class="display edit-btn">Edit</a>
                       <a href="#" class="edit save-btn">Save</a>
                       <a href="#" class="edit cancel-btn">Cancel</a>
                       <a href="#" class="display delete-btn">Delete</a>
                       </text>
                },
                new WebGridColumn{
                    Header="ID", 
                    Format = @<text>
                                <span class="display">
                                      <label id="lblID">@item.ID</label>
                               </span>
                                <input type="text" id="inID" value="@item.ID" 
                                      class="edit" readonly="true"/>
                            </text>
                },
                new WebGridColumn{
                    Header="First Name", 
                    Format = @<text>
                                <span class="display">
                                      <label id="lblName">@item.Name</label>
                               </span>
                                <input type="text" id="inName" 
                                      value="@item.Name" 
                                      class="edit" />
                              </text>
                },
                new WebGridColumn{
                    Header="Email", 
                    Format = @<text>
                                <span class="display">
                               <label id="lblEmail">@item.Email</label>
                               </span>
                                <input type="text" id="inEmail" 
                                      value="@item.Email" 
                                      class="edit" />
                                </text>
                }
            };

Each data column has two controls for display and edit mode. Label controls will be visible for display mode and Input controls will be visible for edit mode. Those controls need to be defined under the FORMAT attributes of WebGridColumn definition. Label control does not have class attributes, hence it is wrapped with <span> tag.

Next call the GetHtml method of WebGrid, so that Razor Engine can generate corresponding HTML for it. After the end of <div> tag, add the following statement:

JavaScript
@grid.GetHtml(columns:cols, rowStyle:"oddRowStyle", alternatingRowStyle: "evenRowStyle")

If you run the application, at this point, you can see that both Label and Input control’s data are visible in the page. Here is a sample image of it.

Image 1

In the next section, you are going to add JQuery fuctionalities to handle active mode of either display or edit.

Full Code Segment

JavaScript
@model IEnumerable<ManipulateWebGridDemo.Models.Student>
@{
    ViewBag.Title = "Manipulate WebGrid Data";
}
 
<div id="ajaxgrid">
@{
        var grid = new WebGrid(Model, ajaxUpdateContainerId: "ajaxgrid", rowsPerPage: 2);
 
        IEnumerable<WebGridColumn> cols = 
            new List<WebGridColumn> {
                new WebGridColumn{
                    Format = @<text>
                                <a href='#' class="display edit-btn">Edit</a>
                                <a href="#" class="edit save-btn">Save</a>
                                <a href="#" class="edit 
                                      cancel-btn">Cancel</a>
                                <a href="#" class="display 
                                      delete-btn">Delete</a>
                            </text>
                },
                new WebGridColumn{
                    Header="ID", 
                    Format = @<text>
                                <span class="display">
                                      <label id="lblID">@item.ID</label>
                                </span>
                                <input type="text" id="inID" value="@item.ID" 
                                            class="edit" readonly="true"/>
                            </text>
                },
                new WebGridColumn{
                    Header="First Name", 
                    Format = @<text>
                                <span class="display">
                                      <label id="lblName">@item.Name</label>
                                </span>
                                <input type="text" id="inName" 
                                      value="@item.Name" 
                                      class="edit" />
                                </text>
                },
                new WebGridColumn{
                    Header="Email", 
                    Format = @<text>
                          <span class="display">
                               <label id="lblEmail">@item.Email</label>
                           </span>
                                <input type="text" id="inEmail" 
                                      value="@item.Email" 
                                      class="edit" />
                                </text>
                }
            };
}
</div>
@grid.GetHtml(columns:cols, rowStyle:"oddRowStyle", alternatingRowStyle: "evenRowStyle")

6.2 Adding JQuery Method

You are going to use JQuery to control the Display and Edit mode. After adding all of the HTML mentioned above, add a <script> section as follows:

JavaScript
<script type="text/javascript">
    $(function () {
        
    });
</script>

There are three different actions for data manipulation – insert, update and delete. In the following sections, you will find JQuery and HomeController code for all of the three actions.

6.2.1 Insert Record

WebGrid does not have method to access footer section during the defining of it. As a result, you need to add a footer section into the HTML code generated by Razor for WebGrid using JQuery. Footer section will be used to insert records. Section for insert, should be above of the page index.

Define a variable (tfootAdd) with the row and all columns. First column contains all three action commands. Rest of the three columns define the fields of Student object. Fields of Student objects do not need to be visible at display mode. Hence, you can use <span> tags without any information and have class attribute “display”. <input> tags are used to capture user input at edit mode.

JavaScript
// Add row at footer to allow user to add new record
var tfootAdd = "<tr class='tfootrow'>" +
        "<td/>" + 
        "<td> " + 
            "<a href='#' class='display ins-btn' >Insert</a>" +
            "<a href='#' class='edit inssave-btn'>Save</a>" +
            "<a href='#' class='edit cancel-btn'>Cancel</a>" +
        "</td>" +
        "<td>" +
            "<span class='display'/>" +
            "<input type='text' id='inID' value='' class = 'edit'/> " +
        "</td>" +
        "<td>" + 
            "<span class='display'/>" + 
            "<input type='text' id='inName' value='' class = 'edit'/>" + 
        "</td>" +
        "<td>" + 
            "<span class='display'/>" + 
            "<input type='text' id='inEmail' value='' class = 'edit'/>" + 
        "</td>" +
"</tr>"

Then, find the first row of footer section (tfoot) and then add the variable (tfootAdd).

JavaScript
$("table tfoot tr:first").before(tfootAdd);

When the application starts, all rows of WebGrid should be in display mode. After that, based on user selection, it should switch between display and edit mode for each row. To accomplish this, add the following JQuery which will find all controls with ‘edit’ class attribute and hide them.

JavaScript
$('.edit').hide();  // default is display

When user clicks on Insert and/or Edit button of a row, that particular row should change to edit mode. In the edit mode, if user clicks on Cancel button, then that row should go back to display mode. Capture the click event of Insert, Edit and Cancel button by using the “ins-btn”, “edit-btn” and “cancel-btn” attributes. In the click event, find the parent row of Insert, Edit or Cancel. Then find the “edit” and “display” attribute of the row and call the toggle function of JQuery. Toggle function of JQuery will switch the display mode.

JavaScript
$('.ins-btn, .edit-btn, .cancel-btn').on("click", function () {
            var tr = $(this).parents('tr:first');
            tr.find('.edit, .display').toggle();
});

Capture the Click event of save action for Insert using JQuery and then call the method of HomeController to save the data. First, define the click method of the Save button (inssave-btn). Inside this function, grab the data for ID, Name and Email. Using the data, you need to create a Student object, which will be used to send data to the InsertData method (described in a later section) of the HomeController. InsertData method of HomeController will be called using Ajax function of JQuery. InsertData method will return 1 for success and 0 for error. Those values are going to capture in the isSuccess variable. When the process of insert is completed, Ajax function will call the done event. If InsertData method returns success, then it will show success message, go back to display mode and refresh the page. Otherwise, it will show the error message and stay in edit mode.

JavaScript
$('.inssave-btn').on("click", function () {
    var tr = $(this).parents('tr:first');
    var name = tr.find("#inName").val();
    var id = tr.find("#inID").val();
    var email = tr.find("#inEmail").val();
    var isSuccess = -1;

    var Student =
    {
        "ID": id,
        "Name": name,
        "email": email
    };

    $.ajax({

    // HomeController and InsertData method

        url: '/Home/InsertData/',

        data: JSON.stringify(Student),

        type: 'POST',

        contentType: 'application/json; charset=utf-8',

        success: function (result) {
            isSuccess = result;

        },
        error: function(result){
            isSuccess = result;
        }

    }).done(function () {
        if (isSuccess == "1") {           // Successfully saved
            tr.find('.edit, .display').toggle();
            alert("Successfully Saved");
            location.reload();      // refresh the page
        }
        else {                      // Data Error
            alert("Error. Please, check the data");
        }
    });
});

Now, modify the HomeController and add InsertData method. This is a simple method, where it checks for duplicate id. If the id is duplicate, it will return error (0) value otherwise the student object will be added to the Students list. As Ajax function is calling using POST, you need to setup method attribute of the InsertData method to HttpPost.

C#
[HttpPost]
public JsonResult InsertData(Models.Student inStudent)
{
    String result = String.Empty;

    Models.Student dup = Students.Find(p => p.ID == inStudent.ID);

    if (dup == null)
    {
        Students.Add(inStudent);
        result = "1";
    }
    else
    {
        result = "0";
    }

    return Json(result, JsonRequestBehavior.AllowGet);
}

6.2.2 Update Record

When user clicks on the Edit button, the row of data will be in edit mode and user can modify data. After editing data, when user clicks on the Save button, you need to call the SaveData method of HomeController using Ajax function. First, define the click method of the Save button (save-btn). Inside this function, grab the data for ID, Name and Email. Using the data, create a Student object, which will be used to send data to the SaveData Method (described in a later section) for the HomeController. Now call SaveData method of HomeController using the Ajax function. SaveData method will return 1 for success and 0 for error. Those values are going to capture in the isSuccess variable. When the process of update is completed, Ajax function will call the done event. If SaveData method returns success, then we need to go back to display mode and refresh the page. Otherwise, we will show the error message.

JavaScript
$('.save-btn').on("click", function () {

    var tr = $(this).parents('tr:first');
    var name = tr.find("#inName").val();
    var id = tr.find("#inID").val();
    var email = tr.find("#inEmail").val();
    var isSuccess = -1;

    tr.find("#lblName").text(name);
    tr.find("#lblEmail").text(email);

    var Student =
    {
        "ID": id,
        "Name": name,
        "email": email
    };

    $.ajax({

        url: '/Home/SaveData/',
        data: JSON.stringify(Student),
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        success: function (result) {
            isSuccess = result;
        },
        error: function (result) {
            isSuccess = result;
        }

    }).done(function () {
        if (isSuccess == "1") {           // Successfully saved
            tr.find('.edit, .display').toggle();
            alert("Successfully Saved");
        }
        else {                      // Data Error
            alert("Error. Please, check the data");
        }
    });
});

Now, modify the HomeController and add SaveData method. This is a simple method, where it finds the existing Student object using id. If the Student object does not exist, it will return error otherwise the student object will be updated. As Ajax function is calling using POST, you need to setup method attribute of the SaveData method to HttpPost.

C#
[HttpPost]
public JsonResult SaveData(Models.Student student)
{
    int index = 0;
    String result = String.Empty;

    index = Students.FindIndex(p => p.ID == student.ID);
    if (index >= 0)
    {
        Students[index] = student;
        result = "1";
    }
    else
        result = "0";

    return Json(result, JsonRequestBehavior.AllowGet);
}

6.2.3 Delete Record

When user clicks on the Delete button, the row of data will be deleted. This will call the Delete (delete-btn) method. Inside this function, grab the data for ID, Name and Email. Using the data, create a Student object, which will be used to send data to the DeleteData method (described in a later section) for the HomeController. Call DeleteData method of HomeController using the Ajax function. DeleteData method will return 1 for success and 0 for error. Those values are going to capture in the isSuccess variable. When the process of delete is completed, Ajax function will call the done event. If DeleteData method returns success, then we need to refresh the page. Otherwise, we will show the error message.

JavaScript
$('.delete-btn').on("click", function () {
 
            var tr = $(this).parents('tr:first');
            var name = tr.find("#inName").val();
            var id = tr.find("#inID").val();
            var email = tr.find("#inEmail").val();
            var isSuccess = -1;
 
            var Student =
            {
                "ID": id,
                "Name": name,
                "email": email
            };
 
            $.ajax({
 
                url: '/Home/DeleteData/',
 
                data: JSON.stringify(Student),
 
                type: 'POST',
 
                contentType: 'application/json; charset=utf-8',
 
                success: function (result) {
                    isSuccess = result;
 
                },
                error: function (result) {
                    isSuccess = result;
                }
 
            }).done(function () {
                if (isSuccess == "1") {           // Successfully Deleted
                    alert("Successfully Deleted");
                    location.reload();      // refresh the page
                }
                else {                      // Data Error
                    alert("Error. Please, check the data");
                }
 
            });

        });

Modify the HomeController and add DeleteData method. This is a simple method, where it finds the existing Student object using id. If the Student object does not exist, it will return error otherwise the student object will be deleted. As Ajax function is calling using POST, you need to setup method attribute of the DeleteData method to HttpPost.

C#
[HttpPost]
public JsonResult DeleteData(Models.Student student)
{
    String result = String.Empty;

    Models.Student s = Students.Find(p => p.ID == student.ID);
    if (s != null)
    {
        Students.Remove(s);
        result = "1";
    }
    else
        result = "0";

    return Json(result, JsonRequestBehavior.AllowGet);
}

7.0 Conclusion

VC and JQuery together make it very easy to implement data editing for WebGrid. The same logic you may use to edit data in table instead of WebGrid. However, if you use table, then you need to maintain the page index from your code.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here