I've got the flollowing issue:
I'm building a TreePanel with data of people but I don't know how to define the model of it without defineing : leaf, cls and text attributes. I wan't that "Name" would be the node text of each node .
My model is defined as following:
Ext.define('People', {
extend: 'Ext.data.Model',
fields: [
{name: 'Name', type: 'string'},
{name: 'Surname', type: 'string'},
{name: 'Email', type: 'string'}
{name: 'BirthDate', type: 'string'}
]
});
My TreeStore (for the moment with static data, but it will be load from an ajax call to the server that will return a list of server person model). Obviously I don't want to define leaf, text and cls attributes in my server model:
Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [
{
"Name":"Juan",
"Surname":"Hoz",
"Email": "user#domain.com",
"BirthDate":"19801205"
},
{
"Name":"Marta",
"Surname":"Hoz",
"Email": "user2#domain.com",
"BirthDate":"19831210"
}
}
});
My TreePanel is defined as following:
Ext.create('Ext.tree.Panel', {
id: 'treePersonId',
store: mystore,
hideHeaders: true,
rootVisible: false,
title: 'Persons',
collapsible: true,
resizable:true
});
Can anyone helps me to find the correct way to do this?
Thank you very much,
Juan
Ext.define('Person', {
extend: 'Ext.data.Model',
fields: [{
name: 'Name',
type: 'string'
}, {
name: 'Surname',
type: 'string'
}, {
name: 'Email',
type: 'string'
}, {
name: 'BirthDate',
type: 'string'
}]
});
Ext.require('*');
Ext.onReady(function() {
var store = Ext.create('Ext.data.TreeStore', {
model: 'Person',
root: {
expanded: true,
children: [{
"Name": "Juan",
"Surname": "Hoz",
"Email": "user#domain.com",
"BirthDate": "19801205"
}, {
"Name": "Marta",
"Surname": "Hoz",
"Email": "user2#domain.com",
"BirthDate": "19831210"
}]
}
});
Ext.create('Ext.tree.Panel', {
renderTo: document.body,
store: store,
hideHeaders: true,
rootVisible: false,
columns: [{
xtype: 'treecolumn',
dataIndex: 'Name',
flex: 1
}]
});
});
Related
I'm working from an example based on the comments in the Sencha documentation. I am able to extract the top-level information (id,name,last) but I can't figure out how to extract the products from each record. I was hoping that it would be as simple as requesting that part of the record but aProduct is always null:
var name = aRecord.get('name'); // Good
var lastName = aRecord.get('last'); // Good
var aProduct = aRecord.get('products'); // Null
I'm including all the code.
JSON:
[
{
"id": 1,
"name": "Ed",
"last": "Bar",
"products": [
{
"short_name": "Product1",
"name": "Another Product"
},
{
"short_name": "Product2",
"name": "Second Product"
}
]
},
{
"id": 2,
"name": "Foo",
"last": "Bar",
"products": [
{
"short_name": "Product1",
"name": "Another Product"
},
{
"short_name": "Product2",
"name": "Second Product"
}
]
}
]
app.js:
Ext.application({
name: 'SenchaFiddle',
models: ['Product', 'User'],
stores: ['UserStore'],
views: [],
controllers: [],
launch: function () {
Ext.create('Ext.Panel', {
fullscreen: true,
html: 'Test...'
});
var userStore = Ext.getStore('UserStore');
console.log(userStore);
console.log('--- Data ---');
userStore.each(function (val) {
console.log(val.get('name'));
});
console.log('--- Done ---');
userStore.load({
params: {},
scope: this,
callback: function (records, operation, success) {
console.log("status=" + success);
console.log("Number Records=" + records.length);
for (var i = 0; i < records.length; i++) {
var aRecord = records[i];
console.log(aRecord);
var name = aRecord.get('name');
var lastName = aRecord.get('last');
var productList = aRecord.get('products');
console.log('(Short, First, Last)=(' + productList + ',' + name + ',' + lastName + ')');
for (var j=0; j<productList.length; j++) {
console.log(productList[j].name + " / " + productList[j].short_name);
}
}
}
});
}
});
User Model:
Ext.define('SenchaFiddle.model.User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'last', type: 'string'}
],
// we can use the hasMany shortcut on the model to create a hasMany association
hasMany: {model: 'Product', name: 'products', "associationKey": 'products'}
}
});
Product Model:
Ext.define('SenchaFiddle.model.Product', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'user_id', type: 'int'},
{name: 'short_name', type: 'string'},
{name: 'name', type: 'string'}
]
}
});
User Store:
Ext.define('SenchaFiddle.store.UserStore', {
extend: 'Ext.data.Store',
config: {
model: 'SenchaFiddle.model.User',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'users.json',
reader: {
type: 'json'
//rootProperty: 'users'
}
}
},
load: function () {
this.callParent(arguments);
console.log("User Store Loaded\n");
}
});
Nice work, you are very close!
Add a products field to your user model:
fields: ['products',
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'last', type: 'string'}
]
Stick w/Sencha, the whole package can be a little overwhelming and admittedly confusing (even after a couple years of use) but it definitely get better.
Brad
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);
I'm working on a basic Sencha Touch application that displays a list of text messages and the name of an associated user that sent the message. I have followed the tutorials online on how to setup model associations but each tutorial assumes that the server produces data with a nested structure.
The data I am working with has a flat structure with primary/foreign key relationships, and I cannot figure out how to get Sencha to load both stores from a single response.
model/User.js
Ext.define('App.model.User', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'uid', type: 'number' },
{ name: 'name', type: 'string' },
]
}
});
store/Users.js
Ext.define('App.store.Users', {
extend: 'Ext.data.Store',
config: {
model: 'App.model.User',
autoLoad: true,
}
});
model/Message.js
Ext.define('App.model.Message', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'id', type: 'number' },
{ name: 'uid', type: 'number' },
{ name: 'message', type: 'string' }
],
associations: [{
type: 'belongsTo',
model: 'App.model.User',
primaryKey: 'uid',
foreignKey: 'uid'
}],
proxy: {
type: 'jsonp',
url: 'messages.json',
reader: {
type: 'json',
rootProperty: 'req_messages'
}
}
}
});
store/Messages.js
Ext.define('App.store.Messages', {
extend: 'Ext.data.Store',
config: {
model: 'App.model.Message',
autoLoad: true,
}
});
The messages are correctly loaded and displayed by my application (sample JSON response below), but I cannot figure out how to get the associated users to be loaded into the store. Can this be solved with a configuration, or will I need a custom reader? Any help appreciated!
Sample JSON
{
"users": [{
"uid": "1",
"name": "John"
}, {
"uid": "3033",
"name": "Noah"
}],
"req_messages": [{
"id": "539",
"uid": "1",
"message": "my message"
}, {
"id": "538",
"uid": "1",
"message": "whoops"
}, {
"id": "534",
"uid": "3033",
"message": "I love pandas."
}]
}
I've never really worked with associations and I went through the document to try to find something that would load two stores with on request, but I couldn't find anything. So here's how I would do it :
Model
Ext.define('App.model.User', {
extend: 'Ext.data.Model',
config: {
fields: [
'uid',
'name'
]
}
});
Ext.define('App.model.Message', {
extend: 'Ext.data.Model',
config: {
fields: [
'id',
'message',
'uid'
],
associations: { type: 'hasOne', model: 'User', primaryKey: 'uid', foreignKey: 'uid'}
}
});
Stores
Ext.define('App.store.Users', {
extend: 'Ext.data.Store',
config: {
model: 'App.model.User',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'http://www.titouanvanbelle.fr/test.json',
reader: {
type: 'json',
rootProperty: 'users'
}
},
listeners:{
load:function(s,r,success,op){
var msgs = JSON.parse(op.getResponse().responseText).req_messages;
Ext.each(msgs, function(msg) {
Ext.getStore('Messages').add(Ext.create('App.model.Message',msg));
});
}
}
}
});
Ext.define('App.store.Messages', {
extend: 'Ext.data.Store',
config: {
model: 'App.model.Message'
}
});
List
Ext.define("App.view.Main", {
extend: 'Ext.Panel',
config: {
fullscreen: true,
layout:'fit',
items: [{
xtype:'list',
store:'Messages',
itemTpl: new Ext.XTemplate(
'<tpl for=".">',
'{[this.getUserName(values)]} : {message}',
'</tpl>',
{
getUserName(v){
var s = Ext.getStore('Users'),
u = s.getAt(s.find('uid',v.uid));
return u.get('name');
}
}
)
}]
}
});
And you'd get something like this :
Hope this helps. If you need explanation, let me know.
I want to make a simple request like Ext.Ajax.request and display it in a list. But it does not work.
I have a URL like this
http://server/GetContacts.aspx?CustAccount=10019
Can someone tell me exactly how it works and what I should consider?
This is an example of what I get back.
{
"HasError": false,
"ErrorString": "",
"Data": [
{"ContactPersonId":"","Name":"","FirstName":"","MiddleName":"","LastName":"","Phone":"","CellularPhone":"","Telefax":"","Email":"","Url":"","Address":"","ZipCode":"","City":"","Street":"","Country":"","Function":""}
]
}
Ext.regModel('kunden', {
idProperty: 'id',
fields: [
{ name: 'ContactPersonId', type: 'string' },
.
.
.
{ name: 'Function', type: 'string' }
]
});
Ext.regStore('kundenStore', {
model: 'kunden',
sorters: [{
property: 'LastName'
}],
proxy: {
type: 'ajax',
url: 'http://server/GetContacts.aspx?CustAccount=10019'
},
reader: {
type: 'json',
root: 'Data'
}
});
NotesApp.views.kundenList = new Ext.List({
id: 'kundenList',
store: 'kundenStore',
grouped: true,
indexBar : true,
itemTpl: '<div class="list-item-title">{firstname} {lastname}</div>' +'<div class="list-item-narrative">{email}</div>',
listeners: {}
}
});
It can be so easily XP
Im just trying to simply load some json data into my combobox using a basic data store. Here is my json data:
{"services": [{"id": 1, "name": "dropbox"}, {"id": 2, "name": "facebook"}, {"id": 3, "name": "twitter"}]}
Here is my extjs 4 code:
Ext.onReady(function(){
Ext.define('ServiceList', {
extend: 'Ext.data.Model',
fields: [
'id', 'name'
]
});
var store = Ext.create('Ext.data.Store', {
model: 'ServiceList',
proxy: {
type: 'json',
url: '/account/service/list',
reader: {
root: 'services',
totalProperty: 'totalCount'
}
}
});
store.load();
Ext.create('Ext.panel.Panel', {
layout: 'auto',
title: 'VAC',
width: '100%',
renderTo: 'vac-app-window',
items: [{
xtype: 'tabpanel',
autoTabs:true,
activeTab: 0,
border:false,
defaults: {autoHeight:true, bodyStyle:'padding:10px'},
items: [{
title: 'Data Services',
items: [{
xtype:'combo',
store:store
}]
}]
}]
});
});
Everything is being done on localhost so no cross domain stuff. I've been going through documentation but just can't figure out what im doing wrong.
As always any tips is much appreciated!
Update:
I edited some changes to the datastore and am getting a bit farther:
Ext.define('ServiceList', {
extend: 'Ext.data.Model',
fields: [
{name:'id', type:'int'},
{name:'name', type:'string'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'ServiceList',
proxy: {
type: 'ajax',
url: '/account/service/list',
reader: {
root: 'services',
type: 'json'
}
}
});
store.load();
Now when the page loads or I attempt to click the combobox the url it is addressing is:
GET /account/service/list?_dc=1318340688155&page=1&start=0&limit=25
From my reading this looks like jsonp but I dont know where the page,start, and limit params come from?
Update2:
Thanks to the help from Molecule Man I was able to sort this out:
Ext.onReady(function(){
Ext.define('ServiceList', {
extend: 'Ext.data.Model',
fields: [
{name:'id', type:'int'},
{name:'name', type:'string'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'ServiceList',
autoLoad: true,
proxy: {
limitParam: undefined,
startParam: undefined,
paramName: undefined,
pageParam: undefined,
noCache:false,
type: 'ajax',
url: '/account/service/list',
reader: {
root: 'services'
}
}
});
Ext.create('Ext.panel.Panel', {
layout: 'auto',
title: 'VAC',
width: '100%',
renderTo: 'vac-app-window',
items: [{
xtype: 'tabpanel',
autoTabs:true,
activeTab: 0,
border:false,
defaults: {autoHeight:true, bodyStyle:'padding:10px'},
items: [{
title: 'Data Services',
items: [{
xtype:'combo',
queryMode:'local',
emptyText: 'Select Service',
store:store,
displayField: 'name',
valueField: 'id'
}]
}]
}]
});
});
Hope this helps anyone else :)
Your combobox' config doesn't contain displayField (defaults to 'text') and valueField(defaults to displayField's value) which are required:
items: [{
xtype:'combo',
displayField: 'name',
valueField: 'id',
store:store
}]