PDA

View Full Version : problem in dynamically generating NestedList



yasodha
4 Jan 2011, 9:02 PM
Hi,
I'm new to sencha touch. I have a doubt in nestedList. I have used the same structure as of kitchen sink. Instead of static values i loaded the nestedlist dynamically. when i click on an item in the list it should display a HTML page. I have my code below.

Structure.js



Ext.regModel('Test', {
fields: [
{name: 'titl', type: 'string'},
{name:'id' , type:'int'},
{name:'html'}

]
});

sink.StructureStore = new Ext.data.TreeStore({
model: 'Test',
proxy:new Ext.data.AjaxProxy({
url: 'test1.json',
reader:{
type:'tree',
root:'index'
}
})
});




index.js



Ext.ns('sink', 'demos', 'Ext.ux');
var i=0;
Ext.ux.UniversalUI = Ext.extend(Ext.Panel, {
fullscreen: true,
layout: 'card',
items: [{ cls: 'launchscreen',
html: '<div><img src="resources/img/sencha.png" width="210" height="291" /><h1>Welcome to Sencha Touch</h1><p>This is a comprehensive collection of our examples in an <br /> easy-to-navigate format. Each sample has a “view source” button which dynamically displays its associated code.<br /><br /><span>Sencha Touch (' + Ext.version +')</span></p></div>'
}],
backText: 'Back',
useTitleAsBackText: true,
initComponent : function() {
this.navigationButton = new Ext.Button({
hidden: Ext.is.Phone || Ext.Viewport.orientation == 'landscape',
text: 'Navigation',
handler: this.onNavButtonTap,
scope: this
});
this.backButton = new Ext.Button({
text: this.backText,
ui: 'back',
handler: this.onUiBack,
hidden: true,
scope: this
});
var btns = [this.navigationButton];
if (Ext.is.Phone) {
btns.unshift(this.backButton);
}
this.navigationBar = new Ext.Toolbar({
ui: 'dark',
dock: 'top',
title: this.title,
items: btns.concat(this.buttons || [])
});
this.navigationPanel = new Ext.NestedList({
store: sink.StructureStore,
useToolbar: Ext.is.Phone ? false : true,
updateTitleText: false,
displayField:"titl",
dock: 'left',
plugins: [new Ext.LeafSelectedPlugin()],
hidden: !Ext.is.Phone && Ext.Viewport.orientation == 'portrait',
toolbar: Ext.is.Phone ? this.navigationBar : null,
getDetailCard: function(item, parent) {
detailCard = new Ext.Panel({

});

},
listeners: {
itemtap: this.onNavPanelItemTap,
leafitemtap:this.leafTap,
scope: this
}
});
this.navigationPanel.on('leafselected', function(enabled) {

});

this.navigationPanel.on('back', this.onNavBack, this);
if (!Ext.is.Phone) {
this.navigationPanel.setWidth(250);
}
this.dockedItems = this.dockedItems || [];
this.dockedItems.unshift(this.navigationBar);
if (!Ext.is.Phone && Ext.Viewport.orientation == 'landscape') {
this.dockedItems.unshift(this.navigationPanel);
}
else if (Ext.is.Phone) {
this.items = this.items || [];
this.items.unshift(this.navigationPanel);
}
this.addEvents('navigate');

Ext.ux.UniversalUI.superclass.initComponent.call(this);
},



onNavPanelItemTap: function(subList, subIdx, el, e) {

var store = subList.getStore(),
record = store.getAt(subIdx),
recordNode = record.node,
nestedList = this.navigationPanel,
title = nestedList.renderTitleText(recordNode),
card, preventHide, anim;
var parentNode=recordNode?recordNode.parentNode:null;

if(recordNode.leaf){

card=nestedList.getDetailCard(recordNode,parentNode);

}


if (Ext.Viewport.orientation == 'portrait' && !Ext.is.Phone && !recordNode.childNodes.length && !preventHide) {
this.navigationPanel.hide();
}
if (card) {
this.setActiveItem(card, 'slide');
this.currentCard = card;
}

if (title) {
this.navigationBar.setTitle(title);
}
this.toggleUiBackButton();
this.fireEvent('navigate', this, record);
},

toggleUiBackButton: function() {
var navPnl = this.navigationPanel;
if (Ext.is.Phone) {
if (this.getActiveItem() === navPnl) {
var currList = navPnl.getActiveItem(),
currIdx = navPnl.items.indexOf(currList),
recordNode = currList.recordNode,
title = navPnl.renderTitleText(recordNode),
parentNode = recordNode ? recordNode.parentNode : null,
backTxt = (parentNode && !parentNode.isRoot) ? navPnl.renderTitleText(parentNode) : this.title || '',
activeItem;

if (currIdx <= 0) {
this.navigationBar.setTitle(this.title || '');
this.backButton.hide();
} else {
this.navigationBar.setTitle(title);
if (this.useTitleAsBackText) {
this.backButton.setText(backTxt);
}
this.backButton.show();
}
// on a demo
} else {
activeItem = navPnl.getActiveItem();
recordNode = activeItem.recordNode;
backTxt = (recordNode && !recordNode.isRoot) ? navPnl.renderTitleText(recordNode) : this.title || '';
if (this.useTitleAsBackText) {
this.backButton.setText(backTxt);
}
this.backButton.show();
}
this.navigationBar.doLayout();
}
},
onUiBack: function() {
var navPnl = this.navigationPanel;
// if we already in the nested list
if (this.getActiveItem() === navPnl) {
navPnl.onBackTap();
// we were on a demo, slide back into
// navigation
} else {
this.setActiveItem(navPnl, {
type: 'slide',
reverse: true
});
}
this.toggleUiBackButton();
this.fireEvent('navigate', this, {});
},


crd:function(){
alert("hi");
},
onNavButtonTap : function() {
this.navigationPanel.showBy(this.navigationButton, 'fade');
},
layoutOrientation : function(orientation, w, h) {
if (!Ext.is.Phone) {
if (orientation == 'portrait') {
this.navigationPanel.hide(false);
this.removeDocked(this.navigationPanel, false);
if (this.navigationPanel.rendered) {
this.navigationPanel.el.appendTo(document.body);
}
this.navigationPanel.setFloating(true);
this.navigationPanel.setHeight(400);
this.navigationButton.show(false);
}
else {
this.navigationPanel.setFloating(false);
this.navigationPanel.show(false);
this.navigationButton.hide(false);
this.insertDocked(0, this.navigationPanel);
}
this.navigationBar.doComponentLayout();
}
Ext.ux.UniversalUI.superclass.layoutOrientation.call(this, orientation, w, h);
}
});
sink.Main = {
init : function() {

this.ui = new Ext.ux.UniversalUI({
title: Ext.is.Phone ? 'P&G' : 'P&G Brands',
useTitleAsBackText: false

});
}



};
Ext.setup({

onReady: function() {
sink.Main.init();
}
});
Ext.ns('demos', 'demos.Data');



test1.json




{
"titl":"Test",
"index":[{
"titl":"cv",
"id":1,
"index":[{
"titl":"sencha",
"html":"1",
"leaf": true
},
{ "titl":"senchatouch",
"html":"1",
"leaf": true
}]
},
{
"titl":"fg",
"id":2,
"index":[{
"titl":"Ext",
"html":"2",
"leaf": true
},{
"titl":"Extjs",
"html":"2",
"leaf": true
}]
},
{
"titl":"zdfvvff",
"id":3,
"index":[{
"titl":"soft",
"html":"3",
"leaf": true
},
{
"titl":"softer",
"html":"3",
"leaf": true
}]
}
]


}






I have attached the files also. someone please help to display it.
Thanks in advance..

gcallaghan
5 Jan 2011, 5:44 PM
The components seem mixed up in this code, for example
you have...


Ext.ux.UniversalUI = Ext.extend(Ext.Panel, {
...
seTitleAsBackText: true,

seTitleAsBackText is an attribute of a nested list, not a Panel.


the kitchen sink is a fairly complicated example, but the general method is when a leaf item is tapped, set/update the active item on a remote panel with a card layout. I'd suggest you first get a nested list working with logs to the console saying that you have indeed hit a leaf item. then layout the nav panel and the content panel. Finally, update a card in the content panel with data from the leaf record.

Rather than trying to imitate the kitchen sink whole hog, it might be better if you started at the component level first and built your way of from there.

yasodha
5 Jan 2011, 8:12 PM
Thanks for the reply gcallaghan. I found out the when it s hitting the leaf item. i don't know to set/update the active item on the remote panel with card layout. can u pls help me out with the code..
In the json file instead of html if i give card will it accept and move to that..
for example:-
card:demos.tabs,
source:'src/demos/tabs.js'

gcallaghan
6 Jan 2011, 3:12 PM
So, adding the card to the json simply provides a reference to an already created card. You can have all those cards created and when a leaf node is selected you still need to set the active item on the remote panel. You can accomplish this several ways.

1. add the remote panel as an injected dependency and set the active item using a listener for leafitemtap in the nested list


myMainPanel = Ext.Panel({
...
initComponent:function(){
this.contentPanel = new Ext.Panel({layout:'card,items:[{xtype:'panel'}]}...
this.nestedListNav =new Ext.NestedList({

listeners:{
leafitemtap:function(sublist,subidx,el,e,card){
this.remotePanel.setActiveItem(subList.getSTore().getAt(subidx).card); //assumes there is a reference to the card in the record like in your last response
}
}
...
});
this.nestedListNav.remotePanel = this.contentPanel;
this.add(nestListNav);
this.add(contentPanel);
}


2. bubble up the leafitemtap event and use a listener there to set/update the active item in the other child content panel. So instead of the listener being in the leaf item, add the listener to the main container..


listeners:{
leafitemtap:function(sublist,subidx,el,e,card){
this.contentPanel.setActiveItem(subList.getStore().getAt(subidx).card); //assumes there is a reference to the card in the record like in your last response
}
}
initComponent:function(){
...
this.nestedListNav.enableBubble('leafitemtap');
...
}

yasodha
24 Jan 2011, 8:16 PM
Thanks for the reply. Its working perfectly.