MVCGrid.Net

A grid for ASP.NET MVC and Bootstrap with ajax paging and sorting. Also has filtering support, export to csv, back button support, and graceful degradation.

The primary goal of this project is to provide the core grid functionality, along with a very simple and easy-to-use client-side API to allow you to easily add the additional front-end interaction you need. You can add it to your project very easily and get it running with minimal effort, but it also has the extensibility to customize when needed.

You configure your grids on app start, and provide a function callback to actually query your data. The library will handle the ajax requests. It will parse and validate the requested options and then pass the QueryOptions to your function to retrieve the data.

Features

Example

Id First Name Last Name Start Date Status Gender
1000PatriciaJacobs10/19/2013ActiveFemale
999JeffreyShaw9/25/2012ActiveMale
998DorothyNguyen11/21/2014InactiveFemale
997KathrynCruz7/29/2014InactiveFemale
996EvelynJacobs10/16/2012InactiveFemale
995MichaelWilson2/9/2013InactiveMale
994NancyCollins3/31/2013InactiveFemale
993JoyceCrawford10/24/2013ActiveFemale
992MartinFrazier6/29/2014InactiveMale
991LoisSnyder4/13/2013InactiveFemale
Showing 1 to 10 of 1000 entries

Here is the view markup for the above grid:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class="panel panel-default">
    <div class="panel-body">
             
        @Html.Partial("_MVCGridToolbar", new MVCGridToolbarModel()
        {
            MVCGridName = "TestGrid",
            PageSize = true,
            ColumnVisibility = true,
            Export = true,
            GlobalSearch = true
        })
        @Html.MVCGrid("TestGrid")
    </div>
</div>

Below is the only code needed to query the data and display the grid:

Inside MVCGridConfig.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
MVCGridDefinitionTable.Add("TestGrid", new MVCGridBuilder<Person>(colDefauls)
    .WithAuthorizationType(AuthorizationType.AllowAnonymous)
    .WithSorting(sorting: true, defaultSortColumn: "Id", defaultSortDirection: SortDirection.Dsc)
    .WithPaging(paging: true, itemsPerPage: 10, allowChangePageSize: true, maxItemsPerPage: 100)
    .WithAdditionalQueryOptionNames("search")
    .AddColumns(cols =>
    {
        cols.Add("Id").WithValueExpression((p, c) => c.UrlHelper.Action("detail", "demo", new { id = p.Id }))
            .WithValueTemplate("<a href='{Value}'>{Model.Id}</a>", false)
            .WithPlainTextValueExpression(p => p.Id.ToString());
        cols.Add("FirstName").WithHeaderText("First Name")
            .WithVisibility(true, true)
            .WithValueExpression(p => p.FirstName);
        cols.Add("LastName").WithHeaderText("Last Name")
            .WithVisibility(true, true)
            .WithValueExpression(p => p.LastName);
        cols.Add("FullName").WithHeaderText("Full Name")
            .WithValueTemplate("{Model.FirstName} {Model.LastName}")
            .WithVisibility(visible: false, allowChangeVisibility: true)
            .WithSorting(false);
        cols.Add("StartDate").WithHeaderText("Start Date")
            .WithVisibility(visible: true, allowChangeVisibility: true)
            .WithValueExpression(p => p.StartDate.HasValue ? p.StartDate.Value.ToShortDateString() : "");
        cols.Add("Status")
            .WithSortColumnData("Active")
            .WithVisibility(visible: true, allowChangeVisibility: true)
            .WithHeaderText("Status")
            .WithValueExpression(p => p.Active ? "Active" : "Inactive")
            .WithCellCssClassExpression(p => p.Active ? "success" : "danger");
        cols.Add("Gender").WithValueExpression((p, c) => p.Gender)
            .WithAllowChangeVisibility(true);
        cols.Add("Email")
            .WithVisibility(visible: false, allowChangeVisibility: true)
            .WithValueExpression(p => p.Email);
        cols.Add("Url").WithVisibility(false)
            .WithValueExpression((p, c) => c.UrlHelper.Action("detail", "demo", new { id = p.Id }));
    })
    //.WithAdditionalSetting(MVCGrid.Rendering.BootstrapRenderingEngine.SettingNameTableClass, "notreal") // Example of changing table css class
    .WithRetrieveDataMethod((context) =>
    {
        var options = context.QueryOptions;
        int totalRecords;
        var repo = DependencyResolver.Current.GetService<IPersonRepository>();
        string globalSearch = options.GetAdditionalQueryOptionString("search");
        string sortColumn = options.GetSortColumnData<string>();
        var items = repo.GetData(out totalRecords, globalSearch, options.GetLimitOffset(), options.GetLimitRowcount(),
            sortColumn, options.SortDirection == SortDirection.Dsc);
        return new QueryResult<Person>()
        {
            Items = items,
            TotalRecords = totalRecords
        };
    })
);