[CLOSED] Various filter issues

Page 1 of 2 12 LastLast
  1. #1

    [CLOSED] Various filter issues

    Hi,

    This thread is related to recent discussions at
    http://forums.ext.net/showthread.php...tability-issue
    http://forums.ext.net/showthread.php...-event-handler

    Please review the code sample below and suggest what adjustments are necessary. My apologies for the somewhat lengthy test case.
    I've encountered two issues with it so far:
    1. Column Header menu items don't change their status until after the menu is collapsed in DateFilter, ListFilter and StringFilter
    2. The StringFilter breaks after columns visibility and/or hideability is modified


    Steps to reproduce the first issue with the DateFilter:
    • Make the Last Updated column visible by checking it in the header menu
    • Check its Before filter
    • Move up to the Columns menu and observe that the Last Updated checkbox is correctly checked off and is disabled
    • Uncheck its Date filter using the Before menu
    • Move up to the Columns menu and observe that the Last Updated checkbox appears correctly checked off and enabled
    • Activate the Date filter again
    • Deactivate it by unchecking the Filters checkbox
    • Move up to the Columns menu and observe that the Last Updated checkbox is still disabled (has to be enabled)
    • Collapse the header menu and reopen it; observe that the Last Updated checkbox is now correctly checked off AND enabled


    Steps to reproduce the first issue with the ListFilter:
    • Select a couple of options in the Industry filter
    • Move up to the Columns menu and observe that the Industry option is checked off but not necessarily disabled (inconsistent)
    • Uncheck the Industry filter using individual options or the Filters checkbox and observe the inconsistent behavior


    Steps to reproduce the first issue with the StringFilter:
    • Type in something in the Company filter
    • Move up to the Columns menu and observe that the Company option is checked off but not necessarily disabled (inconsistent)
    • Uncheck the Company filter using the text filed or the Filters checkbox and observe the inconsistent behavior


    Steps to reproduce the second issue (StringFilter):
    • Click on the Reset button
    • Type in something in the Company filter and observe that it gets activated correctly
    • Make the Last Updated column visible
    • Click on the Reset button again
    • Type in something in the Company filter and observe that it DOESN'T get activated any more


    <%@ Page Language="C#" %>
    
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <%@ Import Namespace="System.Data" %>
    <script runat="server">
        private DataTable TestData
        {
            get
            {
                var updated = new DateTime(2013, 01, 20);
                var addDays = 1;
                var dataTable = new DataTable();
                dataTable.Columns.AddRange(new DataColumn[] { 
                    new DataColumn { ColumnName = "company", DataType = typeof(System.String) },
                    new DataColumn { ColumnName = "industry", DataType = typeof(System.String) },
                    new DataColumn { ColumnName = "price", DataType = typeof(System.Double) },
                    new DataColumn { ColumnName = "change", DataType = typeof(System.Double) },
                    new DataColumn { ColumnName = "pctChange", DataType = typeof(System.Double) },
                    new DataColumn { ColumnName = "lastChange", DataType = typeof(System.DateTime) },
                    new DataColumn { ColumnName = "visible", DataType = typeof(System.Boolean) },
                });
    
                var dataArray = new object[]
                {
                    new object[] { "3m Co", "Conglomerates", 71.72, 0.02, 0.03, updated.AddDays(addDays++), true },
                    new object[] { "Alcoa Inc", "Basic Materials", 29.01, 0.42, 1.47, updated.AddDays(addDays++), true },
                    new object[] { "Altria Group Inc", "Consumer Goods",  83.81, 0.28, 0.34, updated.AddDays(addDays++), true },
                    new object[] { "American Express Company", "Financial", 52.55, 0.01, 0.02, updated.AddDays(addDays++), true },
                    new object[] { "American International Group, Inc.", "Financial", 64.13, 0.31, 0.49, updated.AddDays(addDays++), false },
                    new object[] { "AT&T Inc.", "Technology", 31.61, -0.48, -1.54, updated.AddDays(addDays++), false },
                    new object[] { "Boeing Co.", "Industrial", 75.43, 0.53, 0.71, updated.AddDays(addDays++), false },
                    new object[] { "Caterpillar Inc.", "Industrial", 67.27, 0.92, 1.39, updated.AddDays(addDays++), false },
                    new object[] { "Citigroup, Inc.", "Financial", 49.37, 0.02, 0.04, updated.AddDays(addDays++), false },
                    new object[] { "E.I. du Pont de Nemours and Company", "Basic Materials", 40.48, 0.51, 1.28, updated.AddDays(addDays++), false },
                    new object[] { "Exxon Mobil Corp", "Energy", 68.1, -0.43, -0.64, updated.AddDays(addDays++), true },
                    new object[] { "General Electric Company", "Industrial", 34.14, -0.08, -0.23, updated.AddDays(addDays++), true },
                    new object[] { "General Motors Corporation", "Consumer", 30.27, 1.09, 3.74, updated.AddDays(addDays++), true },
                    new object[] { "Hewlett-Packard Co.", "Technology", 36.53, -0.03, -0.08, updated.AddDays(addDays++), true },
                    new object[] { "Honeywell Intl Inc", "Industrial", 38.77, 0.05, 0.13, updated.AddDays(addDays++), true },
                    new object[] { "Intel Corporation", "Technology", 19.88, 0.31, 1.58, updated.AddDays(addDays++), false },
                    new object[] { "International Business Machines", "Technology", 81.41, 0.44, 0.54, updated.AddDays(addDays++), false },
                    new object[] { "Johnson & Johnson", "Consumer", 64.72, 0.06, 0.09, updated.AddDays(addDays++), false },
                    new object[] { "JP Morgan & Chase & Co", "Financial", 45.73, 0.07, 0.15, updated.AddDays(addDays++), false },
                    new object[] { "McDonald\"s Corporation", "Consumer", 36.76, 0.86, 2.40, updated.AddDays(addDays++), false },
                    new object[] { "Merck & Co., Inc.", "Consumer", 40.96, 0.41, 1.01, updated.AddDays(addDays++), true },
                    new object[] { "Microsoft Corporation", "Technology", 25.84, 0.14, 0.54, updated.AddDays(addDays++), false },
                    new object[] { "Pfizer Inc", "Consumer", 27.96, 0.4, 1.45, updated.AddDays(addDays++), false},
                    new object[] { "The Coca-Cola Company", "Consumer", 45.07, 0.26, 0.58, updated.AddDays(addDays++), true },
                    new object[] { "The Home Depot, Inc.", "Consumer", 34.64, 0.35, 1.02, updated.AddDays(addDays++), true },
                    new object[] { "The Procter & Gamble Company", "Consumer", 61.91, 0.01, 0.02, updated.AddDays(addDays++), true },
                    new object[] { "United Technologies Corporation", "Industrial", 63.26, 0.55, 0.88, updated.AddDays(addDays++), true },
                    new object[] { "Verizon Communications", "Communications", 35.57, 0.39, 1.11, updated.AddDays(addDays++), true },
                    new object[] { "Wal-Mart Stores, Inc.", "Consumer", 45.45, 0.73, 1.63, updated.AddDays(addDays++), true }
                };
    
                foreach (object[] row in dataArray)
                {
                    dataTable.LoadDataRow(row, true);
                }
    
                return dataTable;
            }
        }
    
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                var mainDataSource = this.TestData;
                this.Store1.DataSource = mainDataSource;
                this.Store1.DataBind();
    
                mainDataSource.DefaultView.Sort = "industry ASC";
                var industryTable = mainDataSource.DefaultView.ToTable(true, "industry");
                StoreIndustry.DataSource = industryTable;
                StoreIndustry.DataBind();
            }
        }
    </script>
    <!DOCTYPE html>
    <html>
    <head id="Head1" runat="server">
        <title>Local Data Paging - Ext.NET Examples</title>
        <script type="text/javascript">
            // Display non-hideable columns as checked off and disabled in the column menu selector
            Ext.grid.header.Container.override({
                getColumnMenu: function (headerContainer) {
                    var menuItems = [],
                        i = 0,
                        item,
                        items = headerContainer.query('>gridcolumn[text!="*"]'),
                        itemsLn = items.length,
                        menuItem;
    
                    for (; i < itemsLn; i++) {
                        item = items[i];
                        if (item.text == "*") continue;
                        menuItem = new Ext.menu.CheckItem({
                            text: item.menuText || item.text,
                            checked: !item.hidden,
                            hideOnClick: false,
                            headerId: item.id,
                            menu: item.isGroupHeader ? this.getColumnMenu(item) : undefined,
                            checkHandler: this.onColumnCheckChange,
                            scope: this,
                            disabled: !item.hidden && !item.isHideable() // modified by vadym.f
                        });
                        menuItems.push(menuItem);
    
                        // If the header is ever destroyed - for instance by dragging out the last remaining sub header,
                        // then the associated menu item must also be destroyed.
                        item.on({
                            destroy: Ext.Function.bind(menuItem.destroy, menuItem)
                        });
                    }
                    return menuItems;
                }
            });
    
            var _iconSrc = null;
            var getIconSrc = function () {
                if (!_iconSrc)
                    _iconSrc = Ext.String.format("<img src='{0}' />", Ext.net.ResourceMgr.getIconUrl("Book"));
                return _iconSrc;
            };
    
            var recordIconRenderer = function (value, metadata, record) {
                return getIconSrc();
            };
    
            var onFilterDeactivate = function (filter, options) {
                filter.suspendEvents(false);
                switch (filter.type) {
                    case "boolean":
                        break;
                    case "date":
                        filter.menu.items.each(function (item) {
                            if (item instanceof Ext.menu.CheckItem)
                                item.setChecked(false);
                        });
                        break;
                    case "list":
                        filter.menu.items.each(function (item) {
                            item.setChecked(false);
                        });
                        break;
                    case "numeric":
                        filter.menu.items.each(function (item) {
                            if (item instanceof Ext.form.NumberField)
                                item.setValue("");
                        });
                        break;
                    case "string":
                        filter.menu.items.each(function (item) {
                            item.setValue("");
                        });
                        break;
                };
                filter.setActive(false);
                filter.resumeEvents();
    
                toggleColumnHideability(filter, true);
            };
    
            var onFilterActivate = function (filter, options) {
                toggleColumnHideability(filter, false);
            };
    
            var onFilterUpdate = function (filter, options) {
                // Irrelevant for this test case
            };
    
            var toggleColumnHideability = function (filter, makeHideable) {
                var columns = filter.grid.getView().headerCt.getGridColumns();
                var column = null;
                for (var i = 0; i < columns.length; i++) {
                    if (columns[i].dataIndex == filter.dataIndex) {
                        column = columns[i];
                        break;
                    }
                }
    
                if (makeHideable) {
                    // Make the column hideable again unless it was non-hideable by default (hideableDefault=false)
                    if (typeof column.hideableDefault == "undefined" || column.hideableDefault === true)
                        column.hideable = true;
                }
                else {
                    // Make the column non-hideable
                    var hideableDefault = column.isHideable();
                    column.hideable = false;
                    column.hideableDefault = hideableDefault;
                }
            };
    
            var onGridPanelRender = function (grid) {
                grid.getStore().grid = grid;
                grid.filters.filters.each(function (filter) {
                    filter.grid = grid;
                });
            };
    
            var reset = function (button) {
                var grid = button.up("gridpanel");
                clearFilters(grid, true);
                var columns = grid.getView().headerCt.getGridColumns();
    
                grid.suspendEvents(false);
                for (var i = 0; i < columns.length; i++) {
                    columns[i].suspendEvents(false);
                }
    
                reconfigureColumns(columns);
    
                for (var i = 0; i < columns.length; i++) {
                    columns[i].resumeEvents();
                }
                grid.resumeEvents();
                grid.doLayout();
            };
    
            // This method clears the GridPanel filters
            var clearFilters = function (grid, suspendEvents) {
                if (!grid.filters)
                    return false;
    
                grid.filters.filters.each(function (filter) {
                    if (suspendEvents) {
                        filter.suspendEvents(false);
                    }
    
                    switch (filter.type) {
                        case "boolean":
                            break;
                        case "date":
                            filter.menu.items.each(function (item) {
                                if (item instanceof Ext.menu.CheckItem) {
                                    item.setChecked(false);
                                    var itemText = item.text.toLowerCase();
                                    var picker = filter.getPicker(itemText);
                                    var now = new Date();
                                    picker.setValue(now);
                                    filter.values[itemText] = now;
                                }
                            });
                            break;
                        case "list":
                            filter.menu.items.each(function (item) {
                                item.suspendEvents(false);
                                item.setChecked(false);
                                item.resumeEvents();
                            });
                            break;
                        case "numeric":
                            filter.menu.items.each(function (item) {
                                if (item instanceof Ext.form.NumberField)
                                    item.setValue("");
                            });
                            break;
                        case "string":
                            filter.menu.items.each(function (item) {
                                item.setValue("");
                            });
                            break;
                    };
                    filter.setActive(false);
    
                    if (suspendEvents) {
                        filter.resumeEvents();
                    }
                });
                return true;
            };
    
            var reconfigureColumns = function (columns) {
                for (var i = 0; i < columns.length; i++) {
                    columns[i].setVisible(columns[i].id != "DateColumn1");
                    columns[i].hideable = (columns[i].id != "Column3" && columns[i].id != "Column4");
                }
                return true;
            };
        </script>
    </head>
    <body>
        <form id="Form1" runat="server">
        <ext:ResourceManager ID="ResourceManager1" runat="server" />
        <ext:Store ID="StoreIndustry" runat="server" AutoLoad="true">
            <Model>
                <ext:Model runat="server" IDProperty="industry">
                    <Fields>
                        <ext:ModelField Name="industry" />
                    </Fields>
                </ext:Model>
            </Model>
        </ext:Store>
        <ext:Viewport runat="server" Layout="FitLayout">
            <Items>
                <ext:GridPanel ID="GridPanel1" runat="server" Flex="1" SelectionMemory="false">
                    <Store>
                        <ext:Store ID="Store1" runat="server" RemoteSort="false" AutoLoad="true" PageSize="10">
                            <Model>
                                <ext:Model ID="Model1" runat="server" IDProperty="company">
                                    <Fields>
                                        <ext:ModelField Name="company" />
                                        <ext:ModelField Name="industry" />
                                        <ext:ModelField Name="price" Type="Float" />
                                        <ext:ModelField Name="change" Type="Float" />
                                        <ext:ModelField Name="pctChange" Type="Float" />
                                        <ext:ModelField Name="lastChange" Type="Date" />
                                        <ext:ModelField Name="visible" Type="Boolean" />
                                    </Fields>
                                </ext:Model>
                            </Model>
                        </ext:Store>
                    </Store>
                    <ColumnModel ID="ColumnModel1" runat="server">
                        <Columns>
                            <ext:Column runat="server" ID="IconColumn" MenuDisabled="true" Sortable="false" Resizable="false"
                                Hideable="false" Width="28">
                                <Renderer Fn="recordIconRenderer" />
                            </ext:Column>
                            <ext:Column ID="Column1" runat="server" Text="Company" DataIndex="company" Hideable="true"
                                Width="200">
                                <Editor>
                                    <ext:TextField ID="TextField1" runat="server" />
                                </Editor>
                            </ext:Column>
                            <ext:Column ID="Column2" runat="server" Text="Industry" DataIndex="industry" Hideable="true"
                                Width="200">
                            </ext:Column>
                            <ext:Column ID="Column3" runat="server" Text="Price" Width="75" DataIndex="price"
                                Hideable="false">
                                <Editor>
                                    <ext:TextField ID="TextField2" runat="server" />
                                </Editor>
                            </ext:Column>
                            <ext:Column ID="Column4" runat="server" Text="Change" Width="100" DataIndex="change"
                                Hideable="false" />
                            <ext:Column ID="Column5" runat="server" Text="% Change" Width="100" DataIndex="pctChange"
                                Hideable="true" />
                            <ext:DateColumn ID="DateColumn1" runat="server" Text="Last Updated" Width="120" DataIndex="lastChange"
                                Hideable="true" Hidden="true" Format="MMM dd, yyyy" />
                            <ext:Column ID="Column6" runat="server" Text="Visible" DataIndex="visible" Align="Center"
                                Hideable="true">
                                <Renderer Handler="return (value) ? 'Yes':'No';" />
                            </ext:Column>
                        </Columns>
                    </ColumnModel>
                    <SelectionModel>
                        <ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Single" />
                    </SelectionModel>
                    <Features>
                        <ext:GridFilters runat="server" Local="true">
                            <Filters>
                                <ext:StringFilter DataIndex="company" EmptyText="Type in description...">
                                    <Listeners>
                                        <Deactivate Fn="onFilterDeactivate" />
                                        <Activate Fn="onFilterActivate" />
                                        <Update Fn="onFilterUpdate" />
                                    </Listeners>
                                </ext:StringFilter>
                                <ext:ListFilter DataIndex="industry" LabelField="industry" IDField="industry" StoreID="StoreIndustry">
                                    <Listeners>
                                        <Deactivate Fn="onFilterDeactivate" />
                                        <Activate Fn="onFilterActivate" />
                                        <Update Fn="onFilterUpdate" />
                                    </Listeners>
                                </ext:ListFilter>
                                <ext:DateFilter DataIndex="lastChange">
                                    <DatePickerOptions runat="server" TodayText="Now" />
                                    <Listeners>
                                        <Deactivate Fn="onFilterDeactivate" />
                                        <Activate Fn="onFilterActivate" />
                                        <Update Fn="onFilterUpdate" />
                                    </Listeners>
                                </ext:DateFilter>
                                <ext:BooleanFilter DataIndex="visible">
                                    <Listeners>
                                        <Deactivate Fn="onFilterDeactivate" />
                                        <Activate Fn="onFilterActivate" />
                                        <Update Fn="onFilterUpdate" />
                                    </Listeners>
                                </ext:BooleanFilter>
                            </Filters>
                        </ext:GridFilters>
                    </Features>
                    <BottomBar>
                        <ext:PagingToolbar ID="PagingToolbar1" runat="server">
                            <Items>
                                <ext:Button runat="server" Text="Reset">
                                    <Listeners>
                                        <Click Handler="reset(this);">
                                        </Click>
                                    </Listeners>
                                </ext:Button>
                            </Items>
                        </ext:PagingToolbar>
                    </BottomBar>
                    <Listeners>
                        <Render Fn="onGridPanelRender" />
                    </Listeners>
                    <View>
                        <ext:GridView ID="GridView1" runat="server">
                        </ext:GridView>
                    </View>
                </ext:GridPanel>
            </Items>
        </ext:Viewport>
        </form>
    </body>
    </html>
    Last edited by Daniil; Sep 10, 2013 at 5:28 AM. Reason: [CLOSED]
  2. #2
    Hello!

    Thank you! We are investigating.
  3. #3
    It's necessary to update disable state of the menu. Try the following:

    var toggleColumnHideability = function (filter, makeHideable) {
    	var columns = filter.grid.getView().headerCt.getGridColumns();
    	var column = null;
    	for (var i = 0; i < columns.length; i++) {
    		if (columns[i].dataIndex == filter.dataIndex) {
    			column = columns[i];
    			break;
    		}
    	}
    
    	if (makeHideable) {
    		// Make the column hideable again unless it was non-hideable by default (hideableDefault=false)
    		if (typeof column.hideableDefault == "undefined" || column.hideableDefault === true)
    			column.hideable = true;
    	}
    	else {
    		// Make the column non-hideable
    		var hideableDefault = column.isHideable();
    		column.hideable = false;
    		column.hideableDefault = hideableDefault;
    	}
    	
    	filter.grid.getView().headerCt.updateMenuDisabledState(filter.grid.getView().headerCt.menu);
    };
  4. #4
    Thanks for the workaround Daulet and my apologies for the late response. The hideability feature seems to be doing better now. However, Company StringFilter still appears broken after I hit the "Reset" button.

    Steps to reproduce:

    • Make the "Updated" column visible from the header menu
    • Test the Company filter to ensure that it's functional
    • Click the "Reset" button
    • Re-test the Company StringFilter to observe that it's no longer functional


    Please use the same test case posted in this thread with the addition of your suggested line of code. From my debugging, I'm led to believe that the following call screws things up:

    columns[i].hideable = (columns[i].id != "Column3" && columns[i].id != "Column4");
    Last edited by vadym.f; Aug 26, 2013 at 2:22 PM.
  5. #5
    Please advise if more info is required here.

    Update:

    After stepping through the client code in the ext.axd resource file, I tend to believe that the call doing damage to the StringFilter is invoked inside the onHeaderVisibilityChange event handler, the following line:

    me.purgeCache();
    More specifically, if I avoid stepping into the following block of code within the purgeCache function, the StringFilter remains operational:

            // Menu changes when columns are moved. It will be recreated.
            // Menu does not change when columns are hidden or shown (which is all that happens when menu is visible)
            if (menu && menu.hidden) {
                // Must hide before destroy so that trigger el is deactivated
                menu.hide();
                menu.destroy();
                me.menu = null;
            }
    Last edited by vadym.f; Aug 27, 2013 at 5:55 PM.
  6. #6
    Please try with this override.
    Ext.ux.grid.filter.StringFilter.override({
        init : function (config) {
            delete config.listeners;
            Ext.applyIf(config, {
                enableKeyEvents: true,
                labelCls: 'ux-rangemenu-icon ' + this.iconCls,
                hideEmptyLabel: false,
                labelSeparator: '',
                labelWidth: 29,
                listeners: {
                    scope: this,
                    keyup: this.onInputKeyUp,
                    el: {
                        click: function(e) {
                            e.stopPropagation();
                        }
                    }
                }
            });
    
            this.inputItem = Ext.create('Ext.form.field.Text', config);
            this.menu.add(this.inputItem);
            this.menu.showSeparator = false;
            this.updateTask = Ext.create('Ext.util.DelayedTask', this.fireUpdate, this);
        }
    });
  7. #7
    Much appreciated Daniil, it seems to be working well! Do you expect this override to make the trunk in some form?
  8. #8
    I will wait for a bit while. If you don't face any issues more, I will commit it to SVN.
  9. #9
    So, just to confirm, are you not facing any issues with that?
  10. #10
    So far so good. You can mark this thread as closed.
Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 0
    Last Post: May 31, 2013, 8:06 AM
  2. Replies: 1
    Last Post: Mar 20, 2013, 4:18 PM
  3. Replies: 7
    Last Post: Mar 12, 2013, 8:15 AM
  4. Replies: 2
    Last Post: May 01, 2012, 4:57 PM
  5. [CLOSED] Missing filter column using MultiHeader Filter.
    By flormariafr in forum 1.x Legacy Premium Help
    Replies: 4
    Last Post: Aug 12, 2010, 1:07 PM

Tags for this Thread

Posting Permissions