Griddly

MVC/AJAX hybrid grid

Created by and

Griddly is an extremely configurable MVC/AJAX grid that separates render and data logic. Data is returned from an action method, settings are done in the view.

First render is done server side during the containing page render. Subsequent paging/filtering requests are done via AJAX to the same MVC action method using a hybrid approach.

First, install NuGet, then get Griddly from NuGet:

PM> Install-Package Griddly

Getting started

  1. Install the Griddly NuGet. This will set up the Javascript, CSS, and views.
  2. Add references to griddly.css and griddly.js in your _Layout.

You can also manually install by adding all the dependencies in the correct places. Until we get a manual install guide written, the best way is to look at this example project.

Hello World

This will use a simplified version of your standard order/person schema, with random data populated using FFaker.Net.

Domain

            public class SimplePerson
            {
                public int Id { get; set; }
                public string FirstName { get; set; }
                public string LastName { get; set; }
            }

            public class SimpleOrder
            {
                public int Id { get; set; }
                public string Item { get; set; }
                public int Quantity { get; set; }
                public decimal Total { get; set; }
                public SimplePerson Person { get; set; }
            }
        

Sample Data

            static readonly IQueryable<SimpleOrder> _indexTestData = BuildIndexTestData().AsQueryable();

            static IEnumerable<SimpleOrder> BuildIndexTestData()
            {
                List<SimpleOrder> items = new List<SimpleOrder>();
                Random r = new Random();
                int count = r.Next(10000);
                for (int i = 0; i < count; i++)
                {
                    yield return new SimpleOrder()
                    {
                        Id = i,
                        Item = Lorem.GetWord(),
                        Quantity = 1 + r.Next(10),
                        Total = 1 + (decimal)(r.NextDouble() * 10000),
                        IsApproved = r.Next(10) > 3,
                        Person = new SimplePerson()
                        {
                            Id = r.Next(10000),
                            FirstName = Name.GetFirstName(),
                            LastName = Name.GetLastName(),
                        }
                    };
                }
            }
        

Grid view

Here, we'll set up the columns and filters that make up the grid. This is done by passing a GriddlySettings<T> to the Html.Griddly extension method responsible for setting up and rendering the Griddly. My convention is to call the grid view <Parent View Name>Grid, so this will be IndexGrid.cshtml.

I'll add the filters and a couple of QOL tweaks like setting column names and display formats. I'll drop in a total aggregate for good measure.

            @{
                Layout = null;    
            }
            @Html.Griddly(new GriddlySettings<SimpleOrder>()
                {
                    ClassName = "index-grid"
                }
                .Column(x => x.Item,
                    filter: x => x.FilterBox(FilterDataType.String))
                .Column(x => x.Quantity,
                    filter: x => x.FilterRange(FilterDataType.Integer))
                .Column(x => x.Total, format: "c", defaultSort: SortDirection.Descending,
                    filter: x => x.FilterRange(FilterDataType.Currency))
                .Column(x => x.Person.FirstName, "First Name",
                    filter: x => x.FilterBox(FilterDataType.String))
                .Column(x => x.Person.LastName, "Last Name",
                    filter: x => x.FilterBox(FilterDataType.String))
            )
        

Action Method

This is where the rubber meets the road. We won't do anything fancy here, just grab the data source and implement the filters we set up in the view. We'll also default to only showing approved orders. This example uses parameters on the action method for simplicity, but it could just as easily be using a model.

            public ActionResult IndexGrid(string item, int? quantityStart, int? quantityEnd, decimal? totalStart, decimal? totalEnd, string firstName, string lastName, bool? isApproved)
            {
                this.SetGriddlyDefault(ref isApproved, "isApproved", true);

                IQueryable<SimpleOrder> query = _indexTestData;

                if (!string.IsNullOrWhiteSpace(item))
                    query = query.Where(x => x.Item.ToLower().Contains(item.ToLower()));

                if (quantityStart != null && quantityEnd != null)
                    query = query.Where(x => x.Quantity >= quantityStart && x.Quantity <= quantityEnd);
                if (quantityStart != null)
                    query = query.Where(x => x.Quantity >= quantityStart);
                if (quantityEnd != null)
                    query = query.Where(x => x.Quantity <= quantityEnd);

                if (totalStart != null && totalEnd != null)
                    query = query.Where(x => x.Total >= totalStart && x.Total <= totalEnd);
                if (totalStart != null)
                    query = query.Where(x => x.Total >= totalStart);
                if (totalEnd != null)
                    query = query.Where(x => x.Total <= totalEnd);

                if (!string.IsNullOrWhiteSpace(firstName))
                    query = query.Where(x => x.Person.FirstName.ToLower().Contains(firstName.ToLower()));
                if (!string.IsNullOrWhiteSpace(lastName))
                    query = query.Where(x => x.Person.LastName.ToLower().Contains(lastName.ToLower()));

                if (isApproved != null)
                    query = query.Where(x => x.IsApproved == isApproved);

                return new GriddlyResult<SimpleOrder>(query);
            }
        

Render grid

Now that the grid is all set up, we've just got to render it in the parent view, also done using the Html.Griddly extension method, but here we pass route parameters rather than the GriddlySettings<T> we used in the grid view.

            @Html.Griddly("IndexGrid")
        

Live Demo

And here's what it looks like after that's all set up.

Item  Quantity  Total  First Name  Last Name  Approved? 
omnis 8 $10,000.56 Nicolette Harber True
delectus 3 $9,997.56 Erica Torp True
voluptas 4 $9,995.45 Catharine Gleason True
nostrum 1 $9,994.19 Ocie Conroy True
delectus 9 $9,992.03 Boyd Schulist True
et 4 $9,987.11 Jaida Mayert True
cum 5 $9,978.11 Alvena Upton True
minus 7 $9,977.01 Esther Abshire True
quisquam 5 $9,972.82 Aryanna Langworth True
commodi 8 $9,969.51 Trevor Goodwin True
est 4 $9,962.77 Clemens Macejkovic True
ut 2 $9,960.16 Audie McClure True
aut 3 $9,958.32 Liliana Koch True
voluptas 8 $9,957.34 Annalise Schowalter True
corrupti 8 $9,954.77 Donnie Torp True
earum 10 $9,954.12 Cindy Veum True
quia 10 $9,953.19 Jo Schultz True
in 5 $9,952.34 Adolphus Kirlin True
sint 1 $9,947.30 Lenora Jaskolski True
dolorum 10 $9,946.74 Wilton Smith True
Total 20657 $18,771,262.51