PDA

View Full Version : appendChild in MVC accordion menu



lagodoy
1 Aug 2014, 8:00 AM
dear colleagues,

I'm trying to include more sub levels in accordion menu, but some menu items do not appear, what could be wrong?

this is a part of the JSON for you to understand

{
"text": "menu 1.5",
"iconCls": "user_red",
"leaf": false,
"items": [
{
"text": "menu 1.5.1",
"iconCls": "",
"leaf": true
, "className": ""
},
{
"text": "menu 1.5.2",
"iconCls": "",
"leaf": true
, "className": ""
}]

}

this example, item 1.5.2 will not appear on the menu, because it will be?

thank you in advance for help.

Gary Schlosberg
1 Aug 2014, 3:46 PM
From what you posted, I can't see anything that would cause that. Perhaps you could post some of your code, perhaps the menu code?

lagodoy
2 Aug 2014, 10:27 AM
Dear Gary,


the code is this:


Controller:



Ext.define('Sencha.controller.MenuAccordion', {
extend: 'Ext.app.Controller',

models: [
'MenuAccordionRoot',
'MenuAccordionItem'
],
stores: [
'MenuAccordion'
],
views: [
'MenuAccordion',
'MenuAccordionItem'
],

refs: [
{
ref: 'mainPanel',
selector: 'myviewport #mainPanel',
xtype: 'Ext.tab.Panel'
}
],

onPanelRender: function(component, eOpts) {


var recursiveMenuAccordionItems = function(items, menu) {
var parent = menu.appendChild({
text : items.text,
iconCls : items.iconCls,
className : items.className,
leaf : items.leaf
});

Ext.each(items.items, function(item){
recursiveMenuAccordionItems(item, parent);
});
};

this.getMenuAccordionStore().load(function(records, op, success){

var menuPanel = Ext.ComponentQuery.query('menu')[0];

Ext.each(records, function(root){

var menu = Ext.create('Sencha.view.MenuAccordionItem',{
title : root.get('title'),
iconCls : root.get('iconCls')
});

Ext.each(root.items(), function(itens){

Ext.each(itens.data.items, function(item){

var parent = menu.getRootNode().appendChild({
text : item.get('text'),
iconCls : item.get('iconCls'),
className : item.get('className'),
leaf : item.get('leaf')
});

if(item.raw.hasOwnProperty('items')){
recursiveMenuAccordionItems(item.raw.items[0], parent);
}

});
});

menuPanel.add(menu);
});
});
},

onTreepanelSelect: function(rowmodel, record, index, eOpts) {
Ext.Msg.alert('You selected the following menu item', record.get('text'));

console.log(record.raw.className);

var mainPanel = this.getMainPanel();

var newTab = mainPanel.items.findBy(
function (tab){
return tab.title === record.get('text');
}
);

if (!newTab){
newTab = mainPanel.add({
xtype: record.raw.className,
closable: true,
iconCls: record.get('iconCls'),
title: record.get('text')
});
}

mainPanel.setActiveTab(newTab);
},

init: function(application) {
this.control({
"menu": {
render: this.onPanelRender
},
"treepanel": {
select: this.onTreepanelSelect
}
});
}

});


model 1:



Ext.define('Sencha.model.MenuAccordionRoot', {
extend: 'Ext.data.Model',

requires: [
'Ext.data.Field',
'Ext.data.association.HasMany'
],
uses: [
'Sencha.model.MenuAccordionItem'
],

fields: [
{
name: 'title'
},
{
name: 'iconCls'
// },
// {
// name: 'id'
}
],

hasMany: {
model: 'Sencha.model.MenuAccordionItem',
// foreignKey: 'menu_id',
name: 'items'
}
});


model 2:



Ext.define('Sencha.model.MenuAccordionItem', {
extend: 'Ext.data.Model',

requires: [
'Ext.data.Field',
'Ext.data.association.BelongsTo'
],
uses: [
'Sencha.model.MenuAccordionRoot'
],

fields: [
{
name: 'text'
},
{
name: 'iconCls'
},
{
name: 'className'
},
{
name: 'leaf'
// },
// {
// name: 'items'

// },
// {
// name: 'id'
// },
// {
// name: 'menu_id'
}
],

belongsTo: {
model: 'Sencha.model.MenuAccordionRoot',
// foreignKey: 'menu_id'
}
});


store:



Ext.define('Sencha.store.MenuAccordion', {
extend: 'Ext.data.Store',

requires: [
'Sencha.model.MenuAccordionRoot',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],

constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
model: 'Sencha.model.MenuAccordionRoot',
storeId: 'MenuAccordionStore',
proxy: {
type: 'ajax',
url: 'data/menu.json',
reader: {
type: 'json',
root: 'items'
}
}
}, cfg)]);
}
});




view 1:



Ext.define('Sencha.view.MenuAccordion', {
extend: 'Ext.panel.Panel',
alias: 'widget.menu',

height: 432,
width: 251,
layout: 'accordion',
iconCls: 'home',
title: 'Menu',

initComponent: function() {
var me = this;

me.callParent(arguments);
}

});


view 2:



Ext.define('Sencha.view.MenuAccordionItem', {
extend: 'Ext.tree.Panel',
alias: 'widget.menuitem',

border: 0,
autoScroll: true,
title: '',
rootVisible: false,

initComponent: function() {
var me = this;

me.callParent(arguments);
}

});


json :



{"items":
[
{
"title": "Menu 1",
"iconCls": "folder_user"
, "items" :
[
{
"text": "Menu 1.1"
, "iconCls": "folder_user"
, "className" : ""
, "leaf" : true
, "id" : "11"
}
,{
"text": "Menu 1.2"
, "iconCls": "folder_user"
, "className" : ""
, "leaf" : true
}
,{
"text": "Menu 1.3"
, "iconCls": "folder_user"
, "className" : ""
, "leaf" : true
}
,{
"text": "Menu 1.4"
, "iconCls": "folder_user"
, "className" : ""
, "leaf" : false
, "items" :
[
{
"text": "Menu 1.4.1"
, "iconCls": "folder_user"
, "className" : ""
, "leaf" : true
}
,{
"text": "Menu 1.4.2"
, "iconCls": "folder_user"
, "className" : ""
, "leaf" : true
}
,{
"text": "Menu 1.4.3"
, "iconCls": "folder_user"
, "className" : ""
, "leaf" : true
}
]
}
,{
"text": "Menu 1.5"
, "iconCls": "folder_user"
, "className" : ""
, "leaf" : false
}
,{
"text": "Menu 1.6"
, "iconCls": "folder_user"
, "className" : ""
, "leaf" : true
}

]
},
{
"title": "Menu 2",
"iconCls": "computer",
},
{
"title": "Menu 3",
"iconCls": "table",
},
{
"title": "Menu 4",
"iconCls": "money",
}
]
}


I've tried several things, but I do not know why certain menu items do not appear, as the example of the json above, paragraph 1.4.2 and 1.4.3 do not appear.

I'm sorry I'm unable to send the screen image


I hope the code will help you to try to see what might be wrong.


thank you

skirtle
2 Aug 2014, 7:05 PM
So by 'MVC accordion menu' you actually mean 'tree'?

Reassigning the aliases of menu and menuitem is a really bad idea.

Trying to load tree data via associations seems unnecessarily complicated too.

However, this line seems an obvious candidate for the missing items:


recursiveMenuAccordionItems(item.raw.items[0], parent);

Put some console logging in recursiveMenuAccordionItems, it looks like you aren't calling appendChild for those items.

lagodoy
3 Aug 2014, 11:04 AM
Skirtle Hello, thanks for the reply. then I can not use tree menu in an accordion menu? I'd better use a tree menu?

I'm sorry I have not much experience, and not really understand what do you recommend doing in your last sentence (Put some console logging in recursiveMenuAccordionItems, it looks like you aren't calling appendChild for those items.).

Thanks again for the help

skirtle
3 Aug 2014, 11:42 AM
In ExtJS terminology a 'menu' is a very specific type of component, unrelated to an accordion or tree. You're making your question much harder to understand by referring to other components as menus. Your aliases (menu and menuitem) are also very dangerous as they duplicate the built-in aliases used by menus.

Console logging (via console.log) is a basic JavaScript debugging technique. You'll find plenty of info about it online. If you add suitable logging within that method I think you'll find it isn't being called for all of the items you're expecting.

The line I pointed out appears to be pulling out the first item from the array, which would explain your observation that only the first item is appearing in the UI.