Sencha touch - display child elements of nested JSON data - json

I am new to Sencha touch and need your help to resolve the issue. I am trying to display the list of children text using following JSON and Sencha touch code. I looked thorough the API and found that the Child data can be accessed, but then I am not sure how I can send that back to Panel/Store to display the list as
Child 21
Child 22
I have nested JSON data as follows:
{
"items":[
{
"id":"1",
"text": "Parent 1",
"leaf": false,
"items": [
{
"id":1,
"text": "child 1",
"leaf": true
},
{
"id":2,
"text": "child 2",
"leaf": true
}
]
},
{
"id":"2",
"text": "Parent 2",
"leaf": false,
"items": [
{
"id":3,
"text": "child 21",
"leaf": true
},
{
"id":4,
"text": "Child 22",
"leaf": true
}
]
}
]
}
Now my sencha touch code is as follows:
Ext.ns('MyApp');
MyApp.Child= Ext.regModel(Child, {
fields: ['id','text','day','date'],
belongsTo: 'Parent',
idProperty:'id',
proxy: {
type: 'rest',
url: 'test.json'
}
});
MyApp.Parent = Ext.regModel('Parent', {
fields: [
{name: 'id', type: 'int'},
{name: 'text', type: 'string'}
] ,
associations: [
{ type: 'hasMany', model: 'Child', name: 'items'}
],
proxy: {
type: 'ajax',
url: 'test.json'
}
});
MyApp.parentStore = new Ext.data.Store({
model : 'Parent',
proxy: {
type: 'rest',
url: 'test.json',
reader: {
type: 'json',
root : 'items'
}
},
autoLoad:true
});
MyApp.parentStore.filter('id','2');
// Do something here to get the list of child items.
// MyApp.childStore = ?
MyApp.appList = new Ext.Panel ({
fullscreen : true,
dockedItems : [
{
xtype : 'toolbar',
title : 'Applications',
dock : 'top'
}
],
items: [{
xtype: 'list',
store: MyApp.childStore, // ??????
itemTpl: '<div class="contact"><strong>{text}</strong></div>'
}]
});

From what I understand what you need to do is a NestedList
Have a look at these links:
http://www.sencha.com/learn/intro-to-the-nested-list-component/
https://github.com/nelstrom/Sencha-Touch-nested-list-demo

Related

Extjs load combo boxes dynamically using recursive json data

I have set of models and a store as given below.
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
'id', 'name', 'total'],
hasMany: {
model: 'Order',
name: 'orders'
},
proxy: {
type: 'rest',
url: 'users.json',
reader: {
type: 'json',
root: 'users'
}
}
});
Ext.define('Order', {
extend: 'Ext.data.Model',
fields: [
'id', 'total'],
hasMany: {
model: 'OrderItem',
name: 'orderItems',
associationKey: 'order_items'
},
belongsTo: 'User'
});
Ext.define('OrderItem', {
extend: 'Ext.data.Model',
fields: [
'id', 'price', 'quantity', 'order_id', 'product_id'],
belongsTo: ['Order', {model: 'Product', associationKey: 'product'}]
});
var store = Ext.create('Ext.data.Store', {
model: 'User'
});
And below is the json file which I use to load data.
{
"users": [
{
"id": "123",
"name": "Ed",
"orders": [
{
"id": "50",
"total": "100",
"order_items": [
{
"id" : "20",
"price" : "40",
"quantity": "2",
"product" : {
"id": "1000",
"name": "MacBook Pro"
}
},
{
"id" : "21",
"price" : "20",
"quantity": "3",
"product" : {
"id": "1001",
"name": "iPhone"
}
}
]
}
]
},
{
"id": "124",
"name": "Nisha",
"orders": [
{
"id": "52",
"total": "1004",
"order_items": [
{
"id" : "22",
"price" : "40",
"quantity": "23",
"product" : {
"id": "1002",
"name": "Nokia"
}
},
{
"id" : "23",
"price" : "100",
"quantity": "3",
"product" : {
"id": "1003",
"name": "apple"
}
}
]
}
]
}
]
}
I am loading the user IDs to L1_combo_box as below and according to the user ID the user selects from the L1_combo_box, I need to load order_item ids to L2_combo_box .
For example, I load user ids 123, 124 to L1_combo_box and when user selects 123 from L1 combo box, I need to load 20,21 to L2 combo box. If user selects 124, then I need to load 22,23.
Below is the partially completed code. can anyone help me to complete this?
var searchFormFieldsetItems = [
{
xtype: 'fieldcontainer',
combineErrors: true,
name: 'search_form_fieldset_items',
msgTarget: 'side',
fieldLabel: '',
defaults: {
hideLabel: true
},
items: [{
xtype: 'combo',
name: 'L1_combo_box',
displayField: 'id',
valueField: 'id',
queryMode: 'remote',
store:store,
listeners: {
change: {
fn: function(combo, value) {
var store1 = 'users/orders/order_items/';//This line is partially completed
L2_combo_box.bindStore(store1);
}
}
}
},{
xtype: 'combo',
name: 'L2_combo_box',
displayField: 'id',
valueField: 'id'
}
]
}
];
For this you need to use select for combobox and inside of select event you need to use loadData() method of store to adding data in second combo.
In this FIDDLE, I have created a demo using your code and put my efforts for showing data in second combo. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('User', {
extend: 'Ext.data.Store',
autoLoad: true,
alias: 'store.user',
fields: ["id", "name", "orders"],
proxy: {
type: 'ajax',
url: 'users.json',
reader: {
type: 'json',
rootProperty: 'users'
}
}
});
Ext.define('Order', {
extend: 'Ext.data.Store',
alias: 'store.order',
field: ["id", "price", "quantity", "product"],
storeId: 'order'
});
Ext.create('Ext.form.Panel', {
title: 'Example Combo',
bodyPadding: 5,
defaults: {
width: 250
},
// The fields
defaultType: 'combo',
items: [{
name: 'L1_combo_box',
displayField: 'id',
valueField: 'id',
queryMode: 'local',
emptyText: 'Select user',
store: {
type: 'user'
},
listeners: {
select: function (combo, rec) {
var L2_combo_box = combo.up('form').getForm().findField('L2_combo_box'),
order = rec.get('orders') || [],
data = [];
//reset combo value
L2_combo_box.reset();
//If order have multipe data then need use forEach for all data
order.forEach(item => {
data = data.concat(item.order_items);
});
//load data in combo store
Ext.getStore('order').loadData(data);
}
}
}, {
emptyText: 'Select order items',
name: 'L2_combo_box',
displayField: 'id',
valueField: 'id',
queryMode: 'local',
store: {
type: 'order'
}
}],
renderTo: Ext.getBody()
});
}
});

Sort a store data based on inner JSON field sencha

i have a json in the following format:
{
"collection": [
{
"id": 4,
"tickets": [
{
"price": 40,
},
{
"price": 50,
}
],
},
{
"id": 1,
"tickets": [
{
"price": 10,
},
{
"price": 15,
}
]
},
]
}
STORE:
Ext.define("myProject.store.ABCs", {
extend: "Ext.data.Store",
config: {
model: "myProject.model.ABC",
autoLoad: false,
proxy: {
type: "ajax",
url: '', //myURL
reader: {
type: "json",
rootProperty: "collection", // this is the first collection
},
},
}
});
For this particular JSON i created the models as:
Ext.define("myProject.model.ABC", {
extend: "Ext.data.Model",
config: {
idProperty: "id",
fields:[
{name: "id", type: "int" },
],
hasMany: [
{
model: "myProject.model.XYZ",
name: "tickets",
associationKey: "tickets",
},
],
}
});
And second model as:
Ext.define("myProject.model.XYZ", {
extend: "Ext.data.Model",
config: {
// idProperty: "id",
fields:[
{name: "inner_id", type: "int" },
],
belongsTo: 'myProject.model.ABC'
}
});
This particular code creates a store and populates the models correctly.
var store = Ext.getStore('ABCs');
Now i want to sort this store based on store.tickets().getAt(0).get('price') that is sort the ABC records based on XYZ's first price property.
In the above json. ABC Records will be: [{id:4}, {id:1}]
But since first price in XYZ (40 > 10), i want to sort them and create [{id:1}, {id:4}]
Take a look at the Ext.util.Sorter class, where you can set a sorterFn. See the example at the top of the page - you should be able to simply write the logic for sorting records the way you describe.

Sencha Touch 2.2 load store from JSON, data goes to raw column

I'm trying to load a store from JSON received from webservices. But all the data from the JSON goes under the 'raw' column of the items in the store...
I can't figure out why, my code seems correct.
Any help is welcome.
My Model :
Ext.define('App.model.Node', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'id', type: 'int' },
{ name: 'version', type: 'int' },
{ name: 'user_id', type: 'int' },
{ name: 'tstamp', type: 'date' },
{ name: 'changeset_id', type: 'int' },
{ name: 'tags', type: 'string' },
{ name: 'geom', type: 'string'}
],
idProperty: 'id'
}
});
My Store :
Ext.define('App.store.NodeStore', {
extend: 'Ext.data.Store',
xtype: 'nodestore',
requires: [
'Ext.data.proxy.Rest'
],
config: {
model: 'App.model.Node',
storeId: 'nodeStore',
autoLoad: true,
proxy: {
type:'rest',
url:'http://localhost/server/nodes',
reader: {
type:'json',
rootProperty: 'nodes'
},
noCache: false,
limitParam: false,
headers: {
'Accept' : 'application/json'
}
}
}
});
My JSON :
{
"nodes": [
{
"id": "454467",
"version": 6,
"user_id": 52015,
"tstamp": "2008-12-27 21:38:45",
"changeset_id": "634766",
"tags": "",
"geom": "0101000020E6100000409CD1A0B29321405455682096804740"
},
{
"id": "454468",
"version": 8,
"user_id": 52015,
"tstamp": "2009-12-23 20:47:15",
"changeset_id": "3437205",
"tags": "",
"geom": "0101000020E6100000357C0BEBC69321409EC02ACD9C804740"
},
{
"id": "454469",
"version": 7,
"user_id": 52015,
"tstamp": "2009-12-23 20:47:15",
"changeset_id": "3437205",
"tags": "",
"geom": "0101000020E6100000347914F8D4932140B8BBBD5AA4804740"
}
]
}
And when I do a
var nodeStore = Ext.getStore('nodeStore');
nodeStore.load();
console.log(nodeStore.getData());
we can see the following object, with my data in the raw column under items...
I figured it out, my code is correct and the only thing missing is a callback in the load() function :
nodeStore.load({
callback: function(records, operation, success) {
console.log(records);
console.log(nodeStore.getCount());
nodeStore.each(function(element) {
console.log(element.data.id);
});
},
scope: this,
});
The problem was I was trying to access the store before it loaded the data. Now I'm waiting that all the data is loaded to access it, and it works.

Can't show the json Data in Treepanel in extjs 4

I am working on showing JSON data in EXTJS 4 TreePanel. But my tree is not showing any data . Please let me know where I am wrong. Let me post my codes below:
View Part: it has got the treepanel
xtype: 'treepanel',
title: 'Standard Geographies',
height: 250,
width: 310,
store: 'Data',
border: 1,
displayField: 'name',
useArrows: true,
rootVisible: true,
multiSelect: true,
preventHeader: true,
renderTo: Ext.getBody(),
columns: [{
xtype: 'treecolumn',
text: 'Standard Geographies',
flex: 1,
sortable: false,
//renderer : change,
dataIndex: 'name'
}],
Model Part: Using json data
Ext.define('TA.model.TAModel', {
extend: 'Ext.data.Model',
fields: ['name','typeId'],
//fields: ['abbr','type'],['name','typeId']
proxy: {
type: 'ajax',
url : 'data/StandardGeoTree.json',
actionMethods: {
read: 'POST'
},
reader: {
type: 'json',
root: 'geographyOptions'
},
}
});
Store Part: I hope all is ok in the store part
Ext.define('TA.store.Data', {
//extend: 'Ext.data.Store',
//model: 'TA.model.TAModel',
extend: 'Ext.data.TreeStore',
model: 'TA.model.TAModel',
autoSync: true,
autoLoad: true,
listeners: {
load:function(){
console.log('Schemes Data store loaded');
}
},
proxy: {
type: 'ajax',
//url : 'data/StandardGeoTree.json',
api: {
//read: 'data/StandardGeo.json',
read: 'data/StandardGeoTree.json',
//update: 'data/updateTradeArea.json'
},
reader: {
type: 'json',
root: 'root',
successProperty: 'success',
idProperty : 'typeId'
}
},
root : {
text: 'Root',
id: 'typeId',
expanded : true,
loaded : true,
children: []
}
});
JSON
{
"success": true,
"root" : [
{
"name": "001-USA",
"typeId" : "1",
"children":[
{"name": "USA", "typeId" : "1", "leaf":"true"},
{"name": "State", "typeId" : "2", "leaf":"true"},
{"name": "DMA", "typeId" : "3", "leaf":"true"},
{"name": "CSA", "typeId" : "4", "leaf":"true"},
]
}
]
}
the store configuration for tree component is actually doesn't need to be so complicated. for example simple store declaration below is enough:
var treestore = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: 'data/StandardGeoTree.json'
}
});
then in your tree configuration set store: treestore and rootVisible: false
finally, the store expect json respond in this format:
[{
"text": "To Do",
"cls": "folder",
"expanded": true,
"children": [{
"text": "Go jogging",
"leaf": true
},{
"text": "Take a nap",
"leaf": true
},{
"text": "Climb Everest",
"leaf": true
}]
}]
In your JSON, your root property has to be similar to your children. So it's either "root" or "children", but not both. See this question for the full explanation.
So given you stick to:
reader: {
type: 'json',
root: 'root',
successProperty: 'success',
idProperty : 'typeId'
}
Your JSON should look like so:
{
"success": true,
"root" : [
{
"name": "001-USA",
"typeId" : "1",
"root":[
{"name": "USA", "typeId" : "1", "leaf":"true"},
{"name": "State", "typeId" : "2", "leaf":"true"},
{"name": "DMA", "typeId" : "3", "leaf":"true"},
{"name": "CSA", "typeId" : "4", "leaf":"true"},
]
}
]
}
Nothing worked as solution. So I had to write the below code part in my view which solved my problem. I am pasting the code part below:
var treeStore = Ext.StoreManager.lookup('Data');
treeStore.load();
But I want my store to be loaded automatically. Please let me know if you have any solution to automatically load the store.

Sencha Touch: How to get data from complex JSON objects

I am not able retrieve records from complex json objects but i am able to get the data when using an TPL.
Please see the below example codes:
JSON:
{
"lists": [
{
"title": "Groceries",
"id": "1",
"items": [
{
"text": "contact solution - COUPON",
"listId": "1",
"id": "4",
"leaf": "true"
},
{
"text": "Falafel (bulk)",
"listId": "1",
"id": "161",
"leaf": "true"
},
{
"text": "brita filters",
"listId": "1",
"id": "166",
"leaf": "false"
}
]
}
]
Model:
Ext.regModel("TopModel",
{
fields: [
{ name: 'title', type: 'string' },
{ name: 'id', type: 'string' },
],
hasMany: [
{ model: 'SubModel', name: 'items' }
],
proxy: {
type: 'ajax',
url : 'test/lists.json',
actionMethods: {
create: 'POST',
destroy: 'POST',
read: 'POST',
update: 'POST'
},
reader: {
type: 'json',
root: function(data) {
return data.lists || [];
}
}
}
});
Ext.regModel("SubModel",
{
fields: [
{ name: 'text', type: 'string'},
{ name: 'listId', type: 'string'},
{ name: 'id', type: 'string'},
{ name: 'leaf', type: 'string'}
]
});
In my View file, i have defined the store as below.
this.stores = new Ext.data.Store({
clearOnPageLoad: false,
autoLoad:true,
model:'TopModel',
getGroupString: function(record) {
return record.get('leaf');
}
});
});
I am not able to retrieve the values for record.get('leaf') as this refers to the child model items. When I tried to print it, it prints as undefined.
How to access the child attributes? Here 'items' is listed as an array.
I tried to display the data using list as below. All the records are displayed but the problem is that it is picked as one whole item instead of separate list for each item.
var list = new Ext.List({
cls: 'big-list',
grouped : true,
emptyText: '<div>No data found</div>',
itemTpl: ['<div><tpl for="items">',
'<div>',
'{id} {text}',
'</div>',
'</tpl></div>',
],
store: this.stores,
listeners: {
itemtap: this.onListItemTap,
scope: this
}
});
Kindly help me on how to get the list items to be displayed as individual records.
you can use online json parser(http://json.parser.online.fr/) to parse json xml from parser data you easily seprate objects and arrays and you get all data which are require for you..i hope this help you