Part 1 - Basic Inplace editing in asp.net MVC webgrid



Introduction

Previously we have seen many articles about webgrid in asp.net MVC application, like...

  1. How to display database data in webgrid in asp.net MVC application
  2. How to Dynamically set row background color in a webgrid depending on the content.
  3. Implementing custom paging, sorting and filtering in ASP.Net MVC webgrid
  4. Implementing Basic CRUD operation in webgrid

    and more....


Today in this article I am going to show you, how to implement basic In-place editing in asp.net MVC webgrid.

Most of the developers familiar with the term Inline editing in webgrid but What is in-place editing?

In-place edit allows the user to edit text directly on the page without requiring going to a separate page or open a modal popup. It makes the interaction more direct and intuitive as the user can edit the text in the same place where it is shown.
So what we will do here in this tutorial, We will create an asp.net MVC application where  First of all we will show a list of data in a webgrid and then we will make each cell of the webgrid editable when user will click on the cell. So a user can edit the cell value and submit to the server for updates on the database. Ok.

Let's start implementing basic In-place editing in asp.net MVC webgrid. 

Here In this article, I have used Visual Studio 2017

Step - 1: Create New Project.

Go to File > New > Project > ASP.NET  Web Application (under web) > Enter enter application name > select your project location > and then click on add button > It will brings up a new dialog window for select template > here I will select Empty template > checked  MVC checkbox from Add folder and core referances for: > and then click on ok button.

Step-2: Add a Database.

Now I will create a database for our application. As this is a tutorial project, I will add a database in our applications here in the app_data folder.

Go to Solution Explorer > Right Click on App_Data folder > Add > New item > Select SQL Server Database Under Data > Enter Database name > Add.

Step-3: Create a table in our database.

Now in this step, we will create two database tables here in our database so we can do crud operation on this database table.

Table: SiteUsers


Table: UserRoles

double click on the database under app_data folder  for open the database in server explorer > expand the database and Right click on Tables node > click on Add New Table >  here we will write schema of the table for the table we want to create > now click on Update button for create the table and then again click on Update Database button.

I have added some data also on these tables So we can show in a webgrid and make each cell of the webgrid editable.

Step-4: Add Entity Data Model.

Now we will add an entity data model in our application.

Go to Solution Explorer > Right Click on the Models folder form Solution Explorer > Add > New item > Select ADO.net Entity Data Model under data > Enter model name > Add.
A popup window will come (Entity Data Model Wizard) > Select Generate from database > Next >
Chose your data connection > select your database > next > Select tables > enter Model Namespace > Finish.

Step-5: Add a view model in our application.

Now I will Add a view model in our application.

ViewModel is nothing but a class we will use here for send data from controller to view. and for this, I will add a folder here first in our application.

Right click on your project name from solution explorer > Add > New Folder... > Rename the folder as "ViewModel".

And then let's add a class file here in this ViewModel folder.

Right-click on the ViewModel Folder > Add > Class > Enter Class name "SiteUserModel.cs" > Click on add button.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace InlineEditingWebgrid.ViewModel
{
    public class SiteUserModel
    {
        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime DOB { get; set; }
        public int RoleID { get; set; }
        public string RoleName { get; set; }

    }
}

Step-6: Create a Controller.

Now we will add an MVC controller.

Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name (here I have renamed as "HomeController") > Select Templete "empty MVC Controller"> Add. 

Step-7: Update Index MVC action of the HomeController.

You can see here in this HomeController a default MVC Action "Index" is already added. So we will update the Index action code for fetch data from the database and return as Model with the View. So we can show SiteUsers data in a webgrid on the page. 

public ActionResult Index()
{
    List<SiteUserModel> list = new List<SiteUserModel>();
    using (MyDatabaseEntities dc = new MyDatabaseEntities())
    {
        var v = (from a in dc.SiteUsers
                    join b in dc.UserRoles on a.RoleID equals b.ID
                    select new SiteUserModel
                    {
                        ID = a.ID,
                        FirstName = a.FirstName,
                        LastName = a.LastName,
                        DOB =a.DOB,
                        RoleID = a.RoleID,
                        RoleName =b.RoleName
                    });
        list = v.ToList();
    }
    return View(list);
}

Step-8: Add view for the Index action of the HomeController.

Right Click on Action Method (here right click on Index action) > Add View... > Enter View Name > Select "Empty" under Template dropdown > Select SiteUserModel model from Model class dropdown > > Add.

    HTML Code

    @model List<InlineEditingWebgrid.ViewModel.SiteUserModel>
    @{
        ViewBag.Title = "Index";
        WebGrid grid = new WebGrid(Model, rowsPerPage:10);
    }
    <h2>Inplace editing in webgrid</h2>
    <hr />
    <div class="row">
        @grid.GetHtml(
            tableStyle:"table table-responsive table-striped table-bordered",
            columns: grid.Columns(
                grid.Column(header:"First Name", format:@<text><div class="edit" data-id="@item.ID" data-propertyname="FirstName">@item.FirstName</div></text>),
                grid.Column(header: "Last Name", format:@<text><div class="edit" data-id="@item.ID" data-propertyname="LastName">@item.LastName</div></text>),
                grid.Column(header: "Role", format:@<text><div class="editSelect" data-id="@item.ID" data-propertyname="RoleID">@item.RoleName</div></text>),
                grid.Column(header: "DOB", format:@<text><div class="editDate" data-id="@item.ID" data-propertyname="DOB">@string.Format("{0:dd-MMM-yyyy}", item.DOB )</div></text>)
            )
        )
    </div>
    <style>
        .table td{width:25%;}
    </style>
    @section scripts{
        <script src="https://www.appelsiini.net/download/jquery.jeditable.js"></script>     
        <script>
            $(document).ready(function () {
                var oldValue = '';
                $('.edit').editable('/home/saveuser', {
                    cssclass: 'jeditForm',
                    tooltip: 'click to edit me...',
                    width: 'none',
                    height: 'none',
                    onsubmit: function (settings, original) {
                        oldValue = original.revert;
                    },
                    submitdata: function () {
                        return {
                            id: $(this).data('id'),
                            PropertyName: $(this).data('propertyname')
                        }
                    },
                    callback: function (value, settings) {
                        var jsonData = $.parseJSON(value);
                        if (jsonData.status) {
                            $(this).text(jsonData.value);
                        }
                        else {
                            $(this).text(oldValue);
                        }
                    }
                })
            })
        </script>
    }

    You can see in line 9-17, We have used Webgrid for showing data on the page. In line 23, I have added the jQuery jeditable plugin for make each cell of the webgrid editable. In line 27-51, I have called the editable method of the jQuery jeditable plugin, This will make each cell of the webgrid editable where we have defined edit CSS class (as we have used the edit CSS class as a selector) when a user will click on the cell.

    In the editable method, we have to pass a URL where browser posts edited content and this is a mandatory parameter.We can pass a configuration parameter also for configuring the in-place editor. here in the configuration parameter, we have used followings...

    cssclass: This class will be added to the in-place editable form. We can use this class for making the form looks perfect as per our application looks and feel.
    tooltip:  Tooltips are great for informing users what they should do.
    width: I have defined none in the width for prevent to calculate the width of the in-place edit form.
    heigh: I have defined none in the heigh for prevent to calculate the height of the in-place edit form.
    onsubmit: This function is called before submitting the form. Here I have this function for storing the old value in a variable.
    submitdata: This is also a very useful function.It allows us to pass extra parameters when submitting content to the server.
    callback: This function is called after form has been submitted. This is the best place to capture the server response. But keep in mind that it's only except string value from server So we must have to pass string value from the server. This is the reason we will pass JSON string from the server as the response for send back multiple parameters and here in this function we have converted back the string value to JSON object.

    Step-9: Update _Layout.cshtml.

    We have to update our _Layout.cshtml page. I will add a RenderSection for render js from view page after the jQuery library.

    Here is the complete _Layout.cshtml page
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>@ViewBag.Title - My ASP.NET Application</title>
        <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
        <link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
        <script src="~/Scripts/modernizr-2.6.2.js"></script>
    </head>
    <body>
        <div class="navbar navbar-inverse navbar-fixed-top">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                    </ul>
                </div>
            </div>
        </div>
    
        <div class="container body-content">
            @RenderBody()
            <hr />
            <footer>
                <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
            </footer>
        </div>
    
        <script src="~/Scripts/jquery-1.10.2.min.js"></script>
        <script src="~/Scripts/bootstrap.min.js"></script>
        @RenderSection("Scripts", false)
    </body>
    </html>

    Step-10: Add a new MVC Action for Submit updated data in HomeController.

    Here we will add a new MVC Action (HttpPost Action) for submitting the updated data from the In-place editing form to the MVC action for updating on the database.  

    [HttpPost]
    public ActionResult saveuser(int id, string propertyName, string value)
    {
        var status = false;
        var message = "";
    
        //Update data to database 
        using (MyDatabaseEntities dc = new MyDatabaseEntities())
        {
            var user = dc.SiteUsers.Find(id);
            if (user != null)
            {
                dc.Entry(user).Property(propertyName).CurrentValue = value;
                dc.SaveChanges();
                status = true;
            }
            else
            {
                message = "Error!";
            }
        }
    
        var response = new { value = value, status = status, message = message };
        JObject o = JObject.FromObject(response);
        return Content(o.ToString());
    }
    As I had already written that the jeditable plugin callback function only accepts string value from the server, here in line 23-25, you can see I have generated the JSON string for sending a response. 

    Step-11: Run Application.

    We have done all the steps. Now it's time to run the application.

    Ream Next: Part 2 - Advance Inplace editing in asp.net MVC webgrid


    Hello ! My name is Sourav Mondal. I am a software developer working in Microsoft .NET technologies since 2010.

    I like to share my working experience, research and knowledge through my site.

    I love developing applications in Microsoft Technologies including Asp.Net webforms, mvc, winforms, c#.net, sql server, entity framework, Ajax, Jquery, web api, web service and more.