PDA

View Full Version : Is it possible to generate components dynamically in Ext.XTemplate from a datastore?



ktemur
27 Dec 2010, 4:03 PM
Hi my friends,

My problem is, i am reading an XML file into a datastore and then i want to display data in a panel as menu items.

I have an extended panel and normally i am adding items with this:


var menuPanel = new MenuPanelUi(Ext.get('menuPanelDiv'));
menuPanel.addMenuItem(0,'Menu Item 1', '/testproject/somepage.html');

My problem is how i can use this code in Ext.XTemplate?
I can print all data in data store with this code:


dataStore.on('load', function (store, records, options) {
var tpl = new Ext.XTemplate(
'<tpl for=".">',
'<li><a href="#">{values.data.MenuGroup}</a>',
'<ul>',
'<tpl for="values.data.Submenus">',
'<li><a href="{values.data.Url}">{values.data.Name}</a></li>',
'</tpl>',
'</ul>',
'</li>',
'</tpl>'
);
tpl.overwrite(Ext.get("menu"), dataStore.getRange());
});

But i need to use menuPanel.addMenuItem() in Ext.XTemplate.......So, do you have any idea about how i can make adding operation in this code dynmically?


And here is the full code:


MenuPanelUi = Ext.extend(Ext.Panel, {
width: '1200',
height: 40,
layout: 'hbox',
hideBorders: true,
frame: true,
id: 'menuPanel',
constructor: function(renderArea){
this.renderTo = renderArea;
MenuPanelUi.superclass.constructor.call(this, {
renderTo: renderArea
});
},
initComponent: function() {
this.layoutConfig = {
align: 'stretch'
};
this.items = [
{
xtype: 'container',
flex: 9,
items: [
{
xtype: 'splitbutton',
text: 'islemler',
width: 99,
height: 22,
menu: {
xtype: 'menu',
items: [

]
}
}
]
},
{
xtype: 'container',
flex: 1,
items: [
{
xtype: 'splitbutton',
text: 'cikis',
width: 74,
height: 22,
handler: clickHandler
}
]
}
];
MenuPanelUi.superclass.initComponent.call(this);
},
addMenuItem: function(index, title, url){
this.getMenu(0).add(new Ext.menu.Item({
text: title,
url: url,
listeners: {'click': this.menuItemClickHandler}
}))
},

menuItemClickHandler: function(){
location.href = this.url;
},
getMenu: function(index){
return this.items.get(0).items.get(index).menu;
},
getMenuButton: function(index){
return this.items.get(0).items.get(index);
}

});

function clickHandler(item, e) {
location.href = '/logout.jsp';
}

var menuPanel = new MenuPanelUi(Ext.get('menuPanelDiv'));
menuPanel.addMenuItem(0,'Menu item 1', '/test/someurl.html');




var submenuReader = new Ext.data.XmlReader({
record: 'Menu',
id: '@name',
fields: [
{name: 'Name', mapping: '@name'},
{name: 'Url', mapping: '@url'},
{name: 'Menu', mapping: '/'}
]
});

var dataStore = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: 'menu.xml',
method:'get'
}),
reader: new Ext.data.XmlReader({
record: 'Item',
id: 'MenuGroup',
fields: [
'MenuGroup',
{name: 'Submenus', convert: function(v, n){
return submenuReader.readRecords(n).records;
}}
]
})
});


dataStore.on('load', function (store, records, options) {
var tpl = new Ext.XTemplate(
'<tpl for=".">',
'<li><a href="#">{values.data.MenuGroup}</a>',
'<ul>',
'<tpl for="values.data.Submenus">',
//'menuPanel.addMenuItem(0,'Yeni Tesis', '/subscription/lineActivation/lineActivation.html?method=viewPage');,
'</tpl>',
'</ul>',
'</li>',
'</tpl>'
);

tpl.overwrite(Ext.get("menu"), dataStore.getRange());
});

dataStore.load();

Condor
28 Dec 2010, 1:03 AM
What is it you actually want?
1. Create components from data in a store and add them to a container.
or
2. Render the data in a store with a template and create components in the rendered HTML.

It looks like you want #1, but I'm not sure...

ktemur
28 Dec 2010, 1:23 AM
Hi Condor,

As you guessed, i need #1 - "Create components from data in a store and add them to a container"

I tried to tell - with "Ext.XTemplate" i can print this datastore as html. But i dont need this, i need a possibility to add data in a store into a container. Do you have any suggestion?

Condor
28 Dec 2010, 1:40 AM
OK, so you have a loaded store with fields 'MenuGroup' and 'Submenus' (which contains an array of records with 'Name', 'Url' and 'Menu' fields).

How do you want to use this data to build components (what kind of components and how to configure them)?

ktemur
28 Dec 2010, 1:56 AM
Hi again,

First of all, i read data from following xml:

<Item>
<MenuGroup >Menu Group 1</MenuGroup>
<Submenu>
<Menu name="Menu Item 1" url="/test/url1.jsp" />
<Menu name="Menu Item 2" url="/test/url2.jsp" />
</Submenu>
</Item>
<Item>
<MenuGroup >Menu Group 2</MenuGroup>
<Submenu>
<Menu name="Menu Item 3" url="/test/url1.jsp" />
<Menu name="Menu Item 4" url="/test/url2.jsp" />
</Submenu>
</Item>

I want to push this data into an extended Panel component. You can see details of this extended panel in my first post(MenuPanelUi).

Then i want to add data into this panel menuPanel.addMenuItem() function:

var menuPanel = new MenuPanelUi(Ext.get('menuPanelDiv'));
menuPanel.addMenuItem(0,'Menu Item 1', '/testproject/somepage.html');
menuPanel.addMenuItem(0,'Menu Item 2', '/testproject/somepage.html');
menuPanel.addMenuItem(0,'Menu Item 3', '/testproject/somepage.html');

Condor
28 Dec 2010, 2:16 AM
What are the 3 parameters of addMenuItem? And how are menugroups supposed to be added?

ktemur
28 Dec 2010, 2:23 AM
In this situation, menugroups will not be important.

First parameter of addMenuItem shows under which menu button this item will be added. In our case it is not important, will be always 0.
Just second and third parameter is important and they show menu name and url.

Condor
28 Dec 2010, 4:11 AM
But if you don't want to use the menugroup, then why create a store that reads it? It would be easier if you create a store that is using the submenuReader directly.

Now you have to use:

dataStore.on('load', function (store, records, options) {
store.each(function(record) {
Ext.each(record.get('Submenus'), function(record2){
menuPanel.addMenuItem(0, record2.get('Name'), record2.get('Url'));
});
});
});
Disclaimer: Completely untested code!

ktemur
28 Dec 2010, 4:43 AM
It is totally working!!!!

Again you saved the day, you are a great man Condor, thanks a lot..... :)