We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 10378
    • 375 Posts
    Hello,

    In my custom manager page (for the upcoming GoodNews add-on) I have an ExtJS grid which lists users from the MODx user table. The window to edit those users holds an ExtJS checkbox tree panel (=MODx tree) where you can assign values from nodes and sub-nodes to the selected user by checking/unchecking the related checkboxes. The selected node ids are written to a custom db table.

    As you can see, the data is coming from a processor which works fine.

    The problem I have is:

    the tree only gets rendered once and when I try to edit another user from the grid the tree isn't filled with the new values from the selected user. Instead it represents checked/unchecked statuses from first edited user.

    How can I force the tree to load new values if the window is opened again - corresponding to the selected grid item (user)?

    Thanks in advance for your time! I really hope someone could help me, as I struggle with this problem for 2 days now...
    -- Martin


    Here is the full source (with tree element, grid and window):

    GoodNews.tree.GroupsCategories = function(config) {
        config = config || {};
        
        Ext.applyIf(config,{
            id: 'goodnews-tree-groupscategories'
            ,url: GoodNews.config.connectorUrl
            ,action: 'mgr/groups/getGroupCatNodes'
            ,autoHeight: false
            ,height: Ext.getBody().getViewSize().height*.30
            ,root_id: 'n_gongrp_0'
            ,root_name: _('goodnews.subscriber_groups_categories')
            ,rootVisible: false
            ,enableDD: false
            ,ddAppendOnly: true
            ,useDefaultToolbar: true
            ,stateful: false
            ,collapsed: false
            ,cls: 'gon-tree-groupscategories'
            ,listeners: {
                'checkchange': function(node,checked){
                    // check parent node (group) if child (category) is checked
                    if(checked){
                        pn = node.parentNode;
                        pn.getUI().toggleCheck(checked);
                    // uncheck all child (category) nodes if parent (group) is unchecked
                    }else{
                        node.eachChild(function(n) {                    
                            n.getUI().toggleCheck(checked);
                        });
                    }
                }
            }
        });
        GoodNews.tree.GroupsCategories.superclass.constructor.call(this,config);
        this.expandAll();
    };
    Ext.extend(GoodNews.tree.GroupsCategories,MODx.tree.Tree);
    Ext.reg('goodnews-tree-groupscategories',GoodNews.tree.GroupsCategories);
    
    
    GoodNews.panel.Subscribers = function(config) {
        config = config || {};
        
        Ext.applyIf(config,{
            id: 'goodnews-panel-subscribers'
            ,title: _('goodnews.subscribers')   
            ,defaults: { 
                border: false 
            }
            ,items:[{
                html: '<p>'+_('goodnews.subscribers_desc')+'</p>'
                ,border: false
                ,bodyCssClass: 'panel-desc'
            },{
                xtype: 'goodnews-grid-subscribers'
                ,cls: 'main-wrapper'
                ,preventRender: true
            }]    
        });
        GoodNews.panel.Subscribers.superclass.constructor.call(this,config);
    };
    Ext.extend(GoodNews.panel.Subscribers,Ext.Panel);
    Ext.reg('goodnews-panel-subscribers',GoodNews.panel.Subscribers);
    
    
    GoodNews.grid.Subscribers = function(config){
        config = config || {};
    
        Ext.applyIf(config,{
            id: 'goodnews-grid-subscribers'
            ,url: GoodNews.config.connectorUrl
            ,baseParams: { action: 'mgr/subscribers/getList' }
            ,fields: [
                'id'
                ,'username'
                ,'fullname'
                ,'email'
                ,'groups'
                ,'categories'
                ,'testdummy'
                ,'menu'
            ]
            ,emptyText: _('goodnews.subscribers_none')
            ,paging: true
            ,remoteSort: true
            ,columns: [{
                header: _('goodnews.subscriber_username')
                ,dataIndex: 'username'
                ,sortable: true
                ,width: 100
            },{
                header: _('goodnews.subscriber_fullname')
                ,dataIndex: 'fullname'
                ,sortable: true
                ,width: 100
            },{
                header: _('goodnews.subscriber_email')
                ,dataIndex: 'email'
                ,sortable: true
                ,width: 100
            },{
                header: _('goodnews.subscriber_testdummy')
                ,dataIndex: 'testdummy'
                ,sortable: false
                ,width: 80
                ,renderer: function(value){
                    switch (value){
                        case '0':
                            return '<span class="gon-testdummy-no">'+_('no')+'</span>';
                            break;
                        case '1':
                            return '<span class="gon-testdummy-yes">'+_('yes')+'</span>';
                            break;
                        default:
                            return value;
                    }
                }
            }]
            ,tbar:[{
               text: _('goodnews.modx_user_create')
               ,handler: this.createSubscriber
               ,scope: this
            },'->',{
                xtype: 'modx-combo'
                ,id: 'goodnews-subscribers-group-filter'
                ,emptyText: _('goodnews.subscribers_user_group_filter')
                ,width: 200
                ,listWidth: 200
                ,displayField: 'name'
                ,valueField: 'id'
                ,store: new Ext.data.JsonStore({
                    url: GoodNews.config.connectorUrl
                    ,baseParams: {
                        action : 'mgr/groups/getGroupFilterList'
                        ,addNoGroupOption: true
                    }
                    ,fields: ['id','name']
                    ,root: 'results'
                })
                ,listeners: {
                    'select': {fn:this.filterByUserGroup,scope:this}
                }
            },'-',{
                xtype: 'modx-combo'
                ,id: 'goodnews-subscribers-testdummy-filter'
                ,emptyText: _('goodnews.subscriber_testdummy_filter')
                ,width: 150
                ,listWidth: 150
                ,displayField: 'yesno'
                ,valueField: 'id'
                ,mode: 'local'
                ,store: new Ext.data.ArrayStore({
                    fields: ['id','yesno']
                    //there is a problem using 0/1 or false/true combination for id field
                    ,data: [['nodummy',_('no')],['isdummy',_('yes')]]
                })
                ,listeners: {
                    'select': {fn:this.filterByTestDummy,scope:this}
                }
            },'-',{
                xtype: 'textfield'
                ,id: 'goodnews-subscribers-search-filter'
                ,emptyText: _('goodnews.input_search_filter')
                ,listeners: {
                    'change': {fn:this.search,scope:this}
                    ,'render': {fn: function(cmp) {
                        new Ext.KeyMap(cmp.getEl(), {
                            key: Ext.EventObject.ENTER
                            ,fn: function() {
                                this.fireEvent('change',this);
                                this.blur();
                                return true;
                            }
                            ,scope: cmp
                        });
                    },scope:this}
                }
            },{
                xtype: 'button'
                ,id: 'goodnews-subscribers-filter-clear'
                ,text: _('goodnews.button_filter_clear')
                ,listeners: {
                    'click': {fn: this.clearFilter,scope:this}
                }
            }]
        });
        GoodNews.grid.Subscribers.superclass.constructor.call(this,config);
    };
    Ext.extend(GoodNews.grid.Subscribers,MODx.grid.Grid,{
        getMenu: function() {
            var r = this.getSelectionModel().getSelected();
            var p = r.data.perm;
    
            return [{
                text: _('goodnews.subscriber_update')
                ,handler: this.updateSubscriber
            },'-',{
                text: _('goodnews.user_update')
                ,handler: this.updateUser
            }];
        }
        ,createSubscriber: function(btn,e) {
            var createUser = MODx.action ? MODx.action['security/user/create'] : 'security/user/create';
            location.href = 'index.php?a='+createUser;
        }
        ,updateSubscriber: function(btn,e) {
            if (!this.updateSubscriberWindow) {
                this.updateSubscriberWindow = MODx.load({
                    xtype: 'goodnews-window-subscriber-update'
                    ,record: this.menu.record
                    ,listeners: {
                        'success': {fn:this.refresh,scope:this}
                    }
                });
            }
            this.updateSubscriberWindow.setValues(this.menu.record);
            this.updateSubscriberWindow.show(e.target);
        }
        ,updateUser: function(btn,e) {
            location.href = 'index.php?a='+MODx.action['security/user/update']+'&id='+this.menu.record.id;
        }
        ,filterByUserGroup: function(combo) {
            var s = this.getStore();
            s.baseParams.groupfilter = combo.getValue();
            this.getBottomToolbar().changePage(1);
            this.refresh();
        }
        ,filterByTestDummy: function(combo) {
            var s = this.getStore();
            s.baseParams.testdummyfilter = combo.getValue();
            this.getBottomToolbar().changePage(1);
            this.refresh();
        }
        ,search: function(tf,nv,ov) {
            var s = this.getStore();
            s.baseParams.query = tf.getValue();
            this.getBottomToolbar().changePage(1);
            this.refresh();
        }
        ,clearFilter: function() {
        	this.getStore().baseParams = {
                action: 'mgr/subscribers/getList'
        	};
            Ext.getCmp('goodnews-subscribers-group-filter').reset();
            Ext.getCmp('goodnews-subscribers-testdummy-filter').reset();
            Ext.getCmp('goodnews-subscribers-search-filter').reset();
        	this.getBottomToolbar().changePage(1);
        }
    });
    Ext.reg('goodnews-grid-subscribers',GoodNews.grid.Subscribers);
    
    
    GoodNews.window.UpdateSubscriptions = function(config) {
        config = config || {};
    
        Ext.applyIf(config,{
            title: _('goodnews.subscriber_update')
            ,width: 480
            ,url: GoodNews.config.connectorUrl
            ,baseParams: {
                action: 'mgr/subscribers/update'
            }
            /*
            ,listeners: {
                'beforeSubmit': {fn: this.getCheckedGrpCat(), scope: this}
            }
            */
            ,fields: [{
                xtype: 'hidden'
                ,name: 'id'
            },{
                xtype: 'textfield'
                ,fieldLabel: _('goodnews.subscriber_username')
                ,name: 'username'
                ,readOnly: true
                ,anchor: '100%'
            },{
                xtype: 'goodnews-tree-groupscategories'
                ,fieldLabel: _('goodnews.subscriber_groups_categories')
                ,preventRender: false
            },{
                //todo: if using xcheckbox the checked status isn't set. Why?
                xtype: 'checkbox'
                ,hideLabel: true
                ,boxLabel: _('goodnews.subscriber_select_as_testdummy')
                ,name: 'testdummy'
                ,inputValue: '1'
            }]
        });
        GoodNews.window.UpdateSubscriptions.superclass.constructor.call(this,config);
    };
    Ext.extend(GoodNews.window.UpdateSubscriptions,MODx.Window,{
        getCheckedGrpCat: function(){
            var grpIDs = '';
            var catIDs = '';
            var selNodes = tree.GroupsCategories.getChecked();
            Ext.each(selNodes, function(node){
                if(grpIDs.length > 0){
                    grpIDs += ',';
                }
                grpIDs += node.id;
            });
            console.log('grpIDs: '+grpIDs);
        }
    
    });
    Ext.reg('goodnews-window-subscriber-update',GoodNews.window.UpdateSubscriptions);
    

    This question has been answered by gadgetto. See the first response.

    [ed. note: gadgetto last edited this post 13 years, 5 months ago.]
      Freelancer @bitego http://www.bitego.com
      ---
      GoodNews - one of the most advanced and integrated Group Mailer premium add-ons for MODX Revolution!
      More infos here: http://www.bitego.com/extras/goodnews/
      • 11055 ☆ A M B ☆
      • 3,112 Posts
      When you update the other panel, try to refresh the store of the tree.
      Probably something like this
          var refreshTree = function(){
              var groupsCategoriesTree = Ext.getCmp('goodnews-tree-groupscategories');
              return groupsCategoriesTree.getLoader().load(groupsCategoriesTree.root);
          }
      

      Untested, but taken from my work.
        Rico
        Genius is one percent inspiration and ninety-nine percent perspiration. Thomas A. Edison
        MODx is great, but knowing how to use it well makes it perfect!

        www.virtudraft.com

        Security, security, security! | Indonesian MODx Forum | MODx Revo's cheatsheets | MODx Evo's cheatsheets

        Author of Easy 2 Gallery 1.4.x, PHPTidy, spieFeed, FileDownload R, Upload To Users CMP, Inherit Template TV, LexRating, ExerPlan, Lingua, virtuNewsletter, Grid Class Key, SmartTag, prevNext

        Maintainter/contributor of Babel

        Because it's hard to follow all topics on the forum, PING ME ON TWITTER @_goldsky if you need my help.
      • discuss.answer
        • 10378
        • 375 Posts
        Thanks @goldsky - in meantime Mark Hamstra gave me the final hint:

        Line 206-218 from the above code is now replaced with:

            ,updateSubscriber: function(btn,e) {
                updateSubscriberWindow = MODx.load({
                    xtype: 'goodnews-window-subscriber-update'
                    ,record: this.menu.record
                    ,listeners: {
                        'success': {fn:this.refresh,scope:this}
                    }
                });
                updateSubscriberWindow.setValues(this.menu.record);
                updateSubscriberWindow.show(e.target);
            }
        


        Now the window isn't reused every time! Instead, a new window is created and so the tree is also refreshed with new values.

        I also added the

                ,closeAction: 'close'
        


        property to the window object, so that it's destroyed every time.
          Freelancer @bitego http://www.bitego.com
          ---
          GoodNews - one of the most advanced and integrated Group Mailer premium add-ons for MODX Revolution!
          More infos here: http://www.bitego.com/extras/goodnews/
          • 39194
          • 149 Posts
          By the way I don't think you need to setValues if you pass your record to constructor (via MODx.load)
            • 10378
            • 375 Posts
            Quote from: danya_postfactum at Apr 28, 2013, 10:19 AM
            By the way I don't think you need to setValues if you pass your record to constructor (via MODx.load)

            I removed the setValues part - but without the values aren't set.
              Freelancer @bitego http://www.bitego.com
              ---
              GoodNews - one of the most advanced and integrated Group Mailer premium add-ons for MODX Revolution!
              More infos here: http://www.bitego.com/extras/goodnews/