extjs navigation tree

Hello.
I am having difficulty in creating a "navigation" in extjs.  The point is for the user to select their destination in the tree and then the content area is populated with whatever they need to see.

Since the content is a collection of panels (such as datagrid) that will later get data from a PHP backend, I am trying to create the panels only once.  So for example if i click on 'subjects' for the first time, it will create the object for datagrid and load the data into it.  If i navigate away and then come back, there should be no point in re-creating the big objects, they just need to be re-populated.  In attempt to do that, i am keeping track of panels in 'panels' array. So, for example, panels['subjects'] corresponds to a grid that's loaded when clicking on 'subjects' in menu.

Right now I was only able to achieve one of two things: either grids would be added to content one after another (content would not clear for some reason) or the top one would not go away, just the bottom one.  I tried taking advantage of objects, such as arrays, being passed as references but I am still missing something.

How can I fix this so that navigation works properly while panels and grid objects are not unnecessarily re-created if were already created once, just re-populated??
Ext.onReady(function(){
    panels = new Array();
    var navigation = [
    {'text' : 'Courses', 'leaf' : false, 'children' :[
        {'text' : 'Levels', 'leaf' : true, 'module' : 'levels'},
        {'text' : 'Subjects', 'leaf' : true, 'module' : 'subjects'}
        ]
    },
    {'text' : 'Students', 'leaf' : false, 'children' :[
        {'text' : 'Manage', 'leaf' : true, 'module' : 'studentsManage'}
        ]
    },
    {'text' : 'Teachers', 'leaf' : false, 'children' :[
        {'text' : 'Manage', 'leaf' : true, 'module' : 'teachersManage'}
        ]
    }
    ];
    new Ext.Viewport({
    layout : 'border',
    items  : [
        navigation = new Ext.tree.TreePanel({
            id : 'navigation',
            region : 'west',
            title : 'Administration',
            width: 200,
            root: new Ext.tree.AsyncTreeNode({
                text : 'Administration',
                children: navigation
            }),
            lines: false,
            rootVisible: false
        }),
        content = new Ext.Container({
           region: 'center'
        }),
        {
             xtype: 'container',
             region: 'north',
             height: 50
        }
    ]

    });
    navigation.getSelectionModel().on({
    selectionchange: {
        scope: this, fn:function(selModel, node){
            var module = node.attributes["module"];
           content.removeAll();
          // module name will be = function name that creates it
          
            if(typeof(panels[module]) == 'undefined'){
            	panels[module] = new Array();
            }
            content.add(window[module](panels));
            content.doLayout();
        }
      }
    });
    
    levels = function(panel){
        // @todo remember that panels are created dynamically based on list from ZF
        // @todo from ZF
        subjectsData = [['1', 'primary'],['2', 'middle'],['3', 'high']];
        subjectsStore = new Ext.data.SimpleStore({
         fields: ['subject_id', 'subject_name']
        });

        subjectsStore.loadData(subjectsData);
        if(panel["levels"] == undefined){
           panel["levels"] = new Ext.grid.GridPanel({
            store: subjectsStore,
            columns: [
               {header: 'id', dataIndex: 'subject_id', hidden: true},
               {header: 'Primary', dataIndex: 'subject_name'}
            ],
            title: 'Levels',
            autoHeight: true
           });
        }

       
        return panel["levels"];
    }
    subjects = function(panel){       
        // @todo remember that panels are created dynamically based on list from ZF
        // @todo from ZF
        subjectsData = [['1', 'mathematics'],['2', 'physics'],['3', 'music']];
        subjectsStore = new Ext.data.SimpleStore({
         fields: ['subject_id', 'subject_name']
        });

        subjectsStore.loadData(subjectsData);
        if(panel["primary"] == undefined){
           panel["primary"] = new Ext.grid.GridPanel({
            store: subjectsStore,
            columns: [
               {header: 'id', dataIndex: 'subject_id', hidden: true},
               {header: 'Subject', dataIndex: 'subject_name'}
            ],
            title: 'Subjects',
            autoHeight: true
           });
        }

       
        return panel["primary"];
    }
});

Open in new window

LVL 11
AlexanderREnterprise Web DeveloperAsked:
Who is Participating?
 
elishnevskyCommented:
If you don't mind the rendered grids to remain in the DOM, you can use CardLayout for you center region and when a user clicks a tree node, check if this card container contains a component with a particular itemId, which you can make up from the xtype. If it is not there, then create it, add to the card container, set as active card and load. If it is there, just set as active and load.
0
 
AlexanderREnterprise Web DeveloperAuthor Commented:
Thanks, looks promising so far.

any particular reason why i get
content.setActiveItem is not a function?

0
 
AlexanderREnterprise Web DeveloperAuthor Commented:
Ext.onReady(function(){
    panels = new Array();
    var navigation = [
    {'text' : 'Courses', 'leaf' : false, 'children' :[
        {'text' : 'Levels', 'leaf' : true, 'module' : 'levels'},
        {'text' : 'Subjects', 'leaf' : true, 'module' : 'subjects'}
        ]
    },
    {'text' : 'Students', 'leaf' : false, 'children' :[
        {'text' : 'Manage', 'leaf' : true, 'module' : 'studentsManage'}
        ]
    },
    {'text' : 'Teachers', 'leaf' : false, 'children' :[
        {'text' : 'Manage', 'leaf' : true, 'module' : 'teachersManage'}
        ]
    }
    ];
    new Ext.Viewport({
    layout : 'border',
    items  : [
        navigation = new Ext.tree.TreePanel({
            id : 'navigation',
            region : 'west',
            title : 'Administration',
            width: 200,
            root: new Ext.tree.AsyncTreeNode({
                text : 'Administration',
                children: navigation
            }),
            lines: false,
            rootVisible: false
        }),
        content = new Ext.Container({
                layout: 'card',
           region: 'center',
           activeItem: 0,
           items:[{id: 'levels', html: 'ksfa'},{id: 'subjects', html: 'subjectsss'}]
        }),
        {
             xtype: 'container',
             region: 'north',
             height: 50
        }
    ]

    });
    navigation.getSelectionModel().on({
    selectionchange: {
        scope: this, fn:function(selModel, node){
              var module = node.attributes["module"];
//              content.add(window[module]);
              console.log(content.items);
              content.setActiveItem(1);
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
elishnevskyCommented:
Container doesn't have setActiveItem() method, its layout has it. So to call it you need to do content.layout.setActiveItem(1);
0
 
elishnevskyCommented:
Or better do content.getLayout().setActiveItem(1);
0
 
AlexanderREnterprise Web DeveloperAuthor Commented:
>>If you don't mind the rendered grids to remain in the DOM,
yes, that's exactly what I am looking for.
CardLayout greatly simplifies the code. Typical toolkit newbie problem not knowing what to use when.
And by doing
subjectsStore.loadData(subjectsData);
with updated data, later coming form PHP, grid automatically repopulates.

Now hopefully I can figure out how to keep track of dataStore objects as well so that browser does not have to re-create them every time either, just repopulate.  I'll ask again if I am stuck.
Thank you very much!!
Ext.onReady(function(){
   panels = new Array();
   var navigation = [
   {'text' : 'Courses', 'leaf' : false, 'children' :[
       {'text' : 'Levels', 'leaf' : true, 'module' : 'levels'},
       {'text' : 'Subjects', 'leaf' : true, 'module' : 'subjects'}
       ]
   },
   {'text' : 'Students', 'leaf' : false, 'children' :[
       {'text' : 'Manage', 'leaf' : true, 'module' : 'studentsManage'}
       ]
   },
   {'text' : 'Teachers', 'leaf' : false, 'children' :[
       {'text' : 'Manage', 'leaf' : true, 'module' : 'teachersManage'}
       ]
   }
   ];
   new Ext.Viewport({
   layout : 'border',
   items  : [
       navigation = new Ext.tree.TreePanel({
           id : 'navigation',
           region : 'west',
           title : 'Administration',
           width: 200,
           root: new Ext.tree.AsyncTreeNode({
               text : 'Administration',
               children: navigation
           }),
           lines: false,
           rootVisible: false
       }),
       content = new Ext.Panel({
             layout: 'card',
          region: 'center',
          activeItem: 0,
          items:[{id: 'test1', html: 'ksfa'},{id: 'test2', html: 'subjectsss'}]
       }),
       {
            xtype: 'container',
            region: 'north',
            height: 50
       }
   ]

   });
   navigation.getSelectionModel().on({
   selectionchange: {
       scope: this, fn:function(selModel, node){
           var module = node.attributes["module"];
           window[module](content);
       }
     }
   });

   levels = function(content){
       // @todo remember that panels are created dynamically based on list from ZF
       // @todo from ZF
       levelsData = [['1', 'primary'],['2', 'middle'],['3', 'high']];
       levelsStore = new Ext.data.SimpleStore({
        fields: ['subject_id', 'subject_name']
       });

       levelsStore.loadData(levelsData);
       
       levelsGrid = content.getComponent('levels');
       
       if(!levelsGrid){
       levelsGrid = new Ext.grid.GridPanel({
              id: 'levels',
           store: levelsStore,
           columns: [
              {header: 'id', dataIndex: 'subject_id', hidden: true},
              {header: 'Primary', dataIndex: 'subject_name'}
           ],
           title: 'Levels',
           autoHeight: true
       });
       content.add(levelsGrid);
       }
       content.layout.setActiveItem('levels')
   }
   subjects = function(content){
	// @todo remember that panels are created dynamically based on list from ZF
   // @todo from ZF
   subjectsData = [['1', 'mathematics'],['2', 'physics'],['3', 'music']];
   subjectsStore = new Ext.data.SimpleStore({
    fields: ['subject_id', 'subject_name']
   });
	
   subjectsStore.loadData(subjectsData);
   	
       subjectsGrid = content.getComponent('subjects');
       
       if(!subjectsGrid){
	      
	       subjectsGrid = new Ext.grid.GridPanel({
	           id: 'subjects',
	        store: subjectsStore,
	        columns: [
	           {header: 'id', dataIndex: 'subject_id', hidden: true},
	           {header: 'Subject', dataIndex: 'subject_name'}
	        ],
	        title: 'Subjects',
	        autoHeight: true
	       });
	       content.add(subjectsGrid);
       }
       content.layout.setActiveItem('subjects');
//        return subjects;
   }
});

Open in new window

0
 
AlexanderREnterprise Web DeveloperAuthor Commented:
from 3 days of hitting a wall to just a few more hours when knowing what to look for.
0
 
elishnevskyCommented:
You should consider making your own grid classes by extending GridPanel and defining remotely loaded stores in them.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.