[CLOSED] Nested Grid ListFilter w/Dynamic Store

  1. #1

    [CLOSED] Nested Grid ListFilter w/Dynamic Store

    Hello,
    This is a continuation of another thread Nested Grid w/Remote Filter that you helped with. What I want to explore next is the possibility of having a ListFilter on the 2nd level grid and the Store for each grid dynamically loaded with different data depending on which row is selected.

    Implementing the same method from previous post to load the Store with a PageProxy and DirectFn doesn't work since the Store is not defined with the ListFilter, only referenced by ID and defined elsewhere. The code below uses this method and the filter store is loaded once on intial Grid load.

    Based on this previous post Update GridFilters ListFilter Store Server-Side it looks like it might be possible to update the menu items, but it references the elements by ID and I have SingleExpand="false" on my RowExpander so ID is ignored. This post also mentions that ListFilter isn't dynamic?

    So based on my limited knowledge I'm leaning towards this not being possible, but I want to ask the experts. Let me know what you think.
    Thanks
    JW

    <%@ Page Language="C#" %>
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            Store1.Data = this.Users;
        }
        public List<User> Users
        {
            get
            {
                return new List<User> 
                { 
                    new User(1, "User1", new List<Product>{
                        new Product(1, "Product1 of User1", "A"),
                        new Product(2, "Product2 of User1", "B"),
                        new Product(3, "Product3 of User1", "C")
                    }),
                    new User(2, "User2", new List<Product>{
                        new Product(4, "Product1 of User2", "L"),
                        new Product(5, "Product2 of User2", "M"),
                        new Product(6, "Product3 of User2", "N")
                    }),
                    new User(3, "User3", new List<Product>{
                        new Product(7, "Product1 of User3", "X"),
                        new Product(8, "Product2 of User3", "Y"),
                        new Product(9, "Product3 of User3", "Z")
                    })
                };
            }
        }
        public class Product
        {
            public Product(int id, string name, string type)
            {
                this.Id = id;
                this.Name = name;
                this.Type = type;
            }
            public int Id
            {
                get;
                private set;
            }
            public string Name
            {
                get;
                private set;
            }
            public string Type
            {
                get;
                private set;
            }
        }
        public class User
        {
            public User(int id, string name, List<Product> products)
            {
                this.Id = id;
                this.Name = name;
                this.Products = products;
            }
            public int Id
            {
                get;
                private set;
            }
            public string Name
            {
                get;
                private set;
            }
            public List<Product> Products
            {
                get;
                private set;
            }
        }
        [DirectMethod]
        public object Store2_Load(string action, Dictionary<string, object> extraParams)
        {
    
            if (extraParams.ContainsKey("filter"))
            {
                string filt = extraParams["filter"].ToString();
                FilterConditions fc = new FilterConditions(filt);
            }
            int Id = Convert.ToInt32(extraParams["proxyParm"]);
            return this.Users[Id - 1].Products;
        }
        [DirectMethod]
        public object filter_Load(string action, Dictionary<string, object> extraParams)
        {
            List<object> fltType = new List<object>();
            if (extraParams["row"].ToString().Equals("0"))
            {
                fltType.Add(new { Type = "A" });
                fltType.Add(new { Type = "B" });
                fltType.Add(new { Type = "C" });
            }
            else
            {
                fltType.Add(new { Type = "X" });
                fltType.Add(new { Type = "Y" });
                fltType.Add(new { Type = "Z" });
            }
            return fltType;
        }
    </script>
    <!DOCTYPE html>
    <html>
    <head id="Head1" runat="server">
        <title>Simple HasMany Association - Ext.NET Examples</title>
    </head>
    <body>
        <ext:ResourceManager ID="ResourceManager1" runat="server" />
        <h1>Simple HasMany Association</h1>
        <ext:Model ID="Model1" runat="server" Name="Product" IDProperty="Id">
            <Fields>
                <ext:ModelField Name="Id" Type="Int" />
                <ext:ModelField Name="Name" Type="String" />
                <ext:ModelField Name="Type" Type="String" />
            </Fields>        
        </ext:Model>
        <ext:Store ID="Store1" runat="server">
            <Model>
                <ext:Model ID="Model2" runat="server" Name="User" IDProperty="Id">
                    <Fields>
                        <ext:ModelField Name="Id" Type="Int" />
                        <ext:ModelField Name="Name" Type="String" />
                    </Fields>        
                    <Associations>
                        <ext:HasManyAssociation Model="Product" Name="products" AssociationKey="Products"/>
                    </Associations>
                </ext:Model>
            </Model>
        </ext:Store>
        <ext:Store ID="listStore" runat="server">
            <Proxy>
                <ext:PageProxy DirectFn="App.direct.filter_Load">
                    <ExtraParams>
                        <ext:Parameter Name="row" Value="0" Mode="Value"></ext:Parameter>
                    </ExtraParams>
                </ext:PageProxy>
            </Proxy>
            <Model>
                <ext:Model ID="Model3" runat="server">
                    <Fields>
                        <ext:ModelField Name="Type" Type="String"></ext:ModelField>
                    </Fields>
                </ext:Model>
            </Model>
        </ext:Store>
        <ext:GridPanel ID="GridPanel2" 
            runat="server" 
            StoreID="Store1"
            Title="Users with RowExpander" 
            Width="500" 
            Height="450">                
            <ColumnModel>
                <Columns>
                    <ext:Column ID="Column3" runat="server" Text="Name" DataIndex="Name" Flex="1" />
                </Columns>            
            </ColumnModel>
            <Plugins>
                <ext:RowExpander ID="RowExpander1" runat="server" SingleExpand="false">
                    <Component>
                        <ext:GridPanel runat="server" Title="Products">
                            <Store>
                                <ext:Store ID="Store2" runat="server" ModelName="Product" RemoteFilter="true">
                                    <Proxy>
                                        <ext:PageProxy DirectFn="App.direct.Store2_Load">
                                            <ExtraParams>
                                                <ext:Parameter Name="proxyParm" Value="this.record.data.Id" Mode="Raw"></ext:Parameter>
                                            </ExtraParams>
                                        </ext:PageProxy>
                                    </Proxy>
                                </ext:Store>
                            </Store>
                            <ColumnModel>
                                <Columns>
                                    <ext:Column ID="Column4" runat="server" Text="Name" DataIndex="Name" Flex="3"></ext:Column>
                                    <ext:Column ID="Column5" runat="server" Text="Type" DataIndex="Type" Flex="1"></ext:Column>
                                </Columns>            
                            </ColumnModel>
                            <Features>
                                <ext:GridFilters runat="server" Local="false">
                                    <Filters>
                                        <ext:ListFilter DataIndex="Type" StoreID="listStore" LabelField="Type" IDField="Type"></ext:ListFilter>
                                        <ext:StringFilter DataIndex="Name"></ext:StringFilter>
                                    </Filters>
                                </ext:GridFilters>
                            </Features>
                        </ext:GridPanel>
                    </Component>
                </ext:RowExpander>
            </Plugins>           
        </ext:GridPanel>
    </body>
    </html>
    Last edited by Daniil; Sep 27, 2014 at 7:24 AM. Reason: [CLOSED]
  2. #2
    Hi @jwhitmire36,

    I can suggest the following solution. It makes a ListFilter to auto populate its items.

    1. Please add this script into the page's head.
    Ext.ux.grid.menu.ListMenu.override({
        constructor: function (cfg) {
            var me = this,
                options,
                i,
                len,
                value;
    
            me.selected = [];
            me.addEvents('checkchange');
    
            Ext.ux.grid.menu.ListMenu.superclass.constructor.apply(this, arguments);
    
            if (me.autoOptions) {
                me.labelField = me.idField;
                me.store = Ext.create("Ext.data.ArrayStore", {
                    autoLoad: false,
                    fields: [me.idField]
                });
    
                me.grid.store.on("load", function (gridStore, records) {
                    var options = gridStore.collect(me.dataIndex, false, true),
                        data = [];
    
                    Ext.Array.each(options, function (option) {
                        data.push([option]);
                    });
    
                    this.store.loadData(data);
                    this.onLoad(this.store, this.store.getRange());
                    this.grid.store.on("filterchange", this.updateDisabled, this, { buffer: 100 });
                }, me, { single: true });
    
                return;
            }
    
            if (!me.store && !me.options) {
                me.options = me.grid.store.collect(me.dataIndex, false, true);
            }
    
            if (!me.store && me.options) {
                options = [];
                for (i = 0, len = me.options.length; i < len; i++) {
                    value = me.options[i];
                    switch (Ext.type(value)) {
                        case 'array':
                            options.push(value);
                            break;
                        case 'object':
                            options.push([value[me.idField], value[me.labelField]]);
                            break;
                        default:
                            if (value != null) {
                                options.push([value, value]);
                            }
                    }
                }
    
                me.store = Ext.create('Ext.data.ArrayStore', {
                    fields: [me.idField, me.labelField],
                    data: options,
                    listeners: {
                        load: me.onLoad,
                        scope: me
                    }
                });
                me.loaded = true;
                me.autoStore = true;
            } else {
                this.store = Ext.data.StoreManager.lookup(this.store);
    
                if (this.store.getCount() > 0) {
                    this.onLoad(this.store, this.store.getRange());
                }
                else {
                    this.add({ text: this.loadingText, iconCls: 'loading-indicator' });
                    this.store.on('load', this.onLoad, this);
                }
            }
        },
    
        updateDisabled: function (gridStore, filters) {
            var me = this,
                data = gridStore.collect(me.dataIndex, false, false);
    
            if (me.grid.filters.getFilter(me.dataIndex).active) {
                return;
            }
    
            Ext.suspendLayouts();
            me.items.each(function (item) {
    
                item.setDisabled(data.indexOf(item.text) === -1);
            });
            Ext.resumeLayouts(true);
        }
    });
    2. Please remove the ListFilter's StoreID.

    3. Please set this setting for the ListFilter.
    <CustomConfig>
        <ext:ConfigItem Name="autoOptions" Value="true" Mode="Raw" />
    </CustomConfig>
  3. #3
    Thanks Daniil, this is Awesome!! I'll also have the option to create custom menu items with this solution. Thanks for your help, much appreciated!!

    You can close the thread.

    JW

Similar Threads

  1. Replies: 2
    Last Post: Sep 17, 2014, 8:41 PM
  2. Replies: 6
    Last Post: Oct 15, 2012, 6:20 AM
  3. Replies: 12
    Last Post: Sep 20, 2011, 2:33 PM
  4. Replies: 0
    Last Post: Mar 04, 2011, 6:46 AM
  5. Replies: 1
    Last Post: Feb 24, 2010, 3:05 PM

Tags for this Thread

Posting Permissions