Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

extjs navigation tree

Posted on 2009-12-29
8
Medium Priority
?
2,413 Views
Last Modified: 2013-11-11
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

0
Comment
Question by:AlexanderR
  • 4
  • 4
8 Comments
 
LVL 2

Accepted Solution

by:
elishnevsky earned 2000 total points
ID: 26151964
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
 
LVL 11

Author Comment

by:AlexanderR
ID: 26154936
Thanks, looks promising so far.

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

0
 
LVL 11

Author Comment

by:AlexanderR
ID: 26154939
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 2

Expert Comment

by:elishnevsky
ID: 26155402
Container doesn't have setActiveItem() method, its layout has it. So to call it you need to do content.layout.setActiveItem(1);
0
 
LVL 2

Assisted Solution

by:elishnevsky
elishnevsky earned 2000 total points
ID: 26155438
Or better do content.getLayout().setActiveItem(1);
0
 
LVL 11

Author Comment

by:AlexanderR
ID: 26156729
>>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
 
LVL 11

Author Closing Comment

by:AlexanderR
ID: 31670826
from 3 days of hitting a wall to just a few more hours when knowing what to look for.
0
 
LVL 2

Expert Comment

by:elishnevsky
ID: 26156748
You should consider making your own grid classes by extending GridPanel and defining remotely loaded stores in them.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In my daily work (mainly using ASP.net), I need to write a lot of JavaScript code. One of the most repetitive tasks I do are the jQuery Ajax calls. You know: (CODE) I don't know if for you it's the same, but for me is soooo tedious to write the …
In Part 1 (http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/A_7849-Hex-Maze.html) we covered the hexagonal maze basics -- how the cells are represented in a JavaScript array and how the maze is displayed.  In this part, we'…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…
Suggested Courses

580 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question