How to Embed a NestedList in a TabPanel? - sencha-touch-2

I'm trying to create a tabpanel view that contains a splitview controller on the first tab. Think "kitchen sink" demo placed into one tab of a tabpanel.
The others do not contain the nestedlist.
http://dev.sencha.com/deploy/touch/examples/production/kitchensink/
I've tried placing the nestedlist into a container, which you can see in some of the commented code shown below.
At the moment, this working code only shows the nestlist taking up the entire section on the first tab:
Ext.application({
name: 'Test',
requires: [
'Ext.dataview.NestedList',
'Ext.navigation.Bar'
],
launch: function() {
Ext.create("Ext.TabPanel", {
fullscreen: true,
tabBarPosition: 'bottom',
items: [{
id: 'tab4',
title: 'Tab4',
iconCls: 'star',
xtype: 'container',
items: [{
xtype: 'nestedlist',
displayField: 'text',
docked: 'left',
store: store
}, {
html: 'Detail View'
}]
}, {
id: 'tab2',
title: 'Tab2',
iconCls: 'star',
html: 'No nav bar?'
}, {
id: 'tab3',
title: 'Tab3',
iconCls: 'star',
html: 'Screen3'
}]
}).setActiveItem(0);
}
});
Store setup:
Ext.Loader.setConfig({ enabled: true });
var data = {
text: 'Groceries',
items: [{
text: 'Drinks',
items: [{
text: 'Water',
items: [{
text: 'Sparkling',
leaf: true
},{
text: 'Still',
leaf: true
}]
},{
text: 'Coffee',
leaf: true
},{
text: 'Espresso',
leaf: true
},{
text: 'Redbull',
leaf: true
},{
text: 'Coke',
leaf: true
},{
text: 'Diet Coke',
leaf: true
}]
},{
text: 'Fruit',
items: [{
text: 'Bananas',
leaf: true
},{
text: 'Lemon',
leaf: true
}]
},{
text: 'Snacks',
items: [{
text: 'Nuts',
leaf: true
},{
text: 'Pretzels',
leaf: true
}, {
text: 'Wasabi Peas',
leaf: true
}]
}
]};
Ext.define('ListItem', {
extend: 'Ext.data.Model',
config: {
fields: [{
name: 'text',
type: 'string'
}]
}
});
var store = Ext.create('Ext.data.TreeStore', {
model: 'ListItem',
defaultRootProperty: 'items',
root: data
});

Okay. I have created this example for you: http://www.senchafiddle.com/#ynn40
You can also download the whole source from here: http://rwd.me/FG5s (quite large as it includes the SDK)
Be sure to look through all the files as I have added lots of documentation.
Some notes:
I created a new component called Sencha.view.SplitView. This obviously can be called anything. It has a xtype of splitview so we can simply just require it and include it into our Main.js file (which is a Ext.tab.Panel.
{
xtype: 'splitview',
title: 'SplitView',
store: 'Items'
}
Because this is an item inside a tabPanel, we need to give it the title configuration too. Of course we could include this Splitview component anywhere.
As you can see it has a store configuration which is defined in SplitView:
config: {
/**
* We create a custom config called store here so we can pass the store from this component
* (SplitView) down into the nested list when it updates. Checkout {#link #updateStore}
* #type {Ext.data.Store}
*/
store: null
}
This is used to pass the store from the splitview to the nested list (we will get to that in a second). Of course that configuration will do nothing unless we add the appropriate methods to update the nested list:
/**
* This is called when the {#link #store} config has been updated.
* We simply check if the nested list has been created, and if it has, set the store
* on it with the new value.
*/
updateStore: function(newStore) {
if (this.nestedList) {
this.nestedList.setStore(newStore);
}
}
As you can see, we are simply updating the nestedList (if it exists) store with the new value of the SplitView store.
Inside the initialize method of SplitView, we created both the detailContainer (where the detail card of the nested list should go) and the nestedList and then add them to the SplitView. Make sure you look at some of the configurations that we give nestedList as they are important. The store configuration:
// Set the store of this nested list to the store config of this component (Splitview)
store: this.getStore()
The detailCard and detailContainer configurations:
// Tell the nested list to have a detail card and put it inside our new detailContinaer
detailCard: true,
detailContainer: this.detailContainer
And of course the listeners so we know when things get changed:
// And finally add a listener so we know when to update the detail card
listeners: {
scope: this,
leafitemtap: this.onLeafItemTap
}
Finally we add the onLeadItemTap method into the Splitview (we added the listener above) which should update the detail card with new information:
/**
* This is called when a leaf item is tapped in the nested list, or when the detail card
* should be updated. In here, we just get the record which was tapped and then set the HTML
* of the detail card.
*/
onLeafItemTap: function(nestedList, list, index, node, record, e) {
var detailCard = nestedList.getDetailCard();
detailCard.setHtml(record.get('text'));
}
Hopefully this makes sense and helps you. If not, let me know.

Related

Sencha Touch 2: Add NestedList inside TabPanel

I try to insert a NestedList in a TabPanel, but I get an empty list, the content is not displayed. How to make visible this Neestedlist
Code I tried:
Thank you in advance for your help
Ext.define('ListItem', {
extend: 'Ext.data.Model',
config: {
fields: ['text']
}
});
var treeStore = Ext.create('Ext.data.TreeStore', {
model: 'ListItem',
defaultRootProperty: 'items',
root: {
items: [
{
text: 'Drinks',
items: [
{
text: 'Water',
items: [
{ text: 'Still', leaf: true },
{ text: 'Sparkling', leaf: true }
]
},
{ text: 'Soda', leaf: true }
]
},
{
text: 'Snacks',
items: [
{ text: 'Nuts', leaf: true },
{ text: 'Pretzels', leaf: true },
{ text: 'Wasabi Peas', leaf: true }
]
}
]
}
});
Ext.create('Ext.NestedList', {
fullscreen: true,
store: treeStore
});
Ext.application({
name: 'Sencha',
launch: function() {
// The whole app UI lives in this tab panel
Ext.Viewport.add({
requires: ['Ext.List', 'Ext.dataview.List', 'Ext.data.proxy.JsonP'],
xtype: 'tabpanel',
fullscreen: true,
tabBarPosition: 'bottom',
items: [
// This is the recent blogs page. It uses a tree store to load its data from blog.json.
{
xtype: 'nestedlist',
title: 'Blog',
iconCls: 'star',
cls: 'blog',
displayField: 'title',
store: treeStore
}
]
});
}
});
At the bottom of your provided code, in the Nested List you are creating, you are setting a displayfield property with a value of "title". Therefore the list is trying to use the "title" field from your model, which does not exist. Either change your store data to use "title" instead of "text", or remove the displayField property (as the default is already "text").

Rendering a List in a Panel

I have a Panel where I render a search-form. This works.
My problem is rendering a List under that search-form (so in the same Panel).
This is what I've done so far:
Ext.define("TCM.view.UserSearch",
{
extend: "Ext.form.Panel",
requires:
[
"Ext.form.FieldSet",
"Ext.List"
],
xtype: "usersearch",
config:
{
scrollable:'vertical'
},
initialize: function ()
{
this.callParent(arguments);
var clubsStore = Ext.create('TCM.store.Clubs');
clubsStore.load();
var usersStore = Ext.create('TCM.store.Users');
var searchButton =
{
xtype: 'button',
ui: 'action',
text: 'Search',
handler: this.onSearchButtonTap,
scope: this
};
var topToolbar =
{
xtype: 'toolbar',
docked: 'top',
title: 'Search',
items: [
{ xtype: 'spacer' },
searchButton
]
};
var userClub =
{
xtype: 'selectfield',
store: clubsStore,
name: 'clubId',
label: 'Club',
displayField : 'name',
valueField : 'id',
required: true
};
var userList =
{
xtype: 'list',
store: usersStore,
itemTpl: '{name}',
title: 'Search results'
};
this.add([
topToolbar,
{
xtype: "fieldset",
items: [userClub]
},
userList
]);
},
onSearchButtonTap: function ()
{
console.log("searchUserCommand");
this.fireEvent("searchUserCommand", this);
}
});
I can't see anything being rendered under the fieldset (the searchform). What could be wrong?
Most of time, when you don't see a component it's because you did not set a layout to your container or a height.
You can find more about layout here.
In your case, you want to have two components in your container. Therefore, I suggest a Vbox layout.
Here's an example
Hope this helps.
I actually used something like this in a project try this...Put this in the items property of your fieldset...
{
xtype: 'searchfield',
clearIcon: true,
placeHolder: 'Type Some text'
},
{
xtype: 'list',
hidden:true, //Initially hidden populate as user types something
height: '150px',
pressedDelay: 1,
loadingText: '',
store: 'listStore',
itemTpl: '{\'What you want to be displayed as per your model field\'}'
}
In your controller write a handler for the keyup event of the searchfield to load the store with relevant data and toggle the hidden property of the list. Hopefully list should appear with the search results(Worked for me and looked quite good). Hope this helps...

Sencha 2 navigation view create new instance of view without replacing old one

I have a navigation view with list(A) as its item.
On clicking the list(A) item, showing new view(B).
Now the new view(B) is having one button on clicking again change to view(C).
Problem is
view(C) is same as view(B).
I am able to create the new view and push it, but not able to populate with new data.
and on coming back to view(B), I am getting the data of view(C).
How to solve this scenario.
Code:
/**
* navigationview with list(A)
*/
Ext.define('activity', {
extend: 'Ext.navigation.View',
config: {
items:[
{
grouped:true,
pinHeaders: true,
xtype:'list',
store:{
xclass:'ActivityList'
},
itemTpl:'{title}',
emptyText: 'nothing found'
}
]
}
});
/**
* child view(B) to be appeared on clicking any item in list(A).
*/
Ext.define('TaskDetails', {
extend: 'Ext.Panel',
config: {
title: 'Task',
layout: {
type: 'fit'
},
items: [
{
xtype: 'toolbar',
docked: 'top',
height: '40px',
items: [
{ xtype: 'spacer'},
{
xtype: 'segmentedbutton',
height: '30px',
items: [
{
text: 'Task Details',
pressed: true
},
{
text: 'Child Tasks',
badgeText: '0'
}
]
},
{ xtype: 'spacer'}
]
},
{
xtype: 'container',
items: [
{
xtype:'dataview',
store: {
xclass: 'TaskDetails'
},
itemTpl: 'some thing....'
},
{
xtype:'list',
store:{
xclass:'ChildTask'
},
itemTpl: 'some template...'
}
]
}
]
}
});
I am changing view in controller and want to show the same view(B)again with new data on clicking the list in view(B).
This is a feature of navigation view which you cannot circumvent. Use setActiveItem instead to push views... I had the same issue and changed to setActiveItem it gives you more control of your views than navigation view so
After you first load the view(2), the ref returns an array of 1, as it should. Refs only work if 1 component is returned.
After you load the view(2) again the ref returns an array of 2.
This means none of the listeners fire and the data doesn't load on new instances.
Refs bind to dom elements when controllers first see a view. We can't change that. This means we can't use a ref directly. We know the Ext.ComponentQuery.query is what refs rely on. Using that, we can simulate refs at runtime. I put a runtime dataview ref in the initialize() function of the controller to load the data for a new view. This seems to run every time a view is created, so it works.

how to slide from a generic home page to nestedlist layout in sencha touch

I'm starting to use sencha touch. I've been able to create a nestedlist layout where clicking on a leaf element triggers a getdetailcard. Now I want to do something that's kind of the reverse of that.
I want to now create a home page with nothing on it but a logo. WHen user clicks on logo, the layout scrolls to a nested list of items.
can someone point me to the relevant documentation or show me sample code?
Thanks
You need to add panel card to your viewport and then on logo tap change the active item.
Here is sample code:
var data = {
text: 'Groceries',
items: [{
text: 'Drinks',
items: [{
text: 'Water',
items: [{
text: 'Sparkling',
leaf: true
}]
}]
}]
};
Ext.regModel('ListItem', {
fields: [{name: 'text', type: 'string'}]
});
var store = new Ext.data.TreeStore({
model: 'ListItem',
root: data,
proxy: {
type: 'ajax',
reader: {
type: 'tree',
root: 'items'
}
}
});
var nestedList = new Ext.NestedList({
title: 'Groceries',
displayField: 'text',
store: store
});
var MyApp = new Ext.Application({
name: 'MyApp',
launch: function() {
MyApp.views.viewport = new Ext.Panel({
fullscreen: true,
layout: 'card',
cardAnimation: 'slide',
items: [
{
xtype: 'panel',
html:'<img src="https://www.google.com/intl/en_com/images/srpr/logo3w.png">',
listeners:{
el:{tap:function(){MyApp.views.viewport.setActiveItem(1,{type:'slide',direction:'left'});}}
}
},
nestedList
]
});
}
});

Sencha Touch - In need of a nested list example

I'm in need of a simple nested list-view example. Something along the lines of this...
(source: roosteronacid.com)
When you click an item, you will transition (slide) to the next view/card containing another list, with a "back"-button in the top-menu. And so on and so forth.
The lists doesn't necessarily have to three levels deep. I'd like an example which includes, say, one item with three sub-items, and one item which takes you directly to the "final" view.
you should look into the sencha touch videos on vimeo. here is one that answers your question:
http://vimeo.com/20580117
Try the code given below it will help you understand the basic functionality of created a nested list using sencha touch.
Ext.setup({
tabletStartupScreen: 'tablet_startup.png',
phoneStartupScreen: 'phone_startup.png',
icon: 'icon.png',
glossOnIcon: false,
onReady: function() {
var data = {
text: 'Groceries',
items: [{
text: 'Drinks',
items: [{
text: 'Water',
items: [{
text: 'Sparkling',
leaf: true
},{
text: 'Still',
leaf: true
}]
}, {
text: 'Coffee',
leaf: true
}, {
text: 'Espresso',
leaf: true
}, {
text: 'Redbull',
leaf: true
}, {
text: 'Coke',
leaf: true
}, {
text: 'Diet Coke',
leaf: true
}]
},{
text: 'Fruit',
items: [{
text: 'Bananas',
leaf: true
},{
text: 'Lemon',
leaf: true
}]
},{
text: 'Snacks',
items: [{
text: 'Nuts',
leaf: true
},{
text: 'Pretzels',
leaf: true
},{
text: 'Wasabi Peas',
leaf: true
}]
},{
text: 'Empty Category',
items: []
}]
};
Ext.regModel('ListItem', {
fields: [{name: 'text', type: 'string'}]
});
var store = new Ext.data.TreeStore({
model: 'ListItem',
root: data,
proxy: {
type: 'ajax',
reader: {
type: 'tree',
root: 'items'
}
}
});
var leftNav = new Ext.NestedList({
dock: 'left',
useTitleAsBackText: true,
title: '',
displayField: 'text',
width: '350',
store: store
});
new Ext.Panel({
fullscreen: true,
layout: {
type: 'vbox',
align: 'stretch'
},
defaults: {
flex: 1
},
dockedItems:[leftNav]
});
}
})
Following link will help you to find more info easily http://dev.sencha.com/deploy/touch/docs/.
Also look for examples in the sencha touch downloadable package.
Ignoring the PhoneGap stuff at the start, this tutorial has most of what you need.
That's really easy to do. Check out the Nested List in the Kitchen Sink under User Interface examples and click the "Source" button to see the code..
I went with a different approach, using raw HTML.