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.NETCore.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.Mvc().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.Mvc() .Controller("DataGridEmployeesByState") .LoadAction("Get") .InsertAction("Post") .UpdateAction("Put") .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.NETCore.Demos.Models; using DevExtreme.NETCore.Demos.Models.DataGrid; using DevExtreme.NETCore.Demos.Models.SampleData; using Microsoft.AspNetCore.Mvc; using System.Linq; namespace DevExtreme.NETCore.Demos.Controllers { public class DataGridController : Controller { public ActionResult CascadingLookups() { return View(); } } }
using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using DevExtreme.NETCore.Demos.Models.SampleData; using Microsoft.AspNetCore.Mvc; using System.Net.Http; namespace DevExtreme.NETCore.Demos.Controllers.ApiControllers { [Route("api/[controller]/[action]")] public class DataGridCitiesByStateController : Controller { [HttpGet] public object Get(DataSourceLoadOptions loadOptions) { return DataSourceLoader.Load(SampleData.CitiesByState, loadOptions); } } }
using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc; using DevExtreme.NETCore.Demos.Models.DataGrid; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.Memory; using DevExtreme.AspNet.Mvc; using DevExpress.Utils.Serializing.Helpers; using DevExtreme.AspNet.Data; namespace DevExtreme.NETCore.Demos.Controllers.ApiControllers { [Route("api/[controller]/[action]")] public class DataGridEmployeesByStateController : Controller { InMemoryEmployeesByStateDataContext _data; public DataGridEmployeesByStateController(IHttpContextAccessor httpContextAccessor, IMemoryCache memoryCache) { _data = new InMemoryEmployeesByStateDataContext(httpContextAccessor, memoryCache); } [HttpGet] public object Get(DataSourceLoadOptions loadOptions) { return DataSourceLoader.Load(_data.EmployeesByState, loadOptions); } [HttpPost] public IActionResult Post(string values) { var newEmployee = new EmployeeByState(); JsonPopulateObjectExtensions.PopulateObject(values, newEmployee); if(!TryValidateModel(newEmployee)) return BadRequest(ModelState.GetFullErrorMessage()); _data.EmployeesByState.Add(newEmployee); _data.SaveChanges(); return Ok(); } [HttpPut] public IActionResult Put(int key, string values) { var employee = _data.EmployeesByState.First(a => a.ID == key); JsonPopulateObjectExtensions.PopulateObject(values, employee); if(!TryValidateModel(employee)) return BadRequest(ModelState.GetFullErrorMessage()); _data.SaveChanges(); return Ok(); } [HttpDelete] public void Delete(int key) { var employee = _data.EmployeesByState.First(a => a.ID == key); _data.EmployeesByState.Remove(employee); _data.SaveChanges(); } } }
using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using DevExtreme.NETCore.Demos.Models.SampleData; using Microsoft.AspNetCore.Mvc; using System; using System.Linq; namespace DevExtreme.NETCore.Demos.Controllers.ApiControllers { [Route("api/[controller]/[action]")] public class DataGridStatesWithCitiesController : Controller { [HttpGet] public object Get(DataSourceLoadOptions loadOptions) { return DataSourceLoader.Load(SampleData.StatesWithCities, loadOptions); } } }
using System; using System.Collections.Generic; using System.Linq; namespace DevExtreme.NETCore.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.Linq; namespace DevExtreme.NETCore.Demos.Models { public class CityByState { public string Name { get; set; } public int ID { get; set; } public int StateID { get; set; } } }
using System; using System.Collections.Generic; using System.Linq; using DevExtreme.NETCore.Demos.Models.DataGrid; namespace DevExtreme.NETCore.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; using System.Linq; namespace DevExtreme.NETCore.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 Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Generic; namespace DevExtreme.NETCore.Demos.Models.DataGrid { public class InMemoryEmployeesByStateDataContext : InMemoryDataContext<EmployeeByState> { public InMemoryEmployeesByStateDataContext(IHttpContextAccessor contextAccessor, IMemoryCache memoryCache) : base(contextAccessor, memoryCache) { } 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; namespace DevExtreme.NETCore.Demos.Models { public class State { public int ID { get; set; } public string Name { get; set; } } }
using System; using System.Collections.Generic; using System.Linq; namespace DevExtreme.NETCore.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.