ASP.NET MVC CollectionView 101

This page shows how to get started with ASP.NET MVC's CollectionView.

Server-side Operations

ComponentOne's MVC Edition CollectionView is a service that implements the ICollectionView interface to display data in data-bound controls, such as FlexGrid. The server side CollectionViewHelper is a service that enables collections to have reading, editing, filtering, grouping and sorting ability, this is similar to .Net CollectionView. CollectionView internally handles sorting, paging, filtering requests by data bound controls on the server unless it is explicitly specified to perform these operation at client-side.
This section describes how to use Create, Read, Update, Delete and BatchEdit actions for CRUD operations. It also demonstrates the DisableServerRead functionality of the ItemSource, this is used to perform actions explicitly at client side.

Getting Started

Steps for getting started with the CollectionView in MVC applications:

  1. Create a new MVC project using the C1 ASP.NET MVC application template.
  2. Add model to the project. This example uses Entity Framework with Northwind database
  3. Add controller and corresponding view to the project.
  4. Create Read and Create Actions in the controller.
  5. Add a control in the view to display data. This example uses FlexGrid.
  6. Bind the FlexGrid using its Bind property to display data.
  7. The Bind property is of type ItemSource which can take a Model or Action URL to fetch data.

This creates a FlexGrid with AJAX binding, the data for FlexGrid is internally wrapped in a CollectionView which has capability to sort, group, filter and page data. The GridReadCategory action of controller is assigned to Bind property of FlexGrid' ItemSource to populate data. This example is using Create property of FlexGrid's ItemSource to assign GridCreateCategory action of controller, this allows adding record to source database by handling Edit request of CollectionViewHelper.

@(Html.C1().FlexGrid().Id("fGRCView").AutoGenerateColumns(false).AllowAddNew(true) .AllowSorting(true).CssClass("grid") .Columns(columns => columns .Add(c => c.Binding("CategoryID")) .Add(c => c.Binding("CategoryName")) .Add(c => c.Binding("Description").Width("*"))) .Bind( ib => ib.Bind(Url.Action("GridReadCategory")) .Create(Url.Action("GridCreateCategory")) .Update(Url.Action("GridUpdateCategory"))) )
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using CollectionView101.Models; using C1.Web.Mvc.Grid; using C1.Web.Mvc; using C1.Web.Mvc.Serialization; using System.Data.Entity.Validation; using System.Data.Entity; namespace CollectionView101.Controllers { public class HomeController : Controller { private C1NWindEntities db = new C1NWindEntities(); public ActionResult GridReadCategory([C1JsonRequest] CollectionViewRequest requestData) { return this.C1Json(CollectionViewHelper.Read(requestData, db.Categories)); } public ActionResult GridCreateCategory([C1JsonRequest]CollectionViewEditRequest requestData) { var category = requestData.OperatingItems.First(); if (category.CategoryName == null) { category.CategoryName = ""; } return Create(requestData, db.Categories); } public ActionResult GridUpdateCategory([C1JsonRequest]CollectionViewEditRequest requestData) { return Update(requestData, db.Categories); } private ActionResult Update(CollectionViewEditRequest requestData, DbSet data) where T : class { return this.C1Json(CollectionViewHelper.Edit(requestData, item => { string error = string.Empty; bool success = true; try { db.Entry(item as object).State = EntityState.Modified; db.SaveChanges(); } catch (DbEntityValidationException e) { error = string.Join(",", e.EntityValidationErrors.Select(result => { return string.Join(",", result.ValidationErrors.Select(err => err.ErrorMessage)); })); success = false; } catch (Exception e) { error = e.Message; success = false; } return new CollectionViewItemResult { Error = error, Success = success && ModelState.IsValid, Data = item }; }, () => data.ToList())); } private ActionResult Create(CollectionViewEditRequest requestData, DbSet data) where T : class { return this.C1Json(CollectionViewHelper.Edit(requestData, item => { string error = string.Empty; bool success = true; try { data.Add(item); db.SaveChanges(); } catch (DbEntityValidationException e) { error = string.Join(",", e.EntityValidationErrors.Select(result => { return string.Join(",", result.ValidationErrors.Select(err => err.ErrorMessage)); })); success = false; } catch (Exception e) { error = e.Message; success = false; } return new CollectionViewItemResult { Error = error, Success = success && ModelState.IsValid, Data = item }; }, () => data.ToList())); } } }

Result (live):

CategoryID
CategoryName
Description
1
Beveragess
Soft drinks, coffees, teas, beers, and ales
2
Condiments
Sweet and savory sauces, relishes, spreads, and seasonings
3
Confections
Desserts, candies, and sweet breads
4
Dairy Products
Cheeses
5
Grains/Cereals
Breads, crackers, pasta, and cereal
7
Produce
n b
10
dgr
tgrtg
11
wrtg
tg
12
hbhjbhjb
dghkdghmfd
13
534djdfgjfgj
fjfgajajsdg
14
dfgjdfjdfjg
dfjfskfsdkdfhkdf

Update

The server side CollectionViewHelper class defines a Edit request to handle updates.

This example shows how to define update action which enables updating record in source database by handling Edit request of CollectionViewHelper. In Flexgrid, the Update action is assigned to the Update property of ItemSource.

@(Html.C1().FlexGrid ().Id("fGUCView").AutoGenerateColumns(false) .Columns(columns => columns .Add(c => c.Binding("CategoryID").IsReadOnly(true)) .Add(c => c.Binding("CategoryName")) .Add(c => c.Binding("Description").Width("*"))) .Bind(ib => ib.Bind(Model.Categories) .Update(Url.Action("GridUpdateCategory")) ) )
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using CollectionView101.Models; using C1.Web.Mvc.Grid; using C1.Web.Mvc; using C1.Web.Mvc.Serialization; using System.Data.Entity.Validation; using System.Data.Entity; namespace CollectionView101.Controllers { public class HomeController : Controller { private C1NWindEntities db = new C1NWindEntities(); public ActionResult GridUpdateCategory([C1JsonRequest]CollectionViewEditRequest requestData) { return Update(requestData, db.Categories); } private ActionResult Update (CollectionViewEditRequest requestData, DbSet data) where T : class { return this.C1Json(CollectionViewHelper.Edit (requestData, item => { string error = string.Empty; bool success = true; try { db.Entry(item as object).State = EntityState.Modified; db.SaveChanges(); } catch (DbEntityValidationException e) { error = string.Join(",", e.EntityValidationErrors.Select(result => { return string.Join(",", result.ValidationErrors.Select(err => err.ErrorMessage)); })); success = false; } catch (Exception e) { error = e.Message; success = false; } return new CollectionViewItemResult { Error = error, Success = success && ModelState.IsValid, Data = item }; }, () => data.ToList ())); } // GET: Home public ActionResult Index() { return View(db); } } }
HResult -2146232828 int

Result (live):

CategoryID
CategoryName
Description
1
Beveragess
Soft drinks, coffees, teas, beers, and ales
2
Condiments
Sweet and savory sauces, relishes, spreads, and seasonings
3
Confections
Desserts, candies, and sweet breads
4
Dairy Products
Cheeses
5
Grains/Cereals
Breads, crackers, pasta, and cereal
7
Produce
n b
10
dgr
tgrtg
11
wrtg
tg
12
hbhjbhjb
dghkdghmfd
13
534djdfgjfgj
fjfgajajsdg
14
dfgjdfjdfjg
dfjfskfsdkdfhkdf

Delete

This example shows how to define action in controller to delete rows from database by handling Edit request of CollectionViewHelper. In FlexGrid this action is assigned to the Delete property of ItemSource.

@(Html.C1().FlexGrid().Id("fGDelCView").AutoGenerateColumns(false).IsReadOnly(true) .Columns(columns => columns .Add(c => c.Binding("CategoryID")) .Add(c => c.Binding("CategoryName")) .Add(c => c.Binding("Description").Width("*"))) .AllowDelete(true) .Bind( ib => ib.Bind(Model.Categories) .Delete(Url.Action("GridDeleteCategory")) ) )
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using CollectionView101.Models; using C1.Web.Mvc.Grid; using C1.Web.Mvc; using C1.Web.Mvc.Serialization; using System.Data.Entity.Validation; using System.Data.Entity; namespace CollectionView101.Controllers { public class HomeController : Controller { private C1NWindEntities db = new C1NWindEntities(); public ActionResult GridDeleteCategory([C1JsonRequest]CollectionViewEditRequest requestData) { return Delete(requestData, db.Categories, item => item.CategoryID); } private ActionResult Delete(CollectionViewEditRequest requestData, DbSet data, Func getKey) where T : class { return this.C1Json(CollectionViewHelper.Edit(requestData, item => { string error = string.Empty; bool success = true; try { var resultItem = data.Find(getKey(item)); data.Remove(resultItem); db.SaveChanges(); } catch (DbEntityValidationException e) { error = string.Join(",", e.EntityValidationErrors.Select(result => { return string.Join(",", result.ValidationErrors.Select(err => err.ErrorMessage)); })); success = false; } catch (Exception e) { error = e.Message; success = false; } return new CollectionViewItemResult { Error = error, Success = success && ModelState.IsValid, Data = item }; }, () => data.ToList())); } // GET: Home public ActionResult Index() { return View(db); } } }

Result (live):

CategoryID
CategoryName
Description
1
Beveragess
Soft drinks, coffees, teas, beers, and ales
2
Condiments
Sweet and savory sauces, relishes, spreads, and seasonings
3
Confections
Desserts, candies, and sweet breads
4
Dairy Products
Cheeses
5
Grains/Cereals
Breads, crackers, pasta, and cereal
7
Produce
n b
10
dgr
tgrtg
11
wrtg
tg
12
hbhjbhjb
dghkdghmfd
13
534djdfgjfgj
fjfgajajsdg
14
dfgjdfjdfjg
dfjfskfsdkdfhkdf

BatchEditing

This example shows how to define batch edit action in controller to update database with collection view. BatchEdit allows to submit multiple changes back to database. This is accomplised by handling BatchEdit request of CollectionViewHelper. In FlexGrid, the BatchEdit action is assigned to BatchEdit property of ItemsSource.

Note: Ensure that DisableServerRead property of databound control's ItemSource is set to true when performing BatchEdit. This stops filtering, paging and sorting operations from sending an update request to the server, which will automatically updates the data in source database. These operations should be done at client side incase of BatchEditing otherwise modified data will also be submitted when user sorts, filters or performs paging.

@(Html.C1().FlexGrid().Id("fGBECView").AutoGenerateColumns(false) .Columns(columns => columns .Add(c => c.Binding("CategoryID")) .Add(c => c.Binding("CategoryName")) .Add(c => c.Binding("Description").Width("*"))) .Bind(ib => ib.DisableServerRead(true).Bind(Model.Categories).BatchEdit(Url.Action("GridBatchEdit"))) .AllowAddNew(true) .AllowDelete(true) .CssClass("grid") )
//Batch Edit function batchUpdate() { var batchEditGrid = wijmo.Control.getControl('#fGBECView'), cv = batchEditGrid.collectionView; cv.commit(); };
using CollectionView101.Models; using C1.Web.Mvc.Grid; using C1.Web.Mvc; using C1.Web.Mvc.Serialization; using System.Data.Entity.Validation; using System.Data.Entity; namespace CollectionView101.Controllers { public class HomeController : Controller { private C1NWindEntities db = new C1NWindEntities(); public ActionResult GridBatchEdit([C1JsonRequest]CollectionViewBatchEditRequest requestData) { return this.C1Json(CollectionViewHelper.BatchEdit(requestData, batchData => { var itemresults = new List>(); string error = string.Empty; bool success = true; try { if (batchData.ItemsCreated != null) { batchData.ItemsCreated.ToList().ForEach(st => { db.Categories.Add(st); itemresults.Add(new CollectionViewItemResult { Error = "", Success = ModelState.IsValid, Data = st }); }); } if (batchData.ItemsDeleted != null) { batchData.ItemsDeleted.ToList().ForEach(category => { var fCategory = db.Categories.Find(category.CategoryID); db.Categories.Remove(fCategory); itemresults.Add(new CollectionViewItemResult { Error = "", Success = ModelState.IsValid, Data = category }); }); } if (batchData.ItemsUpdated != null) { batchData.ItemsUpdated.ToList().ForEach(category => { db.Entry(category).State = EntityState.Modified; itemresults.Add(new CollectionViewItemResult { Error = "", Success = ModelState.IsValid, Data = category }); }); } db.SaveChanges(); } catch (DbEntityValidationException e) { error = string.Join(",", e.EntityValidationErrors.SelectMany(i => i.ValidationErrors).Select(i => i.ErrorMessage)); success = false; } catch (Exception e) { error = e.Message; success = false; } return new CollectionViewResponse { Error = error, Success = success, OperatedItemResults = itemresults }; }, () => db.Categories.ToList())); } // GET: Home public ActionResult Index() { return View(db); } } }

Result (live):

CategoryID
CategoryName
Description
1
Beveragess
Soft drinks, coffees, teas, beers, and ales
2
Condiments
Sweet and savory sauces, relishes, spreads, and seasonings
3
Confections
Desserts, candies, and sweet breads
4
Dairy Products
Cheeses
5
Grains/Cereals
Breads, crackers, pasta, and cereal
7
Produce
n b
10
dgr
tgrtg
11
wrtg
tg
12
hbhjbhjb
dghkdghmfd
13
534djdfgjfgj
fjfgajajsdg
14
dfgjdfjdfjg
dfjfskfsdkdfhkdf

Disable Server Reading

DisableServerRead property disables server side synchronisation. When it is set to True, all the items will be transferred to the client side. Sorting, paging or filtering will be done on client side. And the text like waiting... is not shown for loading the data when the scrollbar scrolls. Otherwise, sorting, paging or filtering will be done on server side. And sometimes the waiting... text will be shown.

@(Html.C1().FlexGrid().Id("fGDisableServerView").IsReadOnly(true).AllowSorting(true).AutoGenerateColumns(false) .Bind(b => b.DisableServerRead(true).PageSize(10).Bind(Model.Customers)).CssStyle("height","100%") .Columns(columns => columns .Add(c => c.Binding("CustomerID")) .Add(c => c.Binding("CompanyName")) .Add(c => c.Binding("ContactName")) .Add(c => c.Binding("City")) .Add(c => c.Binding("Country")) .Add(c => c.Binding("Phone")) ) ) @(Html.C1().Pager().Owner("fGDisableServerView"))
$(document).ready(function () { //Disable Server Reading fGDisableServerView = wijmo.Control.getControl('#fGDisableServerView'); }); //Disable Server Read var fGDisableServerView = null;
using CollectionView101.Models; using C1.Web.Mvc.Grid; using C1.Web.Mvc; using C1.Web.Mvc.Serialization; using System.Data.Entity.Validation; using System.Data.Entity; namespace CollectionView101.Controllers { public class HomeController : Controller { private C1NWindEntities db = new C1NWindEntities(); // GET: Home public ActionResult Index() { return View(db); } } }

Result (live):

Paging FlexGrid which PageSize is set to 10

CustomerID
CompanyName
ContactName
City
Country
Phone
ALFKI
Alfreds Futterkiste
Maria Anders
Berlin
Germany
030-0074321
ANATR
Ana Trujillo Emparedados y helados
Ana Trujillo
México D.F.
Mexico
(5) 555-4729
ANTON
Antonio Moreno Taquería
Antonio Moreno
México D.F.
Mexico
(5) 555-3932
AROUT
Around the Horn
Thomas Hardy
London
UK
(171) 555-7788
BERGS
Berglunds snabbköp
Christina Berglund
Luleå
Sweden
0921-12 34 65
BLAUS
Blauer See Delikatessen
Hanna Moos
Mannheim
Germany
0621-08460
BLONP
Blondel père et fils
Frédérique Citeaux
Strasbourg
France
88.60.15.31
BOLID
Bólido Comidas preparadas
Martín Sommer
Madrid
Spain
(91) 555 22 82
BONAP
Bon app'
Laurence Lebihan
Marseille
France
91.24.45.40
BOTTM
Bottom-Dollar Markets
Elizabeth Lincoln
Tsawassen
Canada
(604) 555-4729

Client-side Operations

CollectionView has a powerful client API. CollectionViewHelper internally performes server side operations like sorting, filtering, paging on data for MVC controls like FlexGrid, FlexChart and other Input controls. However it is possible to explicitly perform these operations on client-side. This section demonstrates following client-side operations:- Current Record Management, Sorting, Filtering, Grouping and Tracking Changes.

Note: It is important to note that the DisableServerRead property of ItemSource should be set to True if filtering, paging, sorting is to be performed on data available at client side only. The default setting is False, with default setting: sorting, paging, filtering happen on server, this is done by a internal callback request which is sent to the CollectionViewHelper on the server to perform the said operations.

Refer client api documentation for more detail.

Current Record Management

As implementing the interface ICollectionView, CollectionView can manage the current record.

This example shows how you can manage the current record through APIs provided by the CollectionView class.

In this case, we use the properties currentPosition to obtain the current record position in the collection. We also use the methods moveCurrentTo(item), moveCurrentToFirst(), moveCurrentToLast(), moveCurrentToNext(), moveCurrentToPosition(index) and moveCurrentToPrevious() to change the current position. When the current is changed, we use the events currentChanging and currentChanged to track it. We can cancel the current changing in the event currentChanging.

Notes: Click the "Move To Next" button to move the current to the next one. Click the "Move to Previous" to move the current to the previous on. Clicking the "Stop in 4th Row" button will cause the current is forbidden to be changed when it locates in the 4th row. Then clicking the "Clear Stopping" button will let the current be changed freely.

<div class="row-fluid well btn-group"> <button class="btn btn-default" id="btnCRMMoveNext">Move To Next</button> <button class="btn btn-default" id="btnCRMMovePre">Move To Previous</button> <button class="btn btn-default" id="btnCRMStop4">Stop in 4th Row</button> <button class="btn btn-default" id="btnCRMReset">Clear Stopping</button> </div> @(Html.C1().FlexGrid().Id("crmGrid").IsReadOnly(true).SelectionMode(C1.Web.Mvc.Grid.SelectionMode.Row) .AutoGenerateColumns(true).Bind(b=>b.DisableServerRead(true).Bind(Model.Customers)) )
$(document).ready(function () { //Current Record Management crmGrid = wijmo.Control.getControl('#crmGrid'); cvCRM = crmGrid.itemsSource; //new wijmo.collections.CollectionView(getData(10)), // Add the processes for buttons' click // move the current to the next one document.getElementById('btnCRMMoveNext').addEventListener('click', function () { cvCRM.moveCurrentToNext(); }); // move the current to the preivous one document.getElementById('btnCRMMovePre').addEventListener('click', function () { cvCRM.moveCurrentToPrevious(); }); // when the current item is the 4th one, forbid changing current. document.getElementById('btnCRMStop4').addEventListener('click', function () { cvCRM.currentChanging.addHandler(stopCurrentIn4th); }); // restore to be able to change current. document.getElementById('btnCRMReset').addEventListener('click', function () { cvCRM.currentChanging.removeHandler(stopCurrentIn4th); }); // define the funciton to forbid the current moving. function stopCurrentIn4th(sender, e) { // when the current is the 4rd item, stop moving. if (sender.currentPosition === 3) { e.cancel = true; } }; }); // create collectionview, grid var crmGrid = null , cvCRM = null;
using CollectionView101.Models; using C1.Web.Mvc.Grid; using C1.Web.Mvc; using C1.Web.Mvc.Serialization; using System.Data.Entity.Validation; using System.Data.Entity; namespace CollectionView101.Controllers { public class HomeController : Controller { private C1NWindEntities db = new C1NWindEntities(); // GET: Home public ActionResult Index() { return View(db); } } }

Result (live):

Customer ID
Company Name
Contact Name
Contact Title
Address
City
Region
Postal Code
Country
Phone
Fax
ALFKI
Alfreds Futterkiste
Maria Anders
Sales Representative
Obere Str. 57
Berlin
12209
Germany
030-0074321
030-0076545
ANATR
Ana Trujillo Emparedados y helados
Ana Trujillo
Owner
Avda. de la Constitución 2222
México D.F.
05021
Mexico
(5) 555-4729
(5) 555-3745
ANTON
Antonio Moreno Taquería
Antonio Moreno
Owner
Mataderos 2312
México D.F.
05023
Mexico
(5) 555-3932
AROUT
Around the Horn
Thomas Hardy
Sales Representative
120 Hanover Sq.
London
WA1 1DP
UK
(171) 555-7788
(171) 555-6750
BERGS
Berglunds snabbköp
Christina Berglund
Order Administrator
Berguvsvägen 8
Luleå
S-958 22
Sweden
0921-12 34 65
0921-12 34 67
BLAUS
Blauer See Delikatessen
Hanna Moos
Sales Representative
Forsterstr. 57
Mannheim
68306
Germany
0621-08460
0621-08924
BLONP
Blondel père et fils
Frédérique Citeaux
Marketing Manager
24, place Kléber
Strasbourg
67000
France
88.60.15.31
88.60.15.32
BOLID
Bólido Comidas preparadas
Martín Sommer
Owner
C/ Araquil, 67
Madrid
28023
Spain
(91) 555 22 82
(91) 555 91 99
BONAP
Bon app'
Laurence Lebihan
Owner
12, rue des Bouchers
Marseille
13008
France
91.24.45.40
91.24.45.41
BOTTM
Bottom-Dollar Markets
Elizabeth Lincoln
Accounting Manager
23 Tsawassen Blvd.
Tsawassen
BC
T2F 8M4
Canada
(604) 555-4729
(604) 555-3745
BSBEV
B's Beverages
Victoria Ashworth
Sales Representative
Fauntleroy Circus
London
EC2 5NT
UK
(171) 555-1212
CACTU
Cactus Comidas para llevar
Patricio Simpson
Sales Agent
Cerrito 333
Buenos Aires
1010
Argentina
(1) 135-5555
(1) 135-4892
CENTC
Centro comercial Moctezuma
Francisco Chang
Marketing Manager
Sierras de Granada 9993
México D.F.
05022
Mexico
(5) 555-3392
(5) 555-7293
CHOPS
Chop-suey Chinese
Yang Wang
Owner
Hauptstr. 29
Bern
3012
Switzerland
0452-076545
COMMI
Comércio Mineiro
Pedro Afonso
Sales Associate
Av. dos Lusíadas, 23
São Paulo
SP
05432-043
Brazil
(11) 555-7647
CONSH
Consolidated Holdings
Elizabeth Brown
Sales Representative
Berkeley Gardens 12 Brewery
London
WX1 6LT
UK
(171) 555-2282
(171) 555-9199
DRACD
Drachenblut Delikatessen
Sven Ottlieb
Order Administrator
Walserweg 21
Aachen
52066
Germany
0241-039123
0241-059428
DUMON
Du monde entier
Janine Labrune
Owner
67, rue des Cinquante Otages
Nantes
44000
France
40.67.88.88
40.67.89.89
EASTC
Eastern Connection
Ann Devon
Sales Agent
35 King George
London
WX3 6FW
UK
(171) 555-0297
(171) 555-3373
ERNSH
Ernst Handel
Roland Mendel
Sales Manager
Kirchgasse 6
Graz
8010
Austria
7675-3425
7675-3426
FAMIA
Familia Arquibaldo
Aria Cruz
Marketing Assistant
Rua Orós, 92
São Paulo
SP
05442-030
Brazil
(11) 555-9857
FISSA
FISSA Fabrica Inter. Salchichas S.A.
Diego Roel
Accounting Manager
C/ Moralzarzal, 86
Madrid
28034
Spain
(91) 555 94 44
(91) 555 55 93
FOLIG
Folies gourmandes
Martine Rancé
Assistant Sales Agent
184, chaussée de Tournai
Lille
59000
France
20.16.10.16
20.16.10.17
FOLKO
Folk och fä HB
Maria Larsson
Owner
Ã…kergatan 24
Bräcke
S-844 67
Sweden
0695-34 67 21
FRANK
Frankenversand
Peter Franken
Marketing Manager
Berliner Platz 43
München
80805
Germany
089-0877310
089-0877451
FRANR
France restauration
Carine Schmitt
Marketing Manager
54, rue Royale
Nantes
44000
France
40.32.21.21
40.32.21.20
FRANS
Franchi S.p.A.
Paolo Accorti
Sales Representative
Via Monte Bianco 34
Torino
10100
Italy
011-4988260
011-4988261
FURIB
Furia Bacalhau e Frutos do Mar
Lino Rodriguez
Sales Manager
Jardim das rosas n. 32
Lisboa
1675
Portugal
(1) 354-2534
(1) 354-2535
GALED
Galería del gastrónomo
Eduardo Saavedra
Marketing Manager
Rambla de Cataluña, 23
Barcelona
08022
Spain
(93) 203 4560
(93) 203 4561
GODOS
Godos Cocina Típica
José Pedro Freyre
Sales Manager
C/ Romero, 33
Sevilla
41101
Spain
(95) 555 82 82
GOURL
Gourmet Lanchonetes
André Fonseca
Sales Associate
Av. Brasil, 442
Campinas
SP
04876-786
Brazil
(11) 555-9482
GREAL
Great Lakes Food Market
Howard Snyder
Marketing Manager
2732 Baker Blvd.
Eugene
OR
97403
USA
(503) 555-7555
GROSR
GROSELLA-Restaurante
Manuel Pereira
Owner
5ª Ave. Los Palos Grandes
Caracas
DF
1081
Venezuela
(2) 283-2951
(2) 283-3397
HANAR
Hanari Carnes
Mario Pontes
Accounting Manager
Rua do Paço, 67
Rio de Janeiro
RJ
05454-876
Brazil
(21) 555-0091
(21) 555-8765
HILAA
HILARIÓN-Abastos
Carlos Hernández
Sales Representative
Carrera 22 con Ave. Carlos Soublette #8-35
San Cristóbal
Táchira
5022
Venezuela
(5) 555-1340
(5) 555-1948
HUNGC
Hungry Coyote Import Store
Yoshi Latimer
Sales Representative
City Center Plaza 516 Main St.
Elgin
OR
97827
USA
(503) 555-6874
(503) 555-2376
HUNGO
Hungry Owl All-Night Grocers
Patricia McKenna
Sales Associate
8 Johnstown Road
Cork
Co. Cork
Ireland
2967 542
2967 3333
ISLAT
Island Trading
Helen Bennett
Marketing Manager
Garden House Crowther Way
Cowes
Isle of Wight
PO31 7PJ
UK
(198) 555-8888
KOENE
Königlich Essen
Philip Cramer
Sales Associate
Maubelstr. 90
Brandenburg
14776
Germany
0555-09876
LACOR
La corne d'abondance
Daniel Tonini
Sales Representative
67, avenue de l'Europe
Versailles
78000
France
30.59.84.10
30.59.85.11
LAMAI
La maison d'Asie
Annette Roulet
Sales Manager
1 rue Alsace-Lorraine
Toulouse
31000
France
61.77.61.10
61.77.61.11
LAUGB
Laughing Bacchus Wine Cellars
Yoshi Tannamuri
Marketing Assistant
1900 Oak St.
Vancouver
BC
V3F 2K1
Canada
(604) 555-3392
(604) 555-7293
LAZYK
Lazy K Kountry Store
John Steel
Marketing Manager
12 Orchestra Terrace
Walla Walla
WA
99362
USA
(509) 555-7969
(509) 555-6221
LEHMS
Lehmanns Marktstand
Renate Messner
Sales Representative
Magazinweg 7
Frankfurt a.M.
60528
Germany
069-0245984
069-0245874
LETSS
Let's Stop N Shop
Jaime Yorres
Owner
87 Polk St. Suite 5
San Francisco
CA
94117
USA
(415) 555-5938
LILAS
LILA-Supermercado
Carlos González
Accounting Manager
Carrera 52 con Ave. Bolívar #65-98 Llano Largo
Barquisimeto
Lara
3508
Venezuela
(9) 331-6954
(9) 331-7256
LINOD
LINO-Delicateses
Felipe Izquierdo
Owner
Ave. 5 de Mayo Porlamar
I. de Margarita
Nueva Esparta
4980
Venezuela
(8) 34-56-12
(8) 34-93-93
LONEP
Lonesome Pine Restaurant
Fran Wilson
Sales Manager
89 Chiaroscuro Rd.
Portland
OR
97219
USA
(503) 555-9573
(503) 555-9646
MAGAA
Magazzini Alimentari Riuniti
Giovanni Rovelli
Marketing Manager
Via Ludovico il Moro 22
Bergamo
24100
Italy
035-640230
035-640231
MAISD
Maison Dewey
Catherine Dewey
Sales Agent
Rue Joseph-Bens 532
Bruxelles
B-1180
Belgium
(02) 201 24 67
(02) 201 24 68
MEREP
Mère Paillarde
Jean Fresnière
Marketing Assistant
43 rue St. Laurent
Montréal
Québec
H1J 1C3
Canada
(514) 555-8054
(514) 555-8055
MORGK
Morgenstern Gesundkost
Alexander Feuer
Marketing Assistant
Heerstr. 22
Leipzig
04179
Germany
0342-023176
NORTS
North/South
Simon Crowther
Sales Associate
South House 300 Queensbridge
London
SW7 1RZ
UK
(171) 555-7733
(171) 555-2530
OCEAN
Océano Atlántico Ltda.
Yvonne Moncada
Sales Agent
Ing. Gustavo Moncada 8585 Piso 20-A
Buenos Aires
1010
Argentina
(1) 135-5333
(1) 135-5535
OLDWO
Old World Delicatessen
Rene Phillips
Sales Representative
2743 Bering St.
Anchorage
AK
99508
USA
(907) 555-7584
(907) 555-2880
OTTIK
Ottilies Käseladen
Henriette Pfalzheim
Owner
Mehrheimerstr. 369
Köln
50739
Germany
0221-0644327
0221-0765721
PARIS
Paris spécialités
Marie Bertrand
Owner
265, boulevard Charonne
Paris
75012
France
(1) 42.34.22.66
(1) 42.34.22.77
PERIC
Pericles Comidas clásicas
Guillermo Fernández
Sales Representative
Calle Dr. Jorge Cash 321
México D.F.
05033
Mexico
(5) 552-3745
(5) 545-3745
PICCO
Piccolo und mehr
Georg Pipps
Sales Manager
Geislweg 14
Salzburg
5020
Austria
6562-9722
6562-9723
PRINI
Princesa Isabel Vinhos
Isabel de Castro
Sales Representative
Estrada da saúde n. 58
Lisboa
1756
Portugal
(1) 356-5634
QUEDE
Que Delícia
Bernardo Batista
Accounting Manager
Rua da Panificadora, 12
Rio de Janeiro
RJ
02389-673
Brazil
(21) 555-4252
(21) 555-4545
QUEEN
Queen Cozinha
Lúcia Carvalho
Marketing Assistant
Alameda dos Canàrios, 891
São Paulo
SP
05487-020
Brazil
(11) 555-1189
QUICK
QUICK-Stop
Horst Kloss
Accounting Manager
Taucherstraße 10
Cunewalde
01307
Germany
0372-035188
RANCH
Rancho grande
Sergio Gutiérrez
Sales Representative
Av. del Libertador 900
Buenos Aires
1010
Argentina
(1) 123-5555
(1) 123-5556
RATTC
Rattlesnake Canyon Grocery
Paula Wilson
Assistant Sales Representative
2817 Milton Dr.
Albuquerque
NM
87110
USA
(505) 555-5939
(505) 555-3620
REGGC
Reggiani Caseifici
Maurizio Moroni
Sales Associate
Strada Provinciale 124
Reggio Emilia
42100
Italy
0522-556721
0522-556722
RICAR
Ricardo Adocicados
Janete Limeira
Assistant Sales Agent
Av. Copacabana, 267
Rio de Janeiro
RJ
02389-890
Brazil
(21) 555-3412
RICSU
Richter Supermarkt
Michael Holz
Sales Manager
Grenzacherweg 237
Genève
1203
Switzerland
0897-034214
ROMEY
Romero y tomillo
Alejandra Camino
Accounting Manager
Gran Vía, 1
Madrid
28001
Spain
(91) 745 6200
(91) 745 6210
SANTG
Santé Gourmet
Jonas Bergulfsen
Owner
Erling Skakkes gate 78
Stavern
4110
Norway
07-98 92 35
07-98 92 47
SAVEA
Save-a-lot Markets
Jose Pavarotti
Sales Representative
187 Suffolk Ln.
Boise
ID
83720
USA
(208) 555-8097
SEVES
Seven Seas Imports
Hari Kumar
Sales Manager
90 Wadhurst Rd.
London
OX15 4NB
UK
(171) 555-1717
(171) 555-5646
SIMOB
Simons bistro
Jytte Petersen
Owner
Vinbæltet 34
København
1734
Denmark
31 12 34 56
31 13 35 57
SPECD
Spécialités du monde
Dominique Perrier
Marketing Manager
25, rue Lauriston
Paris
75016
France
(1) 47.55.60.10
(1) 47.55.60.20
SPLIR
Split Rail Beer & Ale
Art Braunschweiger
Sales Manager
P.O. Box 555
Lander
WY
82520
USA
(307) 555-4680
(307) 555-6525
SUPRD
Suprêmes délices
Pascale Cartrain
Accounting Manager
Boulevard Tirou, 255
Charleroi
B-6000
Belgium
(071) 23 67 22 20
(071) 23 67 22 21
THEBI
The Big Cheese
Liz Nixon
Marketing Manager
89 Jefferson Way Suite 2
Portland
OR
97201
USA
(503) 555-3612
THECR
The Cracker Box
Liu Wong
Marketing Assistant
55 Grizzly Peak Rd.
Butte
MT
59801
USA
(406) 555-5834
(406) 555-8083
TOMSP
Toms Spezialitäten
Karin Josephs
Marketing Manager
Luisenstr. 48
Münster
44087
Germany
0251-031259
0251-035695
TORTU
Tortuga Restaurante
Miguel Angel Paolino
Owner
Avda. Azteca 123
México D.F.
05033
Mexico
(5) 555-2933
TRADH
Tradição Hipermercados
Anabela Domingues
Sales Representative
Av. Inês de Castro, 414
São Paulo
SP
05634-030
Brazil
(11) 555-2167
(11) 555-2168
TRAIH
Trail's Head Gourmet Provisioners
Helvetius Nagy
Sales Associate
722 DaVinci Blvd.
Kirkland
WA
98034
USA
(206) 555-8257
(206) 555-2174
VAFFE
Vaffeljernet
Palle Ibsen
Sales Manager
Smagsløget 45
Ã…rhus
8200
Denmark
86 21 32 43
86 22 33 44
VICTE
Victuailles en stock
Mary Saveley
Sales Agent
2, rue du Commerce
Lyon
69004
France
78.32.54.86
78.32.54.87
VINET
Vins et alcools Chevalier
Paul Henriot
Accounting Manager
59 rue de l'Abbaye
Reims
51100
France
26.47.15.10
26.47.15.11
WANDK
Die Wandernde Kuh
Rita Müller
Sales Representative
Adenauerallee 900
Stuttgart
70563
Germany
0711-020361
0711-035428
WARTH
Wartian Herkku
Pirkko Koskitalo
Accounting Manager
Torikatu 38
Oulu
90110
Finland
981-443655
981-443655
WELLI
Wellington Importadora
Paula Parente
Sales Manager
Rua do Mercado, 12
Resende
SP
08737-363
Brazil
(14) 555-8122
WHITC
White Clover Markets
Karl Jablonski
Owner
305 - 14th Ave. S. Suite 3B
Seattle
WA
98128
USA
(206) 555-4112
(206) 555-4115
WILMK
Wilman Kala
Matti Karttunen
Owner/Marketing Assistant
Keskuskatu 45
Helsinki
21240
Finland
90-224 8858
90-224 8858
WOLZA
Wolski Zajazd
Zbyszek Piestrzeniewicz
Owner
ul. Filtrowa 68
Warszawa
01-012
Poland
(26) 642-7012
(26) 642-7012

Sorting

The CollectionView class supports sorting through the ICollectionView interface, which is identical to the one in .NET. To enable sorting, add one or more sortDescriptions objects to the CollectionView.sortDescriptions property. Then the sorted result can be obtained from the CollectionView.items property.

SortDescription objects are flexible, allowing you to sort data based on value in ascending or descending order. In the sample below, you can sort the collection based on the corresponding field value choosed in the first list. You can also specify the sorting order in the second list.

<div class="row-fluid well row"> <div class="col-md-8"> <select id="sortingFieldNameList" class="form-control"> </select> </div> <div class="col-md-4"> <select id="sortingOrderList" class="form-control"> <option value="true" selected="selected">Ascending</option> <option value="false">Descending</option> </select> </div> </div> @(Html.C1().FlexGrid().Id("sortingGrid").IsReadOnly(true).AllowSorting(false).AutoGenerateColumns(false) .Bind(b => b.DisableServerRead(true).Bind(Model.Customers)) .Columns(columns => columns .Add(c => c.Binding("CustomerID")) .Add(c => c.Binding("CompanyName")) .Add(c => c.Binding("ContactName")) .Add(c => c.Binding("City")) .Add(c => c.Binding("Country")) .Add(c => c.Binding("Phone")) ) )
function getNames() { return ['CustomerID', 'CompanyName', 'ContactName', 'City', 'Country', 'Phone']; }; $(document).ready(function () { //Sorting sortingGrid = wijmo.Control.getControl('#sortingGrid'); cvSorting = sortingGrid.itemsSource; sortingFieldNameList = document.getElementById('sortingFieldNameList'); sortingOrderList = document.getElementById('sortingOrderList'); //sortingNames = getNames(); // initialize the list items for field names and orders. sortingFieldNameList.innerHTML += ''; for (var i = 0; i < sortingNames.length; i++) { sortingFieldNameList.innerHTML += ''; } // track the list change in order to udpate the sortDescriptions property. sortingFieldNameList.addEventListener('change', sortGrid); sortingOrderList.addEventListener('change', sortGrid); }); //Sorting // create collectionview, grid, the jQuery elements, the field name list. var cvSorting = null, sortingGrid =null, sortingFieldNameList = null, sortingOrderList = null, sortingNames = getNames(); function sortGrid() { var fieldName = sortingFieldNameList.value, ascending = sortingOrderList.value, sd, sdNew; if (!fieldName) { return; } ascending = ascending === 'true'; sd = cvSorting.sortDescriptions; sdNew = new wijmo.collections.SortDescription(fieldName, ascending); // remove any old sort descriptors and add the new one sd.splice(0, sd.length, sdNew); };
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using CollectionView101.Models; using C1.Web.Mvc.Grid; using C1.Web.Mvc; using C1.Web.Mvc.Serialization; using System.Data.Entity.Validation; using System.Data.Entity; namespace CollectionView101.Controllers { public class HomeController : Controller { private C1NWindEntities db = new C1NWindEntities(); // GET: Home public ActionResult Index() { return View(db); } } }

Result (live):

CustomerID
CompanyName
ContactName
City
Country
Phone
ALFKI
Alfreds Futterkiste
Maria Anders
Berlin
Germany
030-0074321
ANATR
Ana Trujillo Emparedados y helados
Ana Trujillo
México D.F.
Mexico
(5) 555-4729
ANTON
Antonio Moreno Taquería
Antonio Moreno
México D.F.
Mexico
(5) 555-3932
AROUT
Around the Horn
Thomas Hardy
London
UK
(171) 555-7788
BERGS
Berglunds snabbköp
Christina Berglund
Luleå
Sweden
0921-12 34 65
BLAUS
Blauer See Delikatessen
Hanna Moos
Mannheim
Germany
0621-08460
BLONP
Blondel père et fils
Frédérique Citeaux
Strasbourg
France
88.60.15.31
BOLID
Bólido Comidas preparadas
Martín Sommer
Madrid
Spain
(91) 555 22 82
BONAP
Bon app'
Laurence Lebihan
Marseille
France
91.24.45.40
BOTTM
Bottom-Dollar Markets
Elizabeth Lincoln
Tsawassen
Canada
(604) 555-4729
BSBEV
B's Beverages
Victoria Ashworth
London
UK
(171) 555-1212
CACTU
Cactus Comidas para llevar
Patricio Simpson
Buenos Aires
Argentina
(1) 135-5555
CENTC
Centro comercial Moctezuma
Francisco Chang
México D.F.
Mexico
(5) 555-3392
CHOPS
Chop-suey Chinese
Yang Wang
Bern
Switzerland
0452-076545
COMMI
Comércio Mineiro
Pedro Afonso
São Paulo
Brazil
(11) 555-7647
CONSH
Consolidated Holdings
Elizabeth Brown
London
UK
(171) 555-2282
DRACD
Drachenblut Delikatessen
Sven Ottlieb
Aachen
Germany
0241-039123
DUMON
Du monde entier
Janine Labrune
Nantes
France
40.67.88.88
EASTC
Eastern Connection
Ann Devon
London
UK
(171) 555-0297
ERNSH
Ernst Handel
Roland Mendel
Graz
Austria
7675-3425
FAMIA
Familia Arquibaldo
Aria Cruz
São Paulo
Brazil
(11) 555-9857
FISSA
FISSA Fabrica Inter. Salchichas S.A.
Diego Roel
Madrid
Spain
(91) 555 94 44
FOLIG
Folies gourmandes
Martine Rancé
Lille
France
20.16.10.16
FOLKO
Folk och fä HB
Maria Larsson
Bräcke
Sweden
0695-34 67 21
FRANK
Frankenversand
Peter Franken
München
Germany
089-0877310
FRANR
France restauration
Carine Schmitt
Nantes
France
40.32.21.21
FRANS
Franchi S.p.A.
Paolo Accorti
Torino
Italy
011-4988260
FURIB
Furia Bacalhau e Frutos do Mar
Lino Rodriguez
Lisboa
Portugal
(1) 354-2534
GALED
Galería del gastrónomo
Eduardo Saavedra
Barcelona
Spain
(93) 203 4560
GODOS
Godos Cocina Típica
José Pedro Freyre
Sevilla
Spain
(95) 555 82 82
GOURL
Gourmet Lanchonetes
André Fonseca
Campinas
Brazil
(11) 555-9482
GREAL
Great Lakes Food Market
Howard Snyder
Eugene
USA
(503) 555-7555
GROSR
GROSELLA-Restaurante
Manuel Pereira
Caracas
Venezuela
(2) 283-2951
HANAR
Hanari Carnes
Mario Pontes
Rio de Janeiro
Brazil
(21) 555-0091
HILAA
HILARIÓN-Abastos
Carlos Hernández
San Cristóbal
Venezuela
(5) 555-1340
HUNGC
Hungry Coyote Import Store
Yoshi Latimer
Elgin
USA
(503) 555-6874
HUNGO
Hungry Owl All-Night Grocers
Patricia McKenna
Cork
Ireland
2967 542
ISLAT
Island Trading
Helen Bennett
Cowes
UK
(198) 555-8888
KOENE
Königlich Essen
Philip Cramer
Brandenburg
Germany
0555-09876
LACOR
La corne d'abondance
Daniel Tonini
Versailles
France
30.59.84.10
LAMAI
La maison d'Asie
Annette Roulet
Toulouse
France
61.77.61.10
LAUGB
Laughing Bacchus Wine Cellars
Yoshi Tannamuri
Vancouver
Canada
(604) 555-3392
LAZYK
Lazy K Kountry Store
John Steel
Walla Walla
USA
(509) 555-7969
LEHMS
Lehmanns Marktstand
Renate Messner
Frankfurt a.M.
Germany
069-0245984
LETSS
Let's Stop N Shop
Jaime Yorres
San Francisco
USA
(415) 555-5938
LILAS
LILA-Supermercado
Carlos González
Barquisimeto
Venezuela
(9) 331-6954
LINOD
LINO-Delicateses
Felipe Izquierdo
I. de Margarita
Venezuela
(8) 34-56-12
LONEP
Lonesome Pine Restaurant
Fran Wilson
Portland
USA
(503) 555-9573
MAGAA
Magazzini Alimentari Riuniti
Giovanni Rovelli
Bergamo
Italy
035-640230
MAISD
Maison Dewey
Catherine Dewey
Bruxelles
Belgium
(02) 201 24 67
MEREP
Mère Paillarde
Jean Fresnière
Montréal
Canada
(514) 555-8054
MORGK
Morgenstern Gesundkost
Alexander Feuer
Leipzig
Germany
0342-023176
NORTS
North/South
Simon Crowther
London
UK
(171) 555-7733
OCEAN
Océano Atlántico Ltda.
Yvonne Moncada
Buenos Aires
Argentina
(1) 135-5333
OLDWO
Old World Delicatessen
Rene Phillips
Anchorage
USA
(907) 555-7584
OTTIK
Ottilies Käseladen
Henriette Pfalzheim
Köln
Germany
0221-0644327
PARIS
Paris spécialités
Marie Bertrand
Paris
France
(1) 42.34.22.66
PERIC
Pericles Comidas clásicas
Guillermo Fernández
México D.F.
Mexico
(5) 552-3745
PICCO
Piccolo und mehr
Georg Pipps
Salzburg
Austria
6562-9722
PRINI
Princesa Isabel Vinhos
Isabel de Castro
Lisboa
Portugal
(1) 356-5634
QUEDE
Que Delícia
Bernardo Batista
Rio de Janeiro
Brazil
(21) 555-4252
QUEEN
Queen Cozinha
Lúcia Carvalho
São Paulo
Brazil
(11) 555-1189
QUICK
QUICK-Stop
Horst Kloss
Cunewalde
Germany
0372-035188
RANCH
Rancho grande
Sergio Gutiérrez
Buenos Aires
Argentina
(1) 123-5555
RATTC
Rattlesnake Canyon Grocery
Paula Wilson
Albuquerque
USA
(505) 555-5939
REGGC
Reggiani Caseifici
Maurizio Moroni
Reggio Emilia
Italy
0522-556721
RICAR
Ricardo Adocicados
Janete Limeira
Rio de Janeiro
Brazil
(21) 555-3412
RICSU
Richter Supermarkt
Michael Holz
Genève
Switzerland
0897-034214
ROMEY
Romero y tomillo
Alejandra Camino
Madrid
Spain
(91) 745 6200
SANTG
Santé Gourmet
Jonas Bergulfsen
Stavern
Norway
07-98 92 35
SAVEA
Save-a-lot Markets
Jose Pavarotti
Boise
USA
(208) 555-8097
SEVES
Seven Seas Imports
Hari Kumar
London
UK
(171) 555-1717
SIMOB
Simons bistro
Jytte Petersen
København
Denmark
31 12 34 56
SPECD
Spécialités du monde
Dominique Perrier
Paris
France
(1) 47.55.60.10
SPLIR
Split Rail Beer & Ale
Art Braunschweiger
Lander
USA
(307) 555-4680
SUPRD
Suprêmes délices
Pascale Cartrain
Charleroi
Belgium
(071) 23 67 22 20
THEBI
The Big Cheese
Liz Nixon
Portland
USA
(503) 555-3612
THECR
The Cracker Box
Liu Wong
Butte
USA
(406) 555-5834
TOMSP
Toms Spezialitäten
Karin Josephs
Münster
Germany
0251-031259
TORTU
Tortuga Restaurante
Miguel Angel Paolino
México D.F.
Mexico
(5) 555-2933
TRADH
Tradição Hipermercados
Anabela Domingues
São Paulo
Brazil
(11) 555-2167
TRAIH
Trail's Head Gourmet Provisioners
Helvetius Nagy
Kirkland
USA
(206) 555-8257
VAFFE
Vaffeljernet
Palle Ibsen
Ã…rhus
Denmark
86 21 32 43
VICTE
Victuailles en stock
Mary Saveley
Lyon
France
78.32.54.86
VINET
Vins et alcools Chevalier
Paul Henriot
Reims
France
26.47.15.10
WANDK
Die Wandernde Kuh
Rita Müller
Stuttgart
Germany
0711-020361
WARTH
Wartian Herkku
Pirkko Koskitalo
Oulu
Finland
981-443655
WELLI
Wellington Importadora
Paula Parente
Resende
Brazil
(14) 555-8122
WHITC
White Clover Markets
Karl Jablonski
Seattle
USA
(206) 555-4112
WILMK
Wilman Kala
Matti Karttunen
Helsinki
Finland
90-224 8858
WOLZA
Wolski Zajazd
Zbyszek Piestrzeniewicz
Warszawa
Poland
(26) 642-7012

Filtering

The CollectionView class supports filtering through the ICollectionView interface, which is identical to the one in .NET. To enable filtering, set the CollectionView.filter property to a function that determines which objects to be included in the view. For the client side Filtering to work, the DisableServerRead property of the ItemSource should be true.

In this example, we create a filter for the country, and get the filter value from the input control. When you input the filter, the grid will be refreshed and render the fitlered data.

<div class="row-fluid well"> <input id="filteringInput" type="text" class="form-control app-pad" placeholder="Please input the character you want filter by country(case-insensitive)" /> </div> @(Html.C1().FlexGrid().Id("filteringGrid").IsReadOnly(true).AllowSorting(false).AutoGenerateColumns(false) .Bind(b => b.Bind(Model.Customers).DisableServerRead(true)) .Columns(columns => columns .Add(c => c.Binding("CustomerID")) .Add(c => c.Binding("CompanyName")) .Add(c => c.Binding("ContactName")) .Add(c => c.Binding("City")) .Add(c => c.Binding("Country")) .Add(c => c.Binding("Phone")) ) )
function getFilterNames() { return ['ProductID', 'ProductName', 'SupplierID', 'CategoryID', 'QuantityPerUnit', 'UnitPrice', 'UnitsInStock', 'UnitsOnOrder', 'ReorderLevel']; }; $(document).ready(function () { //Filtering // create collectionview, grid, filter with timeout, textbox for inputting filter. filteringGrid = wijmo.Control.getControl('#filteringGrid'); cvFiltering = filteringGrid.itemsSource; filteringInput = document.getElementById('filteringInput'); // apply filter when input filteringInput.addEventListener('input', filterGrid); }); //Filtering // create collectionview, grid, filter with timeout, textbox for inputting filter. var cvFiltering = null, filteringGrid = null, toFilter, filteringInput = null; // define the filter function for the collection view. function filterFunction(item) { var filter = filteringInput.value.toLowerCase(); if (!filter) { return true; } return item.CustomerID.toLowerCase().indexOf(filter) > -1; }; // apply filter (applied on a 500 ms timeOut) function filterGrid() { if (toFilter) { clearTimeout(toFilter); } toFilter = setTimeout(function () { toFilter = null; if (cvFiltering.filter === filterFunction) { cvFiltering.refresh(); } else { cvFiltering.filter = filterFunction; } }, 500); };
using System.Web.Mvc; using CollectionView101.Models; using C1.Web.Mvc.Grid; using C1.Web.Mvc; using C1.Web.Mvc.Serialization; using System.Data.Entity.Validation; using System.Data.Entity; namespace CollectionView101.Controllers { public class HomeController : Controller { private C1NWindEntities db = new C1NWindEntities(); // GET: Home public ActionResult Index() { return View(db); } } }

Result (live):

CustomerID
CompanyName
ContactName
City
Country
Phone
ALFKI
Alfreds Futterkiste
Maria Anders
Berlin
Germany
030-0074321
ANATR
Ana Trujillo Emparedados y helados
Ana Trujillo
México D.F.
Mexico
(5) 555-4729
ANTON
Antonio Moreno Taquería
Antonio Moreno
México D.F.
Mexico
(5) 555-3932
AROUT
Around the Horn
Thomas Hardy
London
UK
(171) 555-7788
BERGS
Berglunds snabbköp
Christina Berglund
Luleå
Sweden
0921-12 34 65
BLAUS
Blauer See Delikatessen
Hanna Moos
Mannheim
Germany
0621-08460
BLONP
Blondel père et fils
Frédérique Citeaux
Strasbourg
France
88.60.15.31
BOLID
Bólido Comidas preparadas
Martín Sommer
Madrid
Spain
(91) 555 22 82
BONAP
Bon app'
Laurence Lebihan
Marseille
France
91.24.45.40
BOTTM
Bottom-Dollar Markets
Elizabeth Lincoln
Tsawassen
Canada
(604) 555-4729
BSBEV
B's Beverages
Victoria Ashworth
London
UK
(171) 555-1212
CACTU
Cactus Comidas para llevar
Patricio Simpson
Buenos Aires
Argentina
(1) 135-5555
CENTC
Centro comercial Moctezuma
Francisco Chang
México D.F.
Mexico
(5) 555-3392
CHOPS
Chop-suey Chinese
Yang Wang
Bern
Switzerland
0452-076545
COMMI
Comércio Mineiro
Pedro Afonso
São Paulo
Brazil
(11) 555-7647
CONSH
Consolidated Holdings
Elizabeth Brown
London
UK
(171) 555-2282
DRACD
Drachenblut Delikatessen
Sven Ottlieb
Aachen
Germany
0241-039123
DUMON
Du monde entier
Janine Labrune
Nantes
France
40.67.88.88
EASTC
Eastern Connection
Ann Devon
London
UK
(171) 555-0297
ERNSH
Ernst Handel
Roland Mendel
Graz
Austria
7675-3425
FAMIA
Familia Arquibaldo
Aria Cruz
São Paulo
Brazil
(11) 555-9857
FISSA
FISSA Fabrica Inter. Salchichas S.A.
Diego Roel
Madrid
Spain
(91) 555 94 44
FOLIG
Folies gourmandes
Martine Rancé
Lille
France
20.16.10.16
FOLKO
Folk och fä HB
Maria Larsson
Bräcke
Sweden
0695-34 67 21
FRANK
Frankenversand
Peter Franken
München
Germany
089-0877310
FRANR
France restauration
Carine Schmitt
Nantes
France
40.32.21.21
FRANS
Franchi S.p.A.
Paolo Accorti
Torino
Italy
011-4988260
FURIB
Furia Bacalhau e Frutos do Mar
Lino Rodriguez
Lisboa
Portugal
(1) 354-2534
GALED
Galería del gastrónomo
Eduardo Saavedra
Barcelona
Spain
(93) 203 4560
GODOS
Godos Cocina Típica
José Pedro Freyre
Sevilla
Spain
(95) 555 82 82
GOURL
Gourmet Lanchonetes
André Fonseca
Campinas
Brazil
(11) 555-9482
GREAL
Great Lakes Food Market
Howard Snyder
Eugene
USA
(503) 555-7555
GROSR
GROSELLA-Restaurante
Manuel Pereira
Caracas
Venezuela
(2) 283-2951
HANAR
Hanari Carnes
Mario Pontes
Rio de Janeiro
Brazil
(21) 555-0091
HILAA
HILARIÓN-Abastos
Carlos Hernández
San Cristóbal
Venezuela
(5) 555-1340
HUNGC
Hungry Coyote Import Store
Yoshi Latimer
Elgin
USA
(503) 555-6874
HUNGO
Hungry Owl All-Night Grocers
Patricia McKenna
Cork
Ireland
2967 542
ISLAT
Island Trading
Helen Bennett
Cowes
UK
(198) 555-8888
KOENE
Königlich Essen
Philip Cramer
Brandenburg
Germany
0555-09876
LACOR
La corne d'abondance
Daniel Tonini
Versailles
France
30.59.84.10
LAMAI
La maison d'Asie
Annette Roulet
Toulouse
France
61.77.61.10
LAUGB
Laughing Bacchus Wine Cellars
Yoshi Tannamuri
Vancouver
Canada
(604) 555-3392
LAZYK
Lazy K Kountry Store
John Steel
Walla Walla
USA
(509) 555-7969
LEHMS
Lehmanns Marktstand
Renate Messner
Frankfurt a.M.
Germany
069-0245984
LETSS
Let's Stop N Shop
Jaime Yorres
San Francisco
USA
(415) 555-5938
LILAS
LILA-Supermercado
Carlos González
Barquisimeto
Venezuela
(9) 331-6954
LINOD
LINO-Delicateses
Felipe Izquierdo
I. de Margarita
Venezuela
(8) 34-56-12
LONEP
Lonesome Pine Restaurant
Fran Wilson
Portland
USA
(503) 555-9573
MAGAA
Magazzini Alimentari Riuniti
Giovanni Rovelli
Bergamo
Italy
035-640230
MAISD
Maison Dewey
Catherine Dewey
Bruxelles
Belgium
(02) 201 24 67
MEREP
Mère Paillarde
Jean Fresnière
Montréal
Canada
(514) 555-8054
MORGK
Morgenstern Gesundkost
Alexander Feuer
Leipzig
Germany
0342-023176
NORTS
North/South
Simon Crowther
London
UK
(171) 555-7733
OCEAN
Océano Atlántico Ltda.
Yvonne Moncada
Buenos Aires
Argentina
(1) 135-5333
OLDWO
Old World Delicatessen
Rene Phillips
Anchorage
USA
(907) 555-7584
OTTIK
Ottilies Käseladen
Henriette Pfalzheim
Köln
Germany
0221-0644327
PARIS
Paris spécialités
Marie Bertrand
Paris
France
(1) 42.34.22.66
PERIC
Pericles Comidas clásicas
Guillermo Fernández
México D.F.
Mexico
(5) 552-3745
PICCO
Piccolo und mehr
Georg Pipps
Salzburg
Austria
6562-9722
PRINI
Princesa Isabel Vinhos
Isabel de Castro
Lisboa
Portugal
(1) 356-5634
QUEDE
Que Delícia
Bernardo Batista
Rio de Janeiro
Brazil
(21) 555-4252
QUEEN
Queen Cozinha
Lúcia Carvalho
São Paulo
Brazil
(11) 555-1189
QUICK
QUICK-Stop
Horst Kloss
Cunewalde
Germany
0372-035188
RANCH
Rancho grande
Sergio Gutiérrez
Buenos Aires
Argentina
(1) 123-5555
RATTC
Rattlesnake Canyon Grocery
Paula Wilson
Albuquerque
USA
(505) 555-5939
REGGC
Reggiani Caseifici
Maurizio Moroni
Reggio Emilia
Italy
0522-556721
RICAR
Ricardo Adocicados
Janete Limeira
Rio de Janeiro
Brazil
(21) 555-3412
RICSU
Richter Supermarkt
Michael Holz
Genève
Switzerland
0897-034214
ROMEY
Romero y tomillo
Alejandra Camino
Madrid
Spain
(91) 745 6200
SANTG
Santé Gourmet
Jonas Bergulfsen
Stavern
Norway
07-98 92 35
SAVEA
Save-a-lot Markets
Jose Pavarotti
Boise
USA
(208) 555-8097
SEVES
Seven Seas Imports
Hari Kumar
London
UK
(171) 555-1717
SIMOB
Simons bistro
Jytte Petersen
København
Denmark
31 12 34 56
SPECD
Spécialités du monde
Dominique Perrier
Paris
France
(1) 47.55.60.10
SPLIR
Split Rail Beer & Ale
Art Braunschweiger
Lander
USA
(307) 555-4680
SUPRD
Suprêmes délices
Pascale Cartrain
Charleroi
Belgium
(071) 23 67 22 20
THEBI
The Big Cheese
Liz Nixon
Portland
USA
(503) 555-3612
THECR
The Cracker Box
Liu Wong
Butte
USA
(406) 555-5834
TOMSP
Toms Spezialitäten
Karin Josephs
Münster
Germany
0251-031259
TORTU
Tortuga Restaurante
Miguel Angel Paolino
México D.F.
Mexico
(5) 555-2933
TRADH
Tradição Hipermercados
Anabela Domingues
São Paulo
Brazil
(11) 555-2167
TRAIH
Trail's Head Gourmet Provisioners
Helvetius Nagy
Kirkland
USA
(206) 555-8257
VAFFE
Vaffeljernet
Palle Ibsen
Ã…rhus
Denmark
86 21 32 43
VICTE
Victuailles en stock
Mary Saveley
Lyon
France
78.32.54.86
VINET
Vins et alcools Chevalier
Paul Henriot
Reims
France
26.47.15.10
WANDK
Die Wandernde Kuh
Rita Müller
Stuttgart
Germany
0711-020361
WARTH
Wartian Herkku
Pirkko Koskitalo
Oulu
Finland
981-443655
WELLI
Wellington Importadora
Paula Parente
Resende
Brazil
(14) 555-8122
WHITC
White Clover Markets
Karl Jablonski
Seattle
USA
(206) 555-4112
WILMK
Wilman Kala
Matti Karttunen
Helsinki
Finland
90-224 8858
WOLZA
Wolski Zajazd
Zbyszek Piestrzeniewicz
Warszawa
Poland
(26) 642-7012

Grouping

The CollectionView class supports grouping through the ICollectionView interface, which is identical to the one in .NET. To enable grouping, add one or more GroupDescription objects to the CollectionView.groupDescriptions property, and ensure that the grid's showGroups property is set to true when creating the grid instance(the default value is false.).

GroupDescription objects are flexible, allowing you to group data based on value or on grouping functions.

The example below groups the collection by the field which you select from the list. The grid shows not only the items content but also the group information: the group name and the average value of amount in the group. You can find the rendering codes for these in the method initTBody. The corresponding code snippet locates in line 116.

Notes: Selecting one item in the list will add a new instance of GroupDescription. If the groupdescription already exists, nothing happens. In order to clear the group setting, select the first item in the list.

<div class="row-fluid well"> <select id="groupingFieldNameList" class="form-control"></select> </div> @(Html.C1().FlexGrid().Id("groupingGrid").IsReadOnly(true).AllowSorting(true).AutoGenerateColumns(true) .Bind(b => b.DisableServerRead(true).Bind(Model.Products)) )
$(document).ready(function () { //Grouping // reference collectionview, grid, the select element and the names list. groupingGrid = wijmo.Control.getControl('#groupingGrid'); cvGrouping = groupingGrid.itemsSource; groupingFieldNameList = document.getElementById('groupingFieldNameList'); groupingFieldNameList.addEventListener('change', groupGrid); // initialize the list and listen to the list's change. groupingFieldNameList.innerHTML += ''; for (var i = 0; i < groupingNames.length; i++) { groupingFieldNameList.innerHTML += ''; } }); //Grouping // create collectionview, grid, the select element and the names list. var cvGrouping = null, groupingGrid = null, groupingFieldNameList = null, groupingNames = getFilterNames(); // update the group settings. function groupGrid() { var gd, fieldName = groupingFieldNameList.value; gd = cvGrouping.groupDescriptions; if (!fieldName) { // clear all the group settings. gd.splice(0, gd.length); return; } if (findGroup(fieldName) >= 0) { return; } if (fieldName === 'UnitPrice') { // when grouping by amount, use ranges instead of specific values gd.push(new wijmo.collections.PropertyGroupDescription(fieldName, function (item, propName) { var value = item[propName]; // UnitPrice if (value > 100) return 'Large Amounts'; if (value > 50) return 'Medium Amounts'; if (value > 0) return 'Small Amounts'; return 'Negative Amounts'; })); } else { // group by specific property values gd.push(new wijmo.collections.PropertyGroupDescription(fieldName)); } }; // check whether the group with the specified property name already exists. function findGroup(propName) { var gd = cvGrouping.groupDescriptions; for (var i = 0; i < gd.length; i++) { if (gd[i].propertyName === propName) { return i; } } return -1; };
using System.Web.Mvc; using CollectionView101.Models; using C1.Web.Mvc.Grid; using C1.Web.Mvc; using C1.Web.Mvc.Serialization; using System.Data.Entity.Validation; using System.Data.Entity; namespace CollectionView101.Controllers { public class HomeController : Controller { private C1NWindEntities db = new C1NWindEntities(); // GET: Home public ActionResult Index() { return View(db); } } }

Result (live):

Product ID
Product Name
Supplier ID
Category ID
Quantity Per Unit
Unit Price
Units In Stock
Units On Order
Reorder Level
Discontinued
1
Chai
1
1
10 boxes x 20 bags
18
39
0
10
2
Chang
1
1
24 - 12 oz bottles
19
17
40
25
3
Aniseed Syrup
1
2
12 - 550 ml bottles
10
13
70
25
4
Chef Anton's Cajun Seasoning
2
2
48 - 6 oz jars
22
53
0
0
5
Chef Anton's Gumbo Mix
2
2
36 boxes
21.35
0
0
0
6
Grandma's Boysenberry Spread
3
2
12 - 8 oz jars
25
120
0
25
7
Uncle Bob's Organic Dried Pears
3
7
12 - 1 lb pkgs.
30
15
0
10
8
Northwoods Cranberry Sauce
3
2
12 - 12 oz jars
40
6
0
0
9
Mishi Kobe Niku
4
6
18 - 500 g pkgs.
97
29
0
0
10
Ikura
4
8
12 - 200 ml jars
31
31
0
0
11
Queso Cabrales
5
4
1 kg pkg.
21
22
30
30
12
Queso Manchego La Pastora
5
4
10 - 500 g pkgs.
38
86
0
0
13
Konbu
6
8
2 kg box
6
24
0
5
14
Tofu
6
7
40 - 100 g pkgs.
23.25
35
0
0
15
Genen Shouyu
6
2
24 - 250 ml bottles
15.50
39
0
5
16
Pavlova
7
3
32 - 500 g boxes
17.45
29
0
10
17
Alice Mutton
7
6
20 - 1 kg tins
39
0
0
0
18
Carnarvon Tigers
7
8
16 kg pkg.
62.50
42
0
0
19
Teatime Chocolate Biscuits
8
3
10 boxes x 12 pieces
9.20
25
0
5
20
Sir Rodney's Marmalade
8
3
30 gift boxes
81
40
0
0
21
Sir Rodney's Scones
8
3
24 pkgs. x 4 pieces
10
3
40
5
22
Gustaf's Knäckebröd
9
5
24 - 500 g pkgs.
21
104
0
25
23
Tunnbröd
9
5
12 - 250 g pkgs.
9
61
0
25
24
Guaraná Fantástica
10
1
12 - 355 ml cans
4.50
20
0
0
25
NuNuCa Nuß-Nougat-Creme
11
3
20 - 450 g glasses
14
76
0
30
26
Gumbär Gummibärchen
11
3
100 - 250 g bags
31.23
15
0
0
27
Schoggi Schokolade
11
3
100 - 100 g pieces
43.90
49
0
30
28
Rössle Sauerkraut
12
7
25 - 825 g cans
45.60
26
0
0
29
Thüringer Rostbratwurst
12
6
50 bags x 30 sausgs.
123.79
0
0
0
30
Nord-Ost Matjeshering
13
8
10 - 200 g glasses
25.89
10
0
15
31
Gorgonzola Telino
14
4
12 - 100 g pkgs
12.50
0
70
20
32
Mascarpone Fabioli
14
4
24 - 200 g pkgs.
32
9
40
25
33
Geitost
15
4
500 g
2.50
112
0
20
34
Sasquatch Ale
16
1
24 - 12 oz bottles
14
111
0
15
35
Steeleye Stout
16
1
24 - 12 oz bottles
18
20
0
15
36
Inlagd Sill
17
8
24 - 250 g jars
19
112
0
20
37
Gravad lax
17
8
12 - 500 g pkgs.
26
11
50
25
38
Côte de Blaye
18
1
12 - 75 cl bottles
263.50
17
0
15
39
Chartreuse verte
18
1
750 cc per bottle
18
69
0
5
40
Boston Crab Meat
19
8
24 - 4 oz tins
18.40
123
0
30
41
Jack's New England Clam Chowder
19
8
12 - 12 oz cans
9.65
85
0
10
42
Singaporean Hokkien Fried Mee
20
5
32 - 1 kg pkgs.
14
26
0
0
43
Ipoh Coffee
20
1
16 - 500 g tins
46
17
10
25
44
Gula Malacca
20
2
20 - 2 kg bags
19.45
27
0
15
45
Røgede sild
21
8
1k pkg.
9.50
5
70
15
46
Spegesild
21
8
4 - 450 g glasses
12
95
0
0
47
Zaanse koeken
22
3
10 - 4 oz boxes
9.50
36
0
0
48
Chocolade
22
3
10 pkgs.
12.75
15
70
25
49
Maxilaku
23
3
24 - 50 g pkgs.
20
10
60
15
50
Valkoinen suklaa
23
3
12 - 100 g bars
16.25
65
0
30
51
Manjimup Dried Apples
24
7
50 - 300 g pkgs.
53
20
0
10
52
Filo Mix
24
5
16 - 2 kg boxes
7
38
0
25
53
Perth Pasties
24
6
48 pieces
32.80
0
0
0
54
Tourtière
25
6
16 pies
7.45
21
0
10
55
Pâté chinois
25
6
24 boxes x 2 pies
24
115
0
20
56
Gnocchi di nonna Alice
26
5
24 - 250 g pkgs.
38
21
10
30
57
Ravioli Angelo
26
5
24 - 250 g pkgs.
19.50
36
0
20
58
Escargots de Bourgogne
27
8
24 pieces
13.25
62
0
20
59
Raclette Courdavault
28
4
5 kg pkg.
55
79
0
0
60
Camembert Pierrot
28
4
15 - 300 g rounds
34
19
0
0
61
Sirop d'érable
29
2
24 - 500 ml bottles
28.50
113
0
25
62
Tarte au sucre
29
3
48 pies
49.30
17
0
0
63
Vegie-spread
7
2
15 - 625 g jars
43.90
24
0
5
64
Wimmers gute Semmelknödel
12
5
20 bags x 4 pieces
33.25
22
80
30
65
Louisiana Fiery Hot Pepper Sauce
2
2
32 - 8 oz bottles
21.05
76
0
0
66
Louisiana Hot Spiced Okra
2
2
24 - 8 oz jars
17
4
100
20
67
Laughing Lumberjack Lager
16
1
24 - 12 oz bottles
14
52
0
10
68
Scottish Longbreads
8
3
10 boxes x 8 pieces
12.50
6
10
15
69
Gudbrandsdalsost
15
4
10 kg pkg.
36
26
0
15
70
Outback Lager
7
1
24 - 355 ml bottles
15
15
10
30
71
Fløtemysost
15
4
10 - 500 g pkgs.
21.50
26
0
0
72
Mozzarella di Giovanni
14
4
24 - 200 g pkgs.
34.80
14
0
0
73
Röd Kaviar
17
8
24 - 150 g jars
15
101
0
5
74
Longlife Tofu
4
7
5 kg pkg.
10
4
20
5
75
Rhönbräu Klosterbier
12
1
24 - 0.5 l bottles
7.75
125
0
25
76
Lakkalikööri
23
1
500 ml
18
57
0
20
77
Original Frankfurter grüne Soße
12
2
12 boxes
13
32
0
15

Tracking changes

The CollectionView class can keep track of changes made to the data. It is useful in situations where you must submit changes to the server. To turn on change tracking, set the trackChanges property to true. Once you do that, the CollectionView keeps track of any changes made to the data and exposes them in three arrays:

This feature is demonstrated below using a FlexGrid. The grid is bound to a CollectionView with trackChanges set to true.

<h5>Change the data here</h5> @(Html.C1().FlexGrid().Id("tcMainGrid").AutoGenerateColumns(false) .AllowAddNew(true).AllowDelete(true) .Columns(columns => columns .Add(c => c.Binding("CategoryID")) .Add(c => c.Binding("CategoryName")) .Add(c => c.Binding("Description").Width("*"))) .Bind(ib => ib.Bind(Model.Categories).DisableServerRead(true) ) ) <h5>See the changes here</h5> <h6>Items edited:</h6> @(Html.C1().FlexGrid().Id("tcEditedGrid").AutoGenerateColumns(false) .IsReadOnly(true).Height(100) .Columns(columns => columns .Add(c => c.Binding("CategoryID").IsReadOnly(true)) .Add(c => c.Binding("CategoryName")) .Add(c => c.Binding("Description").Width("*"))) ) <h6>Items added:</h6> @(Html.C1().FlexGrid().Id("tcAddedGrid").AutoGenerateColumns(false) .IsReadOnly(true).Height(100) .Columns(columns => columns .Add(c => c.Binding("CategoryID").IsReadOnly(true)) .Add(c => c.Binding("CategoryName")) .Add(c => c.Binding("Description").Width("*"))) ) <h6>Items removed:</h6> @(Html.C1().FlexGrid().Id("tcRemovedGrid").AutoGenerateColumns(false) .IsReadOnly(true).Height(100) .Columns(columns => columns .Add(c => c.Binding("CategoryID").IsReadOnly(true)) .Add(c => c.Binding("CategoryName")) .Add(c => c.Binding("Description").Width("*"))) )
$(document).ready(function () { //Tracking changes tcMainGrid = wijmo.Control.getControl('#tcMainGrid');// the flexGrid to edit the data tcEditedGrid = wijmo.Control.getControl('#tcEditedGrid'); // the flexGrid to record the edited items tcAddedGrid = wijmo.Control.getControl('#tcAddedGrid'); // the flexGrid to record the added items tcRemovedGrid = wijmo.Control.getControl('#tcRemovedGrid'); // the flexGrid to record the removed items cvTrackingChanges = tcMainGrid.itemsSource; tcEditedGrid.itemsSource = cvTrackingChanges.itemsEdited; tcAddedGrid.itemsSource = cvTrackingChanges.itemsAdded; tcRemovedGrid.itemsSource = cvTrackingChanges.itemsRemoved; // track changes of the collectionview cvTrackingChanges.trackChanges = true; }); //Tracking changes var tcMainGrid = null, tcEditedGrid = null, tcAddedGrid = null, tcRemovedGrid = null, cvTrackingChanges = null;
using System.Web.Mvc; using CollectionView101.Models; using C1.Web.Mvc.Grid; using C1.Web.Mvc; using C1.Web.Mvc.Serialization; using System.Data.Entity.Validation; using System.Data.Entity; namespace CollectionView101.Controllers { public class HomeController : Controller { private C1NWindEntities db = new C1NWindEntities(); // GET: Home public ActionResult Index() { return View(db); } } }

Result (live):

Change the data here
CategoryID
CategoryName
Description
1
Beveragess
Soft drinks, coffees, teas, beers, and ales
2
Condiments
Sweet and savory sauces, relishes, spreads, and seasonings
3
Confections
Desserts, candies, and sweet breads
4
Dairy Products
Cheeses
5
Grains/Cereals
Breads, crackers, pasta, and cereal
7
Produce
n b
10
dgr
tgrtg
11
wrtg
tg
12
hbhjbhjb
dghkdghmfd
13
534djdfgjfgj
fjfgajajsdg
14
dfgjdfjdfjg
dfjfskfsdkdfhkdf
See the changes here
Items edited:
CategoryID
CategoryName
Description
Items added:
CategoryID
CategoryName
Description
Items removed:
CategoryID
CategoryName
Description