How to display associated json data in grid in extjs4? - json

I am working in extjs4 mvc where I am getting stuck at a point. Actually I want to display associated json data in grid in extjs4. I tried and searched a lot but not yet get problem solved.
Here is my some code
my view file:
Ext.define('AM.view.user.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.userlist',
title : 'All Users',
store: 'Users',
columns: [
{header: 'Name', dataIndex: 'name', flex: 1},
{header: 'Email', dataIndex: 'email', flex: 1},
{header:'title',dataIndex:'title',flex:1} //I tried
]
});
Controller file:
Ext.define('AM.controller.Users', {
extend: 'Ext.app.Controller',
stores: ['Users'],
models: ['User','Book'],
views: ['user.Edit', 'user.List'],
refs: [{
ref: 'usersPanel',
selector: 'panel'
}],
init: function() {
this.control({
'viewport > userlist dataview': {
itemdblclick: this.editUser
},
'useredit button[action=save]': {
click: this.updateUser
}
});
}
});
User model file:
Ext.define('AM.model.User', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'email'],
hasMany: {
model: 'AM.model.Book',
//model: 'Book',
foreignKey: 'userId',
name: 'books'
},
proxy: {
type: 'ajax',
api: {
read: 'data/users.json',
update: 'data/updateUsers.json'
},
reader: {
type: 'json',
root: 'users',
successProperty: 'success'
}
}
});
User store file :--
Ext.define('AM.store.Users', {
extend: 'Ext.data.Store',
model: 'AM.model.User',
autoLoad: true
});
Book model file:
Ext.define('AM.model.Book',{
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'title', type: 'string'}, //,mapping:'record[0].title' not working
{name: 'userId', type: 'int'}
]
});
json file:
{
"success": "true",
"users": [
{
"id": "1",
"name": "shilpa",
"email": "shilpa#sencha.com",
"books": [
{
"id": "10",
"title": "c++",
"userId": "1"
}
]
}
]
}
here is the screenshot:
please give me some suggestion to display associated data in grid.

You can access all the books in the column renderer and construct the string you need. It would be something like this:
{
text: 'Books',
renderer: function (val, meta, record) {
var books = '';
record.books().each(function(bookRecord, index, count) {
books = books + bookRecord.get('title') + ',';
});
return books;
}
}
http://jsfiddle.net/alexrom7/YQXC8/1/

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()
});
}
});

Can't get 'hasMany' data from nest JSON

I have a nested JSON and I cannot seem to extract the nested array. I am not sure if I set up my store and models correctly. It seems right. As you can see at the bottom of this post, when I try to get the nested part out, it doesn't work.
JSON data:
{
"data":{
"name":"John",
"age":"23",
"gender":"Male",
"purchase":[
{
"item":"shirt",
"qty":1,
"price":10
},
{
"item":"hat",
"qty":2,
"price":25
},
{
"item":"pants",
"qty":1,
"price":15
}
]
},
"success":true,
"errorMsg":""
}
Store:
Ext.define('Pvm.store.MyStore', {
extend: 'Pvm.store.PvmBaseStore',
requires: [
'Pvm.model.Customer'
],
model: 'Pvm.model.Customer',
autoLoad: false
});
Customer Model:
Ext.define('Pvm.model.Customer', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
fields: [{
name: 'name',
type: 'auto'
}, {
name: 'age',
type: 'auto'
}, {
name: 'gender',
type: 'auto'
}],
associations: {
type: 'hasMany',
model: 'Pvm.model.Purchase',
name: 'purchase',
associationKey: 'purchase'
},
proxy: {
type: 'ajax',
actionMethods: {
create: 'POST',
read: 'POST', // changed read's method to POST (from GET) so we get the parameters as form data (not in URL, for security reasons)
update: 'POST',
destroy: 'POST'
},
url: '/pvmsvr/uiapi?cmd=readXml',
reader: {
type: 'json',
rootProperty: 'data'
}
}
});
Purchase Model:
Ext.define('Pvm.model.Purchase', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
fields: [{
name: 'item',
type: 'auto'
}, {
name: 'qty',
type: 'auto'
}, {
name: 'price',
type: 'auto'
}],
associations: {
type: 'belongsTo',
model: 'Pvm.model.Customer'
}
});
Controller Code:
onStoreLoaded: function(store, records, successful, eOpts) {
console.log(store); // works
console.log(records); // works
console.log(records[0].get('name')); // works
console.log(records[0].purchase(); // doesn't work; returns 'undefined'
}
I am idiot. I needed the child model's class name in the parent's requires...

Extjs simple model and store

I have a simple model, let's say:
Ext.define('UserModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'firstname', type: 'string'},
{name: 'lastname', type: 'string'}
]
});
And a json file that looks like this:
{
"DatabaseInJSON": {
"Users": [
{
"KeyFirstName": "John",
"KeyLastName": "Doe"
},{
"KeyFirstName": "James",
"KeyLastName": "Howlett"
}
],
"OtherStuffWeDontCareAbout": [
...
]
}
}
My question is:
If I create a store like this, how can i map the attribute "firstname" from my model to "KeyFirstName" from my json ?
Ext.define('my.custom.Store', {
extend: 'Ext.data.Store',
model: 'UserModel',
proxy: {
type: 'ajax',
url: 'path/to/my/file.json',
reader: {
type: 'json',
rootProperty: 'DatabaseInJSON'
}
}
});
You need to either employ mapping or a convert function
Have a look at the demo here which demonstrates both in action.
For the sake of the demo I turned your store into a memory proxy store and you are I presume also accessing your rootProperty wrong as it should be rootProperty: 'DatabaseInJSON.Users'
Code:
Ext.application({
name: 'Fiddle',
launch: function() {
myData = {
"DatabaseInJSON": {
"Users": [{
"KeyFirstName": "John",
"KeyLastName": "Doe"
}, {
"KeyFirstName": "James",
"KeyLastName": "Howlett"
}],
"OtherStuffWeDontCareAbout": {}
}
};
Ext.define('UserModel', {
extend: 'Ext.data.Model',
fields: [{
name: 'firstname',
mapping: 'KeyFirstName',
type: 'string'
}, {
name: 'lastname',
convert: function(v, record) {
return record.data.KeyLastName;
},
type: 'string'
}]
});
Ext.define('my.custom.Store', {
extend: 'Ext.data.Store',
model: 'UserModel',
proxy: {
type: 'memory',
reader: {
type: 'json',
rootProperty: 'DatabaseInJSON.Users'
}
}
});
myStore = Ext.create('my.custom.Store', {
data: myData
});
console.log(myStore.getRange());
}
});
Generally your Json properties should match the same names of your fields so that the reader can read them properly, to map 'KeyFirstName' to 'firstname' I think your best option would be to create a mapping in the field definition on the model.
This would apply this globally for all requests and I believe it would reverse the mapping when it come to saving the data.
To use the mapping in your case, you would need something like:
Ext.define('UserModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'firstname', type: 'string', mapping: function(data) { return data.KeyFirstName; } },
{name: 'lastname', type: 'string', mapping: function(data) { return data.KeyLastName; } }
]
});
Other than changing the format of the JSON data, the only other way I can think of would be to override the read or getResponseData method of the JsonReader

EXTjs treegrid - correct model

A very simple example, but it does not work. List of Working Groups looped. What am I doing wrong? How to correct write a model for this json. Docs
http://docs.sencha.com/extjs/4.0.7/#!/api/Ext.data.reader.Reader
Below is a screenshot result.
https://ps.vk.me/c537518/u155966612/doc/2ee8ec3e7718/1234.png
JS code.
Ext.define('WorckGroup', {
extend: 'Ext.data.Model',
fields: [
{ name: 'text', type: 'string', mapping: 'WorckGroup' },
],
hasMany: { name: 'children', model: 'UserReport', associationKey: 'UserReport' }
});
Ext.define('UserReport', {
extend: 'Ext.data.Model',
fields: [
{ name: 'text', type: 'string', mapping: 'Specialist' },
],
belongsTo: 'WorckGroup'
});
var store = new Ext.data.TreeStore({
model: 'WorckGroup',
proxy: {
type: 'ajax',
url: '/omnireports/ajaxgrid'
},
autoLoad: true,
folderSort: true
});
Ext.define('basegrid', {
extend: 'Ext.tree.Panel',
xtype: 'tree-grid',
title: 'Core Team Projects',
height: 300,
useArrows: true,
rootVisible: false,
multiSelect: true,
singleExpand: false,
initComponent: function () {
this.width = 500;
Ext.apply(this, {
store: store,
columns: [{
xtype: 'treecolumn',
text: 'Task',
flex: 2,
sortable: true,
dataIndex: 'text'
},]
});
this.callParent();
}
});
json
[{"WorckGroup":"Группа поддержки 3D",
"UserReport":[
{"Specialist":"Вагин Александр Константинович","SCallCount":64,"AverageDuration":0.1136067,"leaf":true},
{"Specialist":"Кистерева Татьяна Алексеевна","SCallCount":171,"AverageDuration":0.1058641,"leaf":true},
{"Specialist":"Лысенко Алексей Валентинович","SCallCount":71,"AverageDuration":0.4269940,"leaf":true}]},
{"WorckGroup":"Группа поддержки сервиса КСУП",
"UserReport":[
{"Specialist":"Болгов Руслан Евгеньевич","SCallCount":62,"AverageDuration":0.1093749,"leaf":true},
{"Specialist":"Костин Алексей Алексеевич","SCallCount":17,"AverageDuration":0.1125816,"leaf":true},
{"Specialist":"Мироненко Анна Владимировна","SCallCount":172,"AverageDuration":0.0632347,"leaf":true},
{"Specialist":"Ползиков Мирослав Александрович","SCallCount":315,"AverageDuration":0.0945766,"leaf":true},
{"Specialist":"Тахтенков Николай Владимирович","SCallCount":7,"AverageDuration":0.2342261,"leaf":true}]}

Cant load JSON file

Hi I'm trying to load a local JSON file in Sencha Touch 2.
I'm using phonegap 1.4 and iOS 5, testing in VM.
Here is the code:
Ext.define("User", {
extend: 'Ext.data.Model',
config: {
fields: [
'id', 'name'
],
hasMany: {model: 'Order', name: 'orders'},
proxy: {
type: 'ajax',
url : 'users.json',
reader: {
type: 'json',
root: 'users'
}
}
}
});
Ext.define("Order", {
extend: 'Ext.data.Model',
config: {
fields: [
'id', 'total'
],
hasMany : {model: 'OrderItem', name: 'orderItems', associationKey: 'order_items'},
belongsTo: 'User'
}
});
Ext.define("OrderItem", {
extend: 'Ext.data.Model',
config: {
fields: [
'id', 'price', 'quantity', 'order_id', 'product_id'
],
belongsTo: ['Order', {model: 'Product', associationKey: 'product'}]
}
});
Ext.define("Product", {
extend: 'Ext.data.Model',
fields: [
'id', 'name'
],
hasMany: 'OrderItem'
});
var store = Ext.create('Ext.data.Store', {
model: "User"
});
store.load({
callback: function() {
//the user that was loaded
var user = store.first();
//console.log("Orders for " + user.get('name') + ":")
alert(user.get('name'));
//iterate over the Orders for each User
user.orders().each(function(order) {
console.log("Order ID: " + order.getId() + ", which contains items:");
//iterate over the OrderItems for each Order
order.orderItems().each(function(orderItem) {
//we know that the Product data is already loaded, so we can use the synchronous getProduct
//usually, we would use the asynchronous version (see Ext.data.association.BelongsTo)
var product = orderItem.getProduct();
});
});
}
});
The JSON file:
{
"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"
}
}
]
}
]
}
]
}
The alert says 'undefined', any help? Many thanks
In Sencha Touch 2 the reader object should use rootProperty instead of root.