1. #1
    Sencha User
    Join Date
    Dec 2007
    Posts
    52
    Vote Rating
    0
    JKeane is on a distinguished road

      0  

    Default Answered: ComboBox filter not bubbling up to options until second filter attempt

    Answered: ComboBox filter not bubbling up to options until second filter attempt


    I have a popup window that holds a FormPanel with a handful of fields. One of the things I need to do is link some of the child ComboBoxes so that making a selection in one forces a filter on a subsequent one. I've set up a change event so that the Store of the subsequent combo is filtered (like the ComboBox's doQuery method, but filtering on valueField instead of displayField). However, the filtering only flows to the options after I make a choice, even though I have certified that Store is indeed filtered.

    See code below, and the comments next to the two alerts.

    Code:
    Ext.define("CF.view.Edit", {
        extend: "Ext.window.Window",
        alias: "widget.edit",
        title: "Client Fees - Edit",
        width: 320,
        height: 260,
        autoShow: true,
        buttonAlign: "left",
        initComponent: function () {
            this.items = [{
                xtype: "form",
                frame: true,
                fieldDefaults: {
                    labelWidth: 120
                },
                items: [{
                    xtype: "textfield",
                    name: "companyname",
                    fieldLabel: "Company/Sponsor"
                }, {
                    xtype: "combo",
                    name: "productseq",
                    id: "productseq",
                    fieldLabel: "Product",
                    store: new CF.store.Products(),
                    queryMode: "local",
                    displayField: "productName",
                    valueField: "productSeq"
                }, {
                    xtype: "combo",
                    disabled: false,
                    name: "feetype",
                    id: "feetype",
                    fieldLabel: "Fee Type",
                    store: new CF.store.FeeTypes(),
                    queryMode: "local",
                    displayField: "financeFeeDesc",
                    valueField: "financeFeeSeq",
                    forceSelection: true
                }, {
                    xtype: "hiddenfield",
                    name: "iconproductcode",
                    id: "iconproductcode"
                }, {
                    xtype: "textfield",
                    disabled: true,
                    name: "iconproductname",
                    id: "iconproductname",
                    fieldLabel: "ICON Product"
                }, {
                    xtype: "numberfield",
                    name: "feeamt",
                    fieldLabel: "Fee ($)",
                    hideTrigger: true,
                    keyNavEnabled: false,
                    mouseWheelEnabled: false
                }, {
                    xtype: "combo",
                    name: "feemonth",
                    fieldLabel: "Month",
                    queryMode: "local",
                    forceSelection: true,
                    store: (function () {
                        var x = [],
                            i;
                        for (i = 0; i < 12; i++) {
                            x.push([i + 1, Ext.Date.monthNames[i]]);
                        }
                        return x;
                    })()
                }, {
                    xtype: "combo",
                    name: "feeyear",
                    fieldLabel: "Year",
                    queryMode: "local",
                    forceSelection: true,
                    store: (function () {
                        var x = [],
                            year;
                        for (year = 2007; year <= (new Date).getFullYear(); year++) x.unshift(year);
                        return x;
                    })()
                }]
            }];
    
            //		this.down("#productseq").on("change", function(field,value) {
            //			//Ext.getCmp("iconproductcode").setValue(null);
            //			//Ext.getCmp("iconproductname").setValue(null);
            //			Ext.getCmp("feetype").store.filter(productSeq, value);
            //		});
            //		this.down("#feetype").on("change", function(field,value) {
            //			var icon = field.store.get("");
            //			Ext.getCmp("iconproductcode").setValue(null).store.filter("iconProductCode",value);
            //		});
            this.on("afterrender", function (w) {
                w.down("#productseq").on("change", function (field, value) {
                    //Ext.getCmp("iconproductcode").setValue(null);
                    //Ext.getCmp("iconproductname").setValue(null);
                    alert(Ext.getCmp("feetype").store.getCount()) //displays 160 in my test case
                    Ext.getCmp("feetype").store.clearFilter(true);
                    Ext.getCmp("feetype").store.filter("productSeq", value);
                    alert(Ext.getCmp("feetype").store.getCount()) //now it displays 2 as it should, but this is not reflected in the front-end
                });
            })
    
            this.buttons = [{
                text: 'Save',
                action: 'save'
            }, {
                text: 'Cancel',
                scope: this,
                handler: this.close
            }];
    
            this.callParent(arguments);
        }
    });

  2. I'm not sure I'm reproducing the same issue that you're having. My steps are:
    1. Click the button - a window appears.
    2. Click the trigger for the second combobox.
    3. The list of options is wrong given the first combobox's value.

    Is this the right problem?

    If it is then it is solved (for me at least) by adding:

    Code:
    lastQuery: ''
    to the second combobox's config. The first time you click the trigger it will clear any existing filters unless you do this. This is documented in the link I provided previously.

    If this isn't the problem you're seeing could you give the exact steps to reproduce using your test case?

  3. #2
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,503
    Answers
    528
    Vote Rating
    286
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    I suspect your filter is being cleared when you click the trigger. This can be prevented using lastQuery:

    http://docs.sencha.com/ext-js/4-0/#/...erty-lastQuery

  4. #3
    Sencha User
    Join Date
    Dec 2007
    Posts
    52
    Vote Rating
    0
    JKeane is on a distinguished road

      0  

    Default


    Here's the thing though: it works as it should whenever I expand the ComboBox and select an option. It's on render that the problem happens.

    Ext experts, please feel free to correct me, but I believe this is what happens in the scenario originally mentioned:
    1. CF.view.Edit is instantiated
    2. The view's render event triggers, which assigns the change event to ComboBox named productseq.
    3. The calling Grid's Controller (which instantiated CF.view.Edit) tells the FormPanel inside the Window to load the record
    4. FormPanel.loadRecord sets the value of the productseq ComboBox
    5. productseq fires off the change event

    I suspect this because of the debug alerts. On instantiation, the first alert signals the full size of the Store - 160 rows, in this case. Post-filter, the second alert shows the appropriate number of rows for a given product -- usually around 2, but it varies depending on the selection. However, the ComboBox still shows all 160 rows. Then I make change to a different value for productseq. Again, the pre-filter alert displays -- the 2 or whatever rows from the previous selection. Filter is cleared and reapplied, the post-filter alert displays the new row count, and the filter now works as expected.

  5. #4
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,503
    Answers
    528
    Vote Rating
    286
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    Would you be able to produce a short reproducible test case? Your current test case is quite long and full of code that clearly has no bearing on the problem. Ideally it should be some JS that we could just drop into a shell HTML page. At the moment your code has a lot of external dependencies (e.g. the stores) that make it hard for us to try it ourselves.

    This isn't just about making it easier for us, it is often this trimming process that identifies the cause of a problem.

  6. #5
    Sencha User
    Join Date
    Dec 2007
    Posts
    52
    Vote Rating
    0
    JKeane is on a distinguished road

      0  

    Default


    Certainly. I've broken it down to just be two interrelated ComboBoxes backed by very simple stores. I also created a basic object that stores values to load into the form. And it's still not filtering properly until after the data is loaded and I click to expand the dropdown. Please let me know if I need to strip it down further.

    Code:
    var Products, FeeTypes, TestData;
    Ext.define("Product", {
        extend: "Ext.data.Model",
        fields: [{
            name: "id",
            type: "int"
        }, "name"]
    });
    Products = Ext.create("Ext.data.Store", {
        model: "Product",
        data: [{
            id: 1,
            name: "Widget"
        }, {
            id: 2,
            name: "Gizmo"
        }]
    });
    
    Ext.define("FeeType", {
        extend: "Ext.data.Model",
        fields: [{
            name: "id",
            type: "int"
        }, {
            name: "productId",
            type: "int"
        }, "name"]
    });
    FeeTypes = Ext.create("Ext.data.Store", {
        model: "FeeType",
        data: [{
            id: 1,
            productId: 1,
            name: "Cash"
        }, {
            id: 2,
            productId: 1,
            name: "Store Credit"
        }, {
            id: 3,
            productId: 2,
            name: "Credit Card"
        }]
    });
    
    Ext.define("TestRecord", {
        extend: "Ext.data.Model",
        fields: ["productseq", "feetype"]
    });
    //should match the pair "Gizmo/Credit Card"
    TestData = Ext.create("TestRecord", {
        productseq: 2,
        feetype: 3
    });
    
    Ext.define("CF.view.Edit", {
        extend: "Ext.window.Window",
        alias: "widget.edit",
        title: "Client Fees - Edit",
        width: 320,
        height: 260,
        autoShow: true,
        buttonAlign: "left",
        initComponent: function () {
            this.items = [{
                xtype: "form",
                frame: true,
                fieldDefaults: {
                    labelWidth: 120
                },
                items: [{
                    xtype: "combo",
                    name: "productseq",
                    id: "productseq",
                    fieldLabel: "Product",
                    store: Products,
                    queryMode: "local",
                    displayField: "name",
                    valueField: "id"
                }, {
                    xtype: "combo",
                    disabled: false,
                    name: "feetype",
                    id: "feetype",
                    fieldLabel: "Fee Type",
                    store: FeeTypes,
                    queryMode: "local",
                    displayField: "name",
                    valueField: "id",
                    forceSelection: true
                }]
            }];
    
            this.on("afterrender", function (w) {
                w.down("#productseq").on("change", function (field, value) {
                    Ext.getCmp("feetype").store.clearFilter(true);
                    Ext.getCmp("feetype").store.filter("productId", value);
                });
            });
    
            this.callParent(arguments);
        }
    });
    
    Ext.onReady(function () {
        var b = Ext.create("Ext.Button", {
            renderTo: Ext.getBody(),
            text: "Push me",
            autoRender: true,
            listeners: {
                click: function () {
                    var widget = Ext.widget("edit");
                    widget.down("form").loadRecord(TestData);
                }
            }
        })
    });
    Last edited by JKeane; 17 Aug 2011 at 11:05 AM. Reason: clarification

  7. #6
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,503
    Answers
    528
    Vote Rating
    286
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    I'm not sure I'm reproducing the same issue that you're having. My steps are:
    1. Click the button - a window appears.
    2. Click the trigger for the second combobox.
    3. The list of options is wrong given the first combobox's value.

    Is this the right problem?

    If it is then it is solved (for me at least) by adding:

    Code:
    lastQuery: ''
    to the second combobox's config. The first time you click the trigger it will clear any existing filters unless you do this. This is documented in the link I provided previously.

    If this isn't the problem you're seeing could you give the exact steps to reproduce using your test case?

  8. #7
    Sencha User
    Join Date
    Dec 2007
    Posts
    52
    Vote Rating
    0
    JKeane is on a distinguished road

      0  

    Default


    Yep, lastQuery appears to have done the trick. Thanks!

Thread Participants: 1