Results 1 to 2 of 2

Thread: ExtJS--create/clone new stores for treecombo when new grid row is added

  1. #1
    Sencha User
    Join Date
    Nov 2014
    Posts
    53
    Answers
    4
    Vote Rating
    0
      0  

    Default ExtJS--create/clone new stores for treecombo when new grid row is added

    I have an editable grid that uses 4 instances of the custom "treecombo" extjs component. Theres 4 columns that use treecombo as an editor. I differentiate these 4 combos by itemId. The 4 treecombos all use separate stores.

    The problem is, I have selective filtering implemented on the comboboxes. Meaning, when an item is selected, I filter/load the remaining combos. Think of a Country/State/City/Zip type scenario. When country is selected, the states are loaded accordingly, when state is selected, cities are loaded accordingly etc. So when I add a new row to the grid and make a selection in row 2 for example, ALL the combos in ALL the rows get filtered, not just in row 2. The selections in row 1 wont get cleared/reset which is fine, but if i was to go back and change a selection in row 1, the results I will be seeing in the drop down list will be the filtered results based on row 2 selections, not row 1 selections.

    So my question is, is there a way to make the combos stores in each row independent of combo stores in other rows? Or a way to dynamically create/clone new stores for the 4 combos whenever a new row is added??
    Thank you in advance..
    //grid editors



    Code:
        this.columns = [
          {
                header:"Country",
                dataIndex:"country",
                flex:1,
                editor:Ext.create("MyApp.form.field.TreeCombo",{ selectChildren: true, itemId:"country", store:"Countries", treeWidth:240, displayField:"text", valueField:"text"})
              },
              {
                header:"State",
                dataIndex:"state",
                flex:1,
                editor:Ext.create("MyApp.form.field.TreeCombo",{ itemId:"state", store:"States", treeWidth:240, displayField:"text", valueField:"text"})
              },
              {
                header:"Cities",
                dataIndex:"cities",
                flex:1,
                editor:Ext.create("MyApp.form.field.TreeCombo",{ itemId:"cities", treeWidth:240, store:"Cities",  displayField:"text", valueField:"text"})
              },
              {
                header:"Zip",
                dataIndex:"zip",
                flex:1,
                editor:Ext.create("MyApp.form.field.TreeCombo",{ itemId:"zip", treeWidth:240, store:"Zip", displayField:"text", valueField:"text"})
              }
        ];

    //treecombo source--note, it actually extends field.Picker, not field.ComboBox
    Code:
     Ext.define('MyApp.form.field.TreeCombo',    {
          extend: 'Ext.form.field.Picker',
          alias: 'widget.treecombo',
          tree: false,      
          constructor: function(config)
          {
            this.addEvents(
            {
              "itemclick" : true      
            });
        
        
            this.listeners = config.listeners;
            this.callParent(arguments);
          },
          records: [],
          recursiveRecords: [],
          ids: [],
          selectChildren: true,
          canSelectFolders: true,
          multiselect: false,
          displayField: 'text',
          valueField: 'text',
          treeWidth: 300,
          matchFieldWidth: true,
          treeHeight: 400,
          masN: 0,
          recursivePush: function(node, setIds)
          {
            if (!Array.prototype.indexOf)
            {
              Array.prototype.indexOf = function(elt /*, from*/)
              {
                var len = this.length >>> 0;
        
                var from = Number(arguments[1]) || 0;
                from = (from < 0)
                     ? Math.ceil(from)
                     : Math.floor(from);
                if (from < 0)
                  from += len;
        
                for (; from < len; from++)
                {
                  if (from in this &&
                      this[from] === elt)
                    return from;
                }
                return -1;
              };
            }
            var me = this;
        
        
            me.addRecRecord(node);
            if(setIds) me.addIds(node);
            
            node.eachChild(function(nodesingle)
            {
              if(nodesingle.hasChildNodes() == true)
              {
                me.recursivePush(nodesingle, setIds);
              }
              else
              {
                me.addRecRecord(nodesingle);
                if(setIds) me.addIds(nodesingle);
              }
            });
          },
          recursiveUnPush: function(node)
          {
            var me = this;
            me.removeIds(node);
            
            node.eachChild(function(nodesingle)
            {
              if(nodesingle.hasChildNodes() == true)
              {
                me.recursiveUnPush(nodesingle);
              }
              else me.removeIds(nodesingle);
            });
          },
          addRecRecord: function(record)
          {
            var me = this;
        
        
            for(var i=0,j=me.recursiveRecords.length;i<j;i++)
            {
              var item = me.recursiveRecords[i];
              if(item)
              {
                if(item.getId() == record.getId()) return;
              }
            }
            me.recursiveRecords.push(record);
          },
          afterLoadSetValue: false,
          setValue: function(valueInit)
          {
            if(typeof valueInit == 'undefined') return;
            
            var me = this,
              tree = this.tree,
              values = (valueInit == '') ? [] : valueInit.split(','),
              valueFin = [];
              
            inputEl = me.inputEl;
        
        
            if(tree.store.isLoading())
            {
              me.afterLoadSetValue = valueInit;
            }
        
        
            if(inputEl && me.emptyText && !Ext.isEmpty(values))
            {
              inputEl.removeCls(me.emptyCls);
            }
        
        
            if(tree == false) return false;
            
            var node = tree.getRootNode();
            if(node == null) return false;
            
            me.recursiveRecords = [];
            me.recursivePush(node, false);
            
            me.records = [];
            Ext.each(me.recursiveRecords, function(record)
            {
              var id = record.get(me.valueField);
        
              var index = values.indexOf(""+id);
            
              if(me.multiselect == true) record.set('checked', false);
              
              if(index != -1)
              {
                valueFin.push(record.get(me.displayField));
                if(me.multiselect == true) record.set('checked', true);
                me.addRecord(record);
              }
            });
        
        
            me.value = valueInit;
            me.setRawValue(valueFin.join(', '));
            
            me.checkChange();
            me.applyEmptyText();
            return me;
          },
          getValue: function() 
          {
            return this.value;
          },
          getSubmitValue: function()
          {
            return this.value;
          },
          checkParentNodes: function(node)
          {
            if(node == null) return;
            
            var me = this,
              checkedAll = true;
        
        
            node.eachChild(function(nodesingle)
            {
              var id = nodesingle.getId(),
                index = me.ids.indexOf(''+id);
                
              if(index == -1) checkedAll = false;
            });
            
            if(checkedAll == true)
            {
              me.addIds(node);
              me.checkParentNodes(node.parentNode);
            }
            else
            {
              me.removeIds(node);
              me.checkParentNodes(node.parentNode);
            }
          },
          initComponent: function() 
          {
            var me = this;
            
            me.tree = Ext.create('Ext.tree.Panel',
            {
              alias: 'widget.assetstree',
              hidden: true,
              minHeight: 300,
              rootVisible: (typeof me.rootVisible != 'undefined') ? me.rootVisible : true,
              floating: true,
              useArrows: true,
              width: me.treeWidth,
              autoScroll: true,
              height: me.treeHeight,
              store: me.store,
              listeners:
              {
                load: function(store, records)
                {
                  if(me.afterLoadSetValue != false)
                  {
                    me.setValue(me.afterLoadSetValue);
                  }
                },
                itemclick:  function(view, record, item, index, e, eOpts)
                {
                  me.itemTreeClick(view, record, item, index, e, eOpts, me)
                }
              }
            });
            
            if(me.tree.getRootNode().get('checked') != null) me.multiselect = true;
            
            this.createPicker = function()
            {
              var me = this;
              return me.tree;
            };
            
            this.callParent(arguments);
          },
          addIds: function(record)
          {
            var me = this;
            
            if(me.ids.indexOf(''+record.getId()) == -1) me.ids.push(''+record.get(me.valueField));
          },
          removeIds: function(record)
          {
            var me = this,
              index = me.ids.indexOf(''+record.getId());
              
            if(index != -1)
            {
              me.ids.splice(index, 1);
            }
          },
          addRecord: function(record)
          {
            var me = this;
        
        
            for(var i=0,j=me.records.length;i<j;i++)
            {
              var item = me.records[i];
              if(item)
              {
                if(item.getId() == record.getId()) return;
              }
            }
            me.records.push(record);
          },
          removeRecord: function(record)
          {
            var me = this;
        
        
            for(var i=0,j=me.records.length;i<j;i++)
            {
              var item = me.records[i];
              if(item && item.getId() == record.getId()) delete(me.records[i]);
            }
          },
          itemTreeClick: function(view, record, item, index, e, eOpts, treeCombo)
          {
             
            var me = treeCombo,
              checked = !record.get('checked');//it is still not checked if will be checked in this event
            
            if(me.multiselect == true) record.set('checked', checked);//check record
            
            var node = me.tree.getRootNode().findChild(me.valueField, record.get(me.valueField), true);
            me.setValue(record.data.text);
            if(node == null) 
            {
              if(me.tree.getRootNode().get(me.valueField) == record.get(me.valueField)) node = me.tree.getRootNode();
              else return false;
            }
            
            if(me.multiselect == false) me.ids = [];
            
            //if it can't select folders and it is a folder check existing values and return false
            if(me.canSelectFolders == false && record.get('leaf') == false)
            {
              me.setRecordsValue(view, record, item, index, e, eOpts, treeCombo);
              return false;
            }
            
            //if record is leaf
            if(record.get('leaf') == true) 
            {
              if(checked == true)
              {
                me.addIds(record);
              }
              else
              {
                me.removeIds(record);
              }
            }
            else //it's a directory
            {     
              me.recursiveRecords = [];
              if(checked == true)
              {
                if(me.multiselect == false)
                {
                  if(me.canSelectFolders == true) me.addIds(record); 
                }
                else
                {
                  if(me.canSelectFolders == true)
                  {
                    me.recursivePush(node, true);
                  }
                }
              }
              else
              {
                if(me.multiselect == false)
                {
                  if(me.canSelectFolders == true) me.recursiveUnPush(node);
                  else me.removeIds(record);
                }
                else me.recursiveUnPush(node);
              }
            }
            
            //this will check every parent node that has his all children selected
            if(me.canSelectFolders == true && me.multiselect == true) me.checkParentNodes(node.parentNode);
            
            me.setRecordsValue(view, record, item, index, e, eOpts, treeCombo);
          },
          fixIds: function()
          {
            var me = this;
            
            for(var i=0,j=me.ids.length;i<j;i++)
            {
              if(me.ids[i] == 'NaN') me.ids.splice(i, 1);
            }
          },
          setRecordsValue: function(view, record, item, index, e, eOpts, treeCombo)
          {
            var me = treeCombo;
            
            me.fixIds();
            
            me.setValue(me.ids.join(','));
        
        
            me.fireEvent('itemclick', me, record, item, index, e, eOpts, me.records, me.ids);
        
        
            if(me.multiselect == false) me.onTriggerClick();
          } 
        });
    any help helps, thx
    forgot to mention--there can be X number of rows which complicates this even further

  2. #2
    Sencha User joel.watson's Avatar
    Join Date
    Nov 2014
    Posts
    3,120
    Answers
    446
    Vote Rating
    187
      0  

    Default

    Hi Jack--

    Since you're implementing a custom component, I would suggest creating a test case that demonstrates the problem: https://fiddle.sencha.com

    Thanks
    Joel

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •