Nested GridPanels

  1. #1

    Nested GridPanels

    I am trying to do nested GridPanels but don't have any success binding the inner GridPanel to the outer GridPanel's record. Basically, I want to bind AddressGrid's datasource to CustomerGrid's Addresses list.

    Any ideas how to do in BeforeExpand listener event?


    Model
        public class CustomerViewModel
        {
            [Required]
            public int ID { get; set; }
            public string id { get; set; }
            [Required]
            public string Name { get; set; }
            public string CompanyName { get; set; }
            public IList<AddressViewModel> Addresses { get; set; }
    
            public CustomerViewModel()
            {
                Addresses = new List<AddressViewModel>();
            }
        }
    
        public class AddressViewModel
        {
            public string CountryID { get { return this.Country.ID; } }
    
            public string City { get; set; }
            public string Zip { get; set; }
            public CountryViewModel Country { get; set; }
            public string Street { get; set; }
        }
    
        public class CountryViewModel
        {
            public string ID { get; set; }
            public string Value { get; set; }
        }
    Controller
            public ActionResult DisplayNestedGrid()
            {
                List<CustomerViewModel> customers = new List<CustomerViewModel>();
                customers.Add(GenerateDummyCustomer());
                customers.Add(GenerateDummyCustomer2());
    
                return View(customers);
            }
    
            private CustomerViewModel GenerateDummyCustomer()
            {
                CustomerViewModel customer = new CustomerViewModel();
    
                customer.ID = 1;
                customer.Name = "Jason";
                customer.CompanyName = "ABC Company Pte Ltd";
    
                customer.Addresses.Add(new AddressViewModel() { Country = new CountryViewModel() { ID = "1", Value = "Singapore" }, City = "Singapore", Street = "Test Street" });
                customer.Addresses.Add(new AddressViewModel() { Country = new CountryViewModel() { ID = "2", Value = "Malaysia" }, City = "Kuala Lumpur" });
                customer.Addresses.Add(new AddressViewModel() { Country = new CountryViewModel() { ID = "3", Value = "Indonesia" }, City = "Jakarta" });
                customer.Addresses.Add(new AddressViewModel() { Country = new CountryViewModel() { ID = "4", Value = "Thailand" }, City = "Bangkok" });
    
                return customer;
            }
    
            private CustomerViewModel GenerateDummyCustomer2()
            {
                CustomerViewModel customer = new CustomerViewModel();
    
                customer.ID = 2;
                customer.Name = "Nosaj";
                customer.CompanyName = "CBA Company Pte Ltd";
    
                customer.Addresses.Add(new AddressViewModel() { Country = new CountryViewModel() { ID = "1", Value = "Indonesia" }, City = "Jakarta", Street = "Jakarta Street" });
                customer.Addresses.Add(new AddressViewModel() { Country = new CountryViewModel() { ID = "2", Value = "Malaysia" }, City = "Kuala Lumpur" });
                customer.Addresses.Add(new AddressViewModel() { Country = new CountryViewModel() { ID = "3", Value = "Thailand" }, City = "Bangkok", Street = "Bangkok Street" });
    
                return customer;
            }
    View
    @(
        Html.X().Store()
            .ID("CustomerStore")
            .Data(Model)
            .Model(
                Html.X().Model()
                    .Name("User")
                    .IDProperty("CustomerID")
                    .Fields(
                        Html.X().ModelField().Name("CustomerID"),
                        Html.X().ModelField().Name("Name"),
                        Html.X().ModelField().Name("CompanyName")
                    )
                    .Associations(a => a.Add(Html.X().HasManyAssociation()
                        .Model("Address")
                        .Name("addresses")
                        .AssociationKey("Addresses")
                    ))
            )
    )
    
    @(
        Html.X().Model()
            .Name("Address")
            .Fields(
                Html.X().ModelField().Name("City"),
                Html.X().ModelField().Name("Zip"),
                Html.X().ModelField().Name("CountryID").Mapping("Country.ID"),
                Html.X().ModelField().Name("CountryName").Mapping("Country.Value"),
                Html.X().ModelField().Name("Street")
            )
    )
    
    @(
        Html.X().GridPanel()
            .ID("CustomerGrid")
            .StoreID("CustomerStore")
            .Height(600)
            .ColumnModel(
                Html.X().Column().Text("Customer ID").DataIndex("CustomerID"),
                Html.X().Column().Text("Name").DataIndex("Name").Width(300),
                Html.X().Column().Text("Company Name").DataIndex("CompanyName").Flex(1)
            )
            .Plugins(
                Html.X().RowExpander()
                    .SingleExpand(false)
                    .Component(
                        Html.X().GridPanel()
                            .ID("AddressGrid")
                            .ColumnModel(
                                Html.X().Column().Text("Country").DataIndex("CountryName"),
                                Html.X().Column().Text("Street").DataIndex("Street"),
                                Html.X().Column().Text("City").DataIndex("City"),
                                Html.X().Column().Text("Zip").DataIndex("Zip")
                            )
                    )
                    .Listeners(l => { l.BeforeExpand.Handler = "console.log(record);"; } )
            )
    )
  2. #2
    Hi @jasneo,

    Maybe, you are looking for Associations.
    https://examples3.ext.net/#/Associations/HasMany/Simple

    Though, you could achieve it without Associations. You can load the data to an inner GridPanel:
    innerGrid.getStore().loadData(data);
  3. #3
    Hi @Daniil,

    Yes that's what I am looking for. But how to reference to AddressGrid from RowExpander's Expand handler?

        .Listeners(l => { l.Expand.Handler = "#{AddressGrid}.bindStore(record.addresses());"; })
    This line doesn't work.
  4. #4
    You cannot use #{AddressGrid} because there is a SingleExpand="false" setting. In this case a RowExpander's Component is used just as a template, a control's ID is ignored. Because a new component is rendered for each row and ids have to be unique.

    In a RowExpander's Expand Handler you can use:
    var innerGrid = this.getComponent(record);
    By the way, do you not want to use the inner GridPanel's ViewReady listener as it is demonstrate in the example?

Similar Threads

  1. [CLOSED] Nested GridPanels issues
    By lasalle in forum 2.x Help
    Replies: 2
    Last Post: Nov 13, 2013, 9:05 PM
  2. Replies: 6
    Last Post: Oct 15, 2012, 6:20 AM
  3. [CLOSED] Nested data in nested grids
    By FAS in forum 1.x Legacy Premium Help
    Replies: 16
    Last Post: Apr 19, 2012, 7:51 PM
  4. BUG - tabPanel with 2 gridpanels
    By RPIRES in forum 1.x Help
    Replies: 0
    Last Post: Jul 01, 2010, 6:15 PM
  5. Nested GridPanels?
    By Tbaseflug in forum 1.x Help
    Replies: 1
    Last Post: Jul 06, 2009, 1:48 PM

Posting Permissions