Your search did not match any results.

Data Grid - Cascading Lookups

You can assign a lookup editor to a column. This editor displays a drop-down list populated with values from the specified data source. Users can filter the drop-down list to quickly locate required values.

Backend API
<div id="data-grid-demo"> @(Html.DevExtreme().DataGrid<DevExtreme.MVC.Demos.Models.DataGrid.EmployeeByState>() .ID("gridContainer") .ShowBorders(true) .Editing(editing => { editing.Mode(GridEditMode.Row); editing.AllowUpdating(true); editing.AllowAdding(true); }) .OnEditorPreparing("onEditorPreparing") .Columns(columns => { columns.AddFor(m => m.FirstName); columns.AddFor(m => m.LastName); columns.AddFor(m => m.Position); columns.AddFor(m => m.StateID) .SetCellValue("setStateValue") .Lookup(lookup => lookup .DataSource(d => d.WebApi() .Controller("DataGridStatesWithCities") .LoadAction("Get") .Key("ID")) .DisplayExpr("Name") .ValueExpr("ID") ); columns.AddFor(m => m.CityID) .Lookup(lookup => lookup .DataSource("getCities") .DisplayExpr("Name") .ValueExpr("ID") ); }) .DataSource(d => d.WebApi() .Controller("DataGridEmployeesByState") .InsertAction(true) .UpdateAction(true) .Key("ID") ) ) </div> <script> function onEditorPreparing(e) { if(e.parentType === "dataRow" && e.dataField === "CityID") { e.editorOptions.disabled = (typeof e.row.data.StateID !== "number"); } } function getCities(options) { return { store: DevExpress.data.AspNet.createStore({ key: "ID", loadUrl: '@Url.Action("Get", "DataGridCitiesByState", new { httproute = true })' }), filter: options.data ? ["StateID", "=", options.data.StateID] : null }; } function setStateValue(rowData, value) { rowData.StateID = value; rowData.CityID = null; } </script>
using DevExtreme.MVC.Demos.Models; using DevExtreme.MVC.Demos.Models.DataGrid; using DevExtreme.MVC.Demos.Models.SampleData; using System; using System.Linq; using System.Web.Mvc; namespace DevExtreme.MVC.Demos.Controllers { public class DataGridController : Controller { public ActionResult CascadingLookups() { return View(); } } }
using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using DevExtreme.MVC.Demos.Models.SampleData; using System; using System.Linq; using System.Net.Http; using System.Web.Http; namespace DevExtreme.MVC.Demos.Controllers.ApiControllers { public class DataGridCitiesByStateController : ApiController { [HttpGet] public HttpResponseMessage Get(DataSourceLoadOptions loadOptions) { return Request.CreateResponse(DataSourceLoader.Load(SampleData.CitiesByState, loadOptions)); } } }
using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using DevExtreme.MVC.Demos.Models.DataGrid; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Formatting; using System.Web.Http; namespace DevExtreme.MVC.Demos.Controllers.ApiControllers { public class DataGridEmployeesByStateController : ApiController { InMemoryEmployeesByStateDataContext db = new InMemoryEmployeesByStateDataContext(); [HttpGet] public HttpResponseMessage Get(DataSourceLoadOptions loadOptions) { return Request.CreateResponse(DataSourceLoader.Load(db.EmployeesByState, loadOptions)); } [HttpPost] public HttpResponseMessage Post(FormDataCollection form) { var values = form.Get("values"); var newEmployee = new EmployeeByState(); JsonConvert.PopulateObject(values, newEmployee); Validate(newEmployee); if(!ModelState.IsValid) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState.GetFullErrorMessage()); db.EmployeesByState.Add(newEmployee); db.SaveChanges(); return Request.CreateResponse(HttpStatusCode.Created); } [HttpPut] public HttpResponseMessage Put(FormDataCollection form) { var key = Convert.ToInt32(form.Get("key")); var values = form.Get("values"); var employee = db.EmployeesByState.First(e => e.ID == key); JsonConvert.PopulateObject(values, employee); Validate(employee); if(!ModelState.IsValid) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState.GetFullErrorMessage()); db.SaveChanges(); return Request.CreateResponse(HttpStatusCode.OK); } [HttpDelete] public void Delete(FormDataCollection form) { var key = Convert.ToInt32(form.Get("key")); var employee = db.EmployeesByState.First(e => e.ID == key); db.EmployeesByState.Remove(employee); db.SaveChanges(); } } }
using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using DevExtreme.MVC.Demos.Models.SampleData; using System; using System.Linq; using System.Net.Http; using System.Web.Http; namespace DevExtreme.MVC.Demos.Controllers.ApiControllers { public class DataGridStatesWithCitiesController : ApiController { [HttpGet] public HttpResponseMessage Get(DataSourceLoadOptions loadOptions) { return Request.CreateResponse(DataSourceLoader.Load(SampleData.StatesWithCities, loadOptions)); } } }
using System; using System.Collections.Generic; namespace DevExtreme.MVC.Demos.Models.SampleData { public partial class SampleData { public static readonly IEnumerable<CityByState> CitiesByState = new[] { new CityByState { ID = 1, Name = "Tuscaloosa", StateID = 1 }, new CityByState { ID = 2, Name = "Hoover", StateID = 1 }, new CityByState { ID = 3, Name = "Dothan", StateID = 1 }, new CityByState { ID = 4, Name = "Decatur", StateID = 1 }, new CityByState { ID = 5, Name = "Anchorage", StateID = 2 }, new CityByState { ID = 6, Name = "Fairbanks", StateID = 2 }, new CityByState { ID = 7, Name = "Juneau", StateID = 2 }, new CityByState { ID = 8, Name = "Avondale", StateID = 3 }, new CityByState { ID = 9, Name = "Buckeye", StateID = 3 }, new CityByState { ID = 10, Name = "Carefree", StateID = 3 }, new CityByState { ID = 11, Name = "Springdale", StateID = 4 }, new CityByState { ID = 12, Name = "Rogers", StateID = 4 }, new CityByState { ID = 13, Name = "Sherwood", StateID = 4 }, new CityByState { ID = 14, Name = "Jacksonville", StateID = 4 }, new CityByState { ID = 15, Name = "Cabot", StateID = 4 }, new CityByState { ID = 16, Name = "Adelanto", StateID = 5 }, new CityByState { ID = 17, Name = "Glendale", StateID = 5 }, new CityByState { ID = 18, Name = "Moorpark", StateID = 5 }, new CityByState { ID = 19, Name = "Needles", StateID = 5 }, new CityByState { ID = 20, Name = "Ontario", StateID = 5 } }; } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace DevExtreme.MVC.Demos.Models { public class CityByState { public string Name { get; set; } public int ID { get; set; } public int StateID { get; set; } } }
using DevExtreme.MVC.Demos.Models.DataGrid; using System; using System.Collections.Generic; namespace DevExtreme.MVC.Demos.Models.SampleData { public partial class SampleData { public static readonly IEnumerable<EmployeeByState> DataGridEmployeesByState = new[] { new EmployeeByState { ID = 1, FirstName = "John", LastName = "Heart", Prefix = "Mr.", Position = "CTO", StateID = 5, CityID = 17 }, new EmployeeByState { ID = 2, FirstName = "Olivia", LastName = "Peyton", Prefix = "Mrs.", Position = "HR Manager", StateID = 5, CityID = 17 }, new EmployeeByState { ID = 3, FirstName = "Robert", LastName = "Reagan", Prefix = "Mr.", Position = "IT Manager", StateID = 4, CityID = 14 }, new EmployeeByState { ID = 4, FirstName = "Greta", LastName = "Sims", Prefix = "Ms.", Position = "Shipping Manager", StateID = 3, CityID = 8 }, new EmployeeByState { ID = 5, FirstName = "Brett", LastName = "Wade", Prefix = "Mr.", Position = "Shipping Manager", StateID = 3, CityID = 9 }, new EmployeeByState { ID = 6, FirstName = "Sandra", LastName = "Johnson", Prefix = "Mrs.", Position = "Network Admin", StateID = 2, CityID = 6 }, new EmployeeByState { ID = 7, FirstName = "Kevin", LastName = "Carter", Prefix = "Mr.", Position = "Network Admin", StateID = 1, CityID = 3 }, new EmployeeByState { ID = 8, FirstName = "Cynthia", LastName = "Stanwick", Prefix = "Ms.", Position = "Sales Assistant", StateID = 1, CityID = 3 }, new EmployeeByState { ID = 9, FirstName = "Kent", LastName = "Samuelson", Prefix = "Dr.", Position = "Sales Assistant", StateID = 1, CityID = 2 }, new EmployeeByState { ID = 10, FirstName = "Taylor", LastName = "Riley", Prefix = "Mr.", Position = "Support Assistant", StateID = 5, CityID = 17 }, new EmployeeByState { ID = 11, FirstName = "Sam", LastName = "Hill", Prefix = "Mr.", Position = "Sales Assistant", StateID = 2, CityID = 5 }, new EmployeeByState { ID = 12, FirstName = "Kelly", LastName = "Rodriguez", Prefix = "Ms.", Position = "Sales Assistant", StateID = 5, CityID = 17 }, new EmployeeByState { ID = 13, FirstName = "Natalie", LastName = "Maguirre", Prefix = "Mrs.", Position = "Sales Assistant", StateID = 4, CityID = 14 }, new EmployeeByState { ID = 14, FirstName = "Walter", LastName = "Hobbs", Prefix = "Mr.", Position = "Support Assistant", StateID = 2, CityID = 5 } }; } }
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace DevExtreme.MVC.Demos.Models.DataGrid { public class EmployeeByState { public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Position { get; set; } public string Prefix { get; set; } [Display(Name = "State")] public int? StateID { get; set; } [Display(Name = "City")] public int? CityID { get; set; } } }
using System; using System.Collections.Generic; namespace DevExtreme.MVC.Demos.Models.DataGrid { public class InMemoryEmployeesByStateDataContext : InMemoryDataContext<EmployeeByState> { public ICollection<EmployeeByState> EmployeesByState => ItemsInternal; protected override IEnumerable<EmployeeByState> Source => SampleData.SampleData.DataGridEmployeesByState; protected override int GetKey(EmployeeByState item) => item.ID; protected override void SetKey(EmployeeByState item, int key) => item.ID = key; } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace DevExtreme.MVC.Demos.Models { public class State { public int ID { get; set; } public string Name { get; set; } } }
using System; using System.Collections.Generic; namespace DevExtreme.MVC.Demos.Models.SampleData { public partial class SampleData { public static readonly IEnumerable<State> StatesWithCities = new[] { new State { ID = 1, Name = "Alabama" }, new State { ID = 2, Name = "Alaska" }, new State { ID = 3, Name = "Arizona" }, new State { ID = 4, Name = "Arkansas" }, new State { ID = 5, Name = "California" } }; } }

This demo shows how to implement cascading lookups:

  1. Configure the primary lookup
    A column's lookup is configured in the lookup object. Assign an array of items to the lookup's dataSource. Then specify the valueExpr and displayExpr properties if the data source contains objects. (See the StateID column.)

  2. Configure the secondary lookup
    The secondary lookup has a similar configuration, but its dataSource should be a function so that you can dynamically filter the lookup. (See step 3.)

  3. Connect the lookups
    To filter the secondary lookup's items based on the primary lookup's value, specify the filter property in the secondary lookup's dataSource. (See the CityID column).

  4. Reset the secondary lookup when the primary lookup's value is changed
    Use the setCellValue function as shown in the StateID column's configuration.

  5. Disable the secondary lookup until the primary lookup's value is set
    Use the onEditorPreparing handler for this.

After you configure lookups, enable edit operations. Specify the required editing.mode and set the editing object's allowUpdating, allowAdding, and allowDeleting properties to true.