Empty Sencha Touch 2 List - sencha-touch-2

The Git Ropo for full code
I have defined:
/app/model/Todo:
Ext.define('Test.model.Todo', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'title', type: 'string' },
{ name: 'priority', type: 'integer', defaultValue: 0 },
{ name: 'done', type: 'boolean' }
]
}
});
/app/store/TodoStore
Ext.define('Test.store.TodoStore', {
extend: 'Ext.data.Store',
requires: [ 'Test.model.Todo' ],
config: {
model: 'Test.model.Todo',
data: [
{ title: 'Todo Item 1', priority: 0, done: false },
{ title: 'Todo Item 2', priority: 0, done: false },
{ title: 'Todo Item 3', priority: 0, done: false },
{ title: 'Todo Item 4', priority: 0, done: false },
{ title: 'Todo Item 5', priority: 0, done: false },
{ title: 'Todo Item 6', priority: 0, done: false }
]
}
});
Now, if I just use store: 'TodoStore' in a list, I get
[WARN][Ext.dataview.List#applyStore] The specified Store cannot be found
So I added too app.js
Ext.application({
name: 'Test',
...
stores: [ 'TodoStore' ],
The warning goes away, but I still have a blank list. Am I missing something?
Old Post below
Ext.define("SimpleTodo.view.Main", {
extend: 'Ext.Panel',
requires: [ 'Ext.TitleBar', 'Ext.dataview.List' ],
config: {
styleHtmlContent: true,
items: [
...
{
xtype: 'list',
itemTpl: '{name}',
store: {
fields: ['name'],
data: [
{ name: 'Todo 1' },
{ name: 'Todo 2' },
{ name: 'Todo 3' },
{ name: 'Todo 4' },
{ name: 'Todo 5' },
{ name: 'Todo 6' }
]
}
}
]
}
});
Getting:
Expecting a function in instanceof check, but got #<Object>

It's because Sencha Touch does not understand the way you've defined your store.
You should do something like this, which consists of 3 steps:
Defining model
Ext.define('SimpleTodo.model.listitem',{
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'name', type: 'string'},
],
}
})
Defining store:
Ext.define('SimpleTodo.store.listitems', {
extend: 'Ext.data.Store',
config: {
model: 'SimpleTodo.model.listitem',
data: [
{ name: 'Todo 1' },
{ name: 'Todo 2' },
{ name: 'Todo 3' },
{ name: 'Todo 4' },
{ name: 'Todo 5' },
{ name: 'Todo 6' }
],
}
});
finally, in your list:
store: 'listitems'
Hope this helps.

As it turns out, you can't define a list within a panel (however, this view could be part of a tabpanel). So:
Ext.define("SimpleTodo.view.Main", {
extend: 'Ext.dataview.List',
config: {
title: 'Simple Todo',
itemTpl: '{name}',
store: 'myStore'
}
}
UPDATE: Here's an example of a list in a container with a titlebar. Note the layout: 'vbox' on the container and the flex: 1 on the list. Those are both necessary for the list to display properly.
Ext.define("SimpleTodo.view.Main", {
extend: 'Ext.Container',
config: {
layout: 'vbox',
items: [
{
xtype: 'titlebar',
docked: 'top',
title: 'Simple ToDo'
},
{
xtype: 'listcmp',
flex: 1
}
]
}
}
With a separate view containing your list definition. E.g:
Ext.define('SimpleTodo.view.ListCmp', {
extend: 'Ext.List',
xtype: 'listcmp',
config: {
store: 'SimpleToDo',
itemTpl: '{title}'
}
}

try supplying full class path of the store:
store: 'SimpleTodo.store.listitems',
I suppose the framework does not know what class you are referring by just the class/file name.
if still not working i will suspect the list does not what to display, so try configuring the list itemTpl config:
itemTpl: '{name}',

Related

Two lists same container same store

I got this class where I'm trying to show some data from the same store in the same container. I did it this way because I want to have two rows each on a separate line and I was not having
too much control over them. Here's the class:
Ext.define('Clue.view.ListQuestions', {
extend: 'Ext.Container',
requires: ['Ext.dataview.List'],
xtype: 'listquestions',
config: {
id: 'listquestions',
items: [{
xtype: 'list',
id: 'questionLi1',
baseCls: 'questionLi1',
flex: 1,
store: {
xtype: 'levelstore',
filters: [{
filterFn: function(item) {
return item.data.levelId < 2 && item.data.questionId < 6;
}
}]
},
itemTpl: '<div>{questionId}</div>'
},{
xtype: 'list',
id: 'questionLi2',
baseCls: 'questionLi2',
flex: 1,
store: {
xtype: 'levelstore',
filters: [{
filterFn: function(item) {
return item.data.levelId < 2 && item.data.questionId > 5;
}
}]
},
itemTpl: '<div>{questionId}</div>'
}]
}
})
If I remove the second list, first list is showing, otherwise the first list is not showing. What I'm doing wrong ?
here's the store:
Ext.define('Clue.store.LQuestions', {
extend: 'Ext.data.Store',
xtype: 'levelstore',
requires: ['Ext.data.proxy.LocalStorage'],
config: {
model: 'Clue.model.LQuestions',
storeId: 'levelStore',
sorters: [{
property: 'levelId',
direction: 'ASC'
}],
proxy: {
type: 'localstorage',
id: 'levelstorage'
}
}
})
other details
I added some css on the questionLi1 and questionLi2 and their items. 3px red border. the lists are taking space but in the first list elements are not there ( not even in html ) second list is rendered fine. if I put a console.log() in the first filterFn function nothing shows up.. so I was thinking that maybe I overwrite something...
this is what I get
and if I do:
...
flex: 1,
/*store: {
xtype: 'levelstore',
filters: [{
filterFn: function(item) {
return item.data.levelId < 2 && item.data.questionId > 5;
}
}]
},*/
itemTpl: '<div>{questionId}</div>'
...
on the second list I get
Adding a flex config to a component only works if you specify a vbox of hbox layout to its parent like so
Ext.create('Ext.Container', {
fullscreen: true,
layout: 'vbox',
items: [{
xtype: 'list',
itemTpl: '{title}',
flex: 1,
data: [
{ title: 'List 1: Item 1' },
{ title: 'List 1: Item 2' },
{ title: 'List 1: Item 3' },
{ title: 'List 1: Item 4' }
]
}, {
xtype: 'list',
itemTpl: '{title}',
flex: 1,
data: [
{ title: 'List 2: Item 1' },
{ title: 'List 2: Item 2' },
{ title: 'List 2: Item 3' },
{ title: 'List 2: Item 4' }
]
}]
});
Sencha Fiddle

Empty nested list display

Based on newly created Sencha Touch 2 app as it is learned here.
Then I'd like to add my nested list - hierarchical menu tree and found that doesn't matter - my store inline or my store read from json - nothing displayed inside tab 'Menu'.
What's wrong?
Important files / code fragments:
MVC section in app.js:
// MVC
views: [
'Main'
],
models: [
'MenuItem'
],
stores: [
'MenuTree'
],
view.Main.js:
Ext.define('MobilePost.view.Main', {
extend: 'Ext.tab.Panel',
xtype: 'main',
requires: [
'Ext.TitleBar',
'Ext.data.TreeStore',
'Ext.dataview.NestedList',
'Ext.data.proxy.JsonP',
'MobilePost.store.MenuTree'
],
config: {
tabBarPosition: 'bottom',
items: [
{
// From tutorial, working
title: 'Home',
iconCls: 'home',
cls: 'home',
html: [
'<img src="http://staging.sencha.com/img/sencha.png" />',
'<h1>Welcome to Sencha Touch</h1>'
].join("")
},
{
// From tutorial, working
xtype: 'nestedlist',
title: 'Blog',
iconCls: 'star',
displayField: 'title',
store: {
type: 'tree',
fields: [
'title', 'link', 'author', 'contentSnippet', 'content',
{ name: 'leaf', defaultValue: true }
],
root: {
leaf: false
},
proxy: {
type: 'jsonp',
url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
}
},
detailCard: {
xtype: 'panel',
scrollable: true,
styleHtmlContent: true
},
listeners: {
itemtap: function( nestedList, list, index, element, post ) {
this.getDetailCard().setHtml(post.get('content'));
}
}
},
{
// Mine, not working
xtype: 'nestedlist',
title: 'Menu',
iconCls: 'settings',
store: 'MenuTree'
}
]
}
});
Model - model.MenuItem.js:
Ext.define('MobilePost.model.MenuItem', {
extend: 'Ext.data.Model',
config: {
fields: [
'id', // Menu item id for events
'text', // Menu item text
{ name: 'leaf', defaultValue: false }
]
}
});
Store - store.MenuTree.js:
Ext.define('MobilePost.store.MenuTree', {
extend: 'Ext.data.TreeStore',
requires: [ 'MobilePost.model.MenuItem' ],
type: 'tree',
defaultRootProperty: 'items',
config: {
model: 'MobilePost.model.MenuItem',
/*
// TODO: inline store - uncomment to use
root: {
items: [
{
id: 'settings',
text: 'Settings',
items: [
{
id: 'shift',
text: 'Working shift',
leaf: true
},
{
id: 'users',
text: 'Users',
leaf: true
},
{
id: 'cash',
text: 'Cash',
leaf: true
}
]
}
]
}*/
// TODO: JSON store - comment for inline store
proxy: {
type: 'ajax',
url: 'menu.json'
}
},
// TODO: JSON store - comment for inline store
root: {}
});
JSON - menu.json (valid, passed check by jsonlint.com):
{
"items": [
{
"id": "settings",
"text": "Settings",
"items": [
{
"id": "shift",
"text": "Working shift",
"leaf": true
},
{
"id": "users",
"text": "Operators",
"leaf": true
},
{
"id": "cash",
"text": "Cash",
"leaf": true
}
]
}
]
}
At what point your store is loaded? Shouldn't you use autoLoad:true in your store?
also if you don't want to create and load your store with application load you should manually create store whenever required and set it to list
var treeStore = Ext.create('MobilePost.store.MenuTree');
treeStore.load();
and use this as store attribute in your view
{
// Mine, not working
xtype: 'nestedlist',
title: 'Menu',
id: 'myListId',
iconCls: 'settings',
store: treeStore
}
OR set the store if view is already created
Ext.getCmp('myListId').setStore(treeStore);

How to do I insert a form into a view?

I am new to sencha touch and I am having trouble loading a form into a view.
In my app.js I am loading the main view as such
Ext.Viewport.add(Ext.create('app.view.Main'));
My full app.js is as follows
Ext.application({
name: 'app',
requires: [
'Ext.MessageBox',
'Ext.form.FieldSet',
],
views: ['Main'],
launch: function() {
// Initialize the main view
Ext.Viewport.add(Ext.create('PlanPouch.view.Main'));
},
});
My main view is:
Ext.define("app.view.Main", {
extend: 'Ext.Container',
config:{
items:[
form
]
}
});
var form = Ext.create('Ext.form.Panel', {
fullscreen: true,
items: [
{
xtype: 'textfield',
name: 'name',
label: 'Name'
},
{
xtype: 'emailfield',
name: 'email',
label: 'Email'
},
{
xtype: 'passwordfield',
name: 'password',
label: 'Password'
}
]
});
I took the form from the official documentation and the form doesn't load for some reason. So how can I add the form to my main view?
First let it solve by your approach. Make the following changes & it should work in your system (Running on mine):-
1.) In app.js
Ext.Viewport.add(Ext.create('app.view.Main'));
2). In Main.js
Ext.define("app.view.Main", {
extend: 'Ext.Container',
config:{
items:[
{
xtype: form
}
]
}
});
var form = Ext.create('Ext.form.Panel', {
fullscreen: true,
items: [
{
xtype: 'textfield',
name: 'name',
label: 'Name'
},
{
xtype: 'emailfield',
name: 'email',
label: 'Email'
},
{
xtype: 'passwordfield',
name: 'password',
label: 'Password'
}
]
});
But i will not prefer to call the formpanel in the way you are doing. Rather you can follow ARolek answer OR follow this approach :-
1) app.js
Ext.application({
name: "app",
views: ["Main","second"],
launch: function () {
Ext.Viewport.add(Ext.create('app.view.Main'));
}
});
2) Main.js
Ext.define("app.view.Main", {
extend: "Ext.Container",
requires:["app.view.second"],
config:{
fullscreen: true,
layout:
{
type: 'fit'
},
items:[
{
xtype: "form"
}
]
}
});
3) second.js
Ext.define("app.view.second", {
extend: "Ext.form.Panel",
requires:['Ext.form.FieldSet','Ext.Toolbar'],
alias: "widget.form",
config:
{
items:
[
{
xtype: 'fieldset',
title: 'About You',
items: [
{
xtype: 'textfield',
name: 'name',
label: 'Name'
},
{
xtype: 'emailfield',
name: 'email',
label: 'Email'
},
{
xtype: 'passwordfield',
name: 'password',
label: 'Password'
}
]
}
]
}
});
If you want the form to always be in app.view.Main, then simply do:
Ext.define("app.view.Main", {
extend: 'Ext.Container',
config:{
items:[
{
xtype:'formpanel',
items: [
{
xtype: 'textfield',
name: 'name',
label: 'Name'
},
{
xtype: 'emailfield',
name: 'email',
label: 'Email'
},
{
xtype: 'passwordfield',
name: 'password',
label: 'Password'
}
]
}
]
}
});

Can't Get View to Display Store Data in Sencha Touch

I'm trying to display a list of simple data in Sencha-Touch 2. For some reason, It's not displaying the data and I'm unable to figure it out. I'm getting two title bars: the correct title with "Recent Posts" and a blank one underneath. I don't know why it is coming like this. Perhaps that's conflicting with the rest of the display?
Ext.define('GS.view.NewBlog',{
extend: 'Ext.navigation.View',
xtype: 'newblog',
requires: [
'Ext.dataview.List',
'Ext.TitleBar'
],
config: {
title: 'Blog',
iconCls: 'star',
items: {
docked: 'top',
xtype: 'titlebar',
title: 'Recent Posts'
}, // end items
store: {
fields: ['title','author'],
data: [
{title: 'This is the first Title', author: 'John Smith'},
{title: 'This is the second title', author: 'Jane Doe'}
] // end data
} // end store
}, // end config
itemTpl: '{title}'
});
You need to define a Store:
Ext.define('GS.store.Posts', {`
extend: 'Ext.data.Store',`
config: {
data: [
{
title: 'This is the first Title',
author: 'John Smith'
},
{
title: 'This is the second title',
author: 'Jane Doe'
}
],
storeId: 'Posts',
fields: [
{
name: 'title'
},
{
name: 'author'
}
]
}
});
Define the Panel with a List using the Store:
Ext.define('GS.view.NewBlog', {
extend: 'Ext.Panel',
alias: 'widget.NewBlog',
config: {
layout: {
type: 'card'
},
items: [
{
xtype: 'toolbar',
docked: 'top',
title: 'Recent Posts'
},
{
xtype: 'list',
itemTpl: [
'<div>{title} - {author}</div>'
],
store: 'Posts'
}
]
}
});
Your app.js:
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
stores: [
'Posts'
],
views: [
'NewBlog'
],
name: 'GS',
launch: function() {
Ext.create('GS.view.NewBlog', {fullscreen: true});
}
});
Title Bar is showing twice because you are using Ext.navigation.View, which by default has titlebar. And you are adding one more title bar in the items.
Now define store and itemtpl inside an item, within config. You can define store seperately and mention the id of the store inside store.
items : [{
xtype : 'list',
store: 'store id goes here,
itemTpl: '{title}'
}]

Defining View in ExtJS. "Uncaught TypeError: Cannot call method 'substring' of undefined"

I am trying to define a view but I am getting an error
Uncaught TypeError: Cannot call method 'substring' of undefined
/app/view/Sidebar.js
Ext.define('SimpleTodo.view.Sidebar', {
extend: 'Ext.panel.Panel',
alias: 'widget.sidebar',
config: {
title: 'Projects & Todo Lists',
tbar: [
{
xtype: 'button',
text: 'Add Project'
},
{
xtype: 'button',
text: 'Add Todo List'
}
],
//store: Ext.data.StoreManager.lookup('projects'),
html: 'Hello world',
width: 200
}
});
Then tried to use it in my app.js
Ext.application({
name: 'SimpleTodo',
views: [
'Sidebar'
],
appFolder: 'app',
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: {
type: 'hbox',
pack: 'start',
align: 'stretch'
},
items: [
{
xtype: 'sidebar' // <---- here
},
{
xtype: 'panel',
id: 'detailsView',
flex: 1,
layout: 'card',
items: [
{
xtype: 'panel',
id: 'todoDetails',
title: 'Todo Details'
},
{
xtype: 'panel',
id: 'addProject',
title: 'Add project',
}
]
}
]
})
}
});
What am I missing? Have I defined my views and used it correctly?
Actually it must be like that:
Ext.application({
name: 'SimpleTodo',
requires:[
'SimpleTodo.view.Sidebar'
],
appFolder: 'app',
launch: function() {
Ext.onReady(function(){
Ext.create('Ext.container.Viewport', {
layout: {
type: 'hbox',
pack: 'start',
align: 'stretch'
},
items: [
{
xtype: 'sidebar' // <---- here
},
{
xtype: 'panel',
id: 'detailsView',
flex: 1,
layout: 'card',
items: [
{
xtype: 'panel',
id: 'todoDetails',
title: 'Todo Details'
},
{
xtype: 'panel',
id: 'addProject',
title: 'Add project',
}
]
}
]
})
});
}
});