I have a json file and I assume that I do not know anyting about the content. I do not know the model. However it is given in the json file the model, the data, and other information about the grid. How I'll create the columns etc in this way?
Stackoverflow is littered with questions very similar to this one. I worked through them all and did not find a definitive solution. However, most of the provided answers pointed me in the right direction. I'll give me best shot at putting all those suggestions together and making this clear for others:
Model: (Only shows 2 fields that will be in all JSON responses. Will still be overwritten)
Ext.define('RTS.model.TestsModel', {
extend: 'Ext.data.Model',
alias: 'model.TestsModel',
fields: [
{
name: 'poll_date'
},
{
name: 'poller'
}
]
});
Store:
Ext.define('RTS.store.TestsStore', {
extend: 'Ext.data.Store',
alias: 'store.TestsStore',
model: 'RTS.model.TestsModel',
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: false,
proxy : {
type : 'ajax',
url : 'tests.php',
reader : {
type : 'json',
root : 'tests',
successProperty : 'success'
}
},
storeId: 'tests-store'
}, cfg)]);
}
});
View: (The columns will be defined in each JSON response)
Ext.define('RTS.view.TestsView', {
extend: 'Ext.grid.Panel',
alias: 'widget.TestsView',
id: 'tests-view',
title: 'Tests',
emptyText: '',
store: 'TestsStore',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
viewConfig: {
},
columns: [
]
});
me.callParent(arguments);
}
});
Controller: (The controller does all the work in forcing the view and model to change based on the JSON response).
Ext.define('RTS.controller.TestsController', {
extend: 'Ext.app.Controller',
alias: 'controller.TestsController',
stores: [
'TestsStore'
],
models: [
'TestsModel'
],
views: [
'TestsView'
],
init: function(application) {
// When store changes, trigger an event on grid
// to be handled in 'this.control'.
// NOTE : Ext JS does not allow control of
// non-component events.
// Ext JS 4.2 beta will allow the controller
// to detect non-component changes and handle them
var testsStore = this.getStore('TestsStore');
testsStore.on("metachange", metaChanged, this);
function metaChanged(store, meta) {
var grid = Ext.ComponentQuery.query('TestsView')[0];
grid.fireEvent('metaChanged', store, meta);
};
this.control({
"TestsView": {
metaChanged: this.handleStoreMetaChange
}
});
},
/**
* Will update the model with the metaData and
* will reconfigure the grid to use the
* new model and columns.
*/
handleStoreMetaChange: function(store, meta) {
var testsGrids = Ext.ComponentQuery.query('TestsView')[0];
testsGrids.reconfigure(store, meta.columns);
}
});
JSON Response:
Your json response must have the "metaData" property included. It should define the fields just as you would on a static model and the view that would normally be defined to show the fields.
{
"success": true,
"msg": "",
"metaData": {
"fields": [
{
"name": "poller"
},
{
"name": "poll_date"
},
{
"name": "PING",
"type": "int"
},
{
"name": "SNMP",
"type": "int"
},
{
"name": "TELNET",
"type": "int"
},
{
"name": "SSH",
"type": "int"
},
{
"name": "all_passed"
}
],
"columns": [
{
"dataIndex": "poller",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "Poller"
},
{
"dataIndex": "poll_date",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "Poll Date"
},
{
"dataIndex": "PING",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "PING",
"renderer": "RenderFailedTests"
},
{
"dataIndex": "SNMP",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "SNMP",
"renderer": "RenderFailedTests"
},
{
"dataIndex": "TELNET",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "TELNET",
"renderer": "RenderFailedTests"
},
{
"dataIndex": "SSH",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "SSH",
"renderer": "RenderFailedTests"
},
{
"dataIndex": "all_passed",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "All Passed",
"renderer": "RenderFailedTests"
}
]
},
"tests": [
{
"poller": "CHI",
"poll_date": "2013-03-06",
"PING": "1",
"SNMP": "0",
"TELNET": "1",
"SSH": "0",
"all_passed": "0"
},
{
"poller": "DAL",
"poll_date": "2013-03-06",
"PING": "1",
"SNMP": "0",
"TELNET": "1",
"SSH": "0",
"all_passed": "0"
},
{
"poller": "CHI",
"poll_date": "2013-03-04",
"PING": "1",
"SNMP": "0",
"TELNET": "1",
"SSH": "0",
"all_passed": "0"
},
{
"poller": "DAL",
"poll_date": "2013-03-04",
"PING": "1",
"SNMP": "0",
"TELNET": "1",
"SSH": "0",
"all_passed": "0"
},
{
"poller": "CHI",
"poll_date": "2013-03-01",
"PING": "1",
"SNMP": "0",
"TELNET": "1",
"SSH": "0",
"all_passed": "0"
}
]
}
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.reader.Json -> Response MetaData section
in the grid don't forget to add this one columns: [], then under the store listeners: { 'metachange': function(store, meta) { myGrid.reconfigure(store, meta.columns); } } and the response json file should have metaData with fields and columns. Read Response MetaData section in the documentation for more info.
You can create grid definition in runtime. Look at the reconfigure method: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.grid.Panel-method-reconfigure
Related
I have a remote data and I am trying to build Kendo UI Chart's DataSource. The remote data represents a generic data model for most charts. The model goes like this,
model: {
fields: {
Title: { field: "Title", type: "string" },
XLabel: { field: "XLabel", type: "string" },
YLabel: { field: "YLabel", type: "string" },
Legend: [
{?????????{ type: "string" }}
]
},
hasChildren: true,
children: "ChartDataSets"
}
}
Sample of remote data:
{
"Chart": [
{
"Title": "1",
"XLabel": "",
"YLabel": "",
"Legend": [ "P1","P2","P3"],
"ChartDataSets": [
{
"GroupName": "Week 0",
"Series": [
{
"Key": "2015",
"Value": 42
},
{
"Key": "2016",
"Value": 42
}
]
},
{
"GroupName": "Week 1",
"Series": [
{
"Key": "2015",
"Value": 52
},
{
"Key": "2016",
"Value": 32
}
]
}
]
}
]
}...
So Legend is an array of strings and ChartDataSets is an array of json objects. How do I represent Legend as an array or that it has children?
Also, would you recommend using Hierarchical DataSource? How is the performance affected if I use Hierarchical DataSource?
__________Never Mind - Found it ____________
Solution:
model: {
fields: {
Title: { field: "Title", type: "string" },
XLabel: { field: "XLabel", type: "string" },
YLabel: { field: "YLabel", type: "string" },
Legend: [{field: "Legend"}]
},
hasChildren: true, ...
I am trying to create a tree from json file. The JSON data is:
[
{
"root": {
"text": "Root Node",
"expanded": true,
"children": [
{
"text": "Invisible",
"leaf": true,
"children": [
{
"text": "Bookmark 2",
"leaf": true
},
{
"text": "Bookmark 3",
"leaf": true
}
]
},
{
"text": "Visible",
"leaf": true,
"children": [
{
"text": "Bookmark 4",
"leaf": true
},
{
"text": "Bookmark 5",
"leaf": true
}
]
}
]
}
}
]
Here is the code I am using for my store:
Ext.define('DHT.store.Categories', {
extend: 'Ext.data.TreeStore',
model: 'DHT.model.Category',
autoLoad: true,
autoSync: true,
proxy: {
type: 'ajax',
url: 'treedata.json',
reader:
{
type: 'json'
}
}
});
and here is the code for tree:
Ext.define('DHT.view.Category.CategoryList', {
extend: 'Ext.tree.Panel',
alias: 'widget.treeList',
width: 200,
height: 400,
store: Ext.create('DHT.store.Categories'),
rootVisible: false
});
The above code is only showing folder image that keep on expanding! Can someone point out the problem?
You have leaf: true and children, this is not possible
{
"text": "Invisible",
"leaf": true,
"children": [
{
"text": "Bookmark 2",
"leaf": true
},
...
]
}
correct:
{
"text": "Invisible",
"leaf": false,
"children": [
{
"text": "Bookmark 2",
"leaf": true
},
...
]
}
You have to define a root property in your treestore
The root property needs to be consistent, in your case it would be 'root', 'children', 'children'
Read this: Treepanel with nested data from JSON
I'm creating a MVC extjs application. I've got a treepanel with a store, which is loading the data from a php source.
I get the following json-formatted response:
[
{
"text": "Home",
"leaf": true,
"dbName": "NULL",
"children": []
},
{
"text": "Moje Firma s.r.o.",
"leaf": false,
"expanded": false,
"children": [
{
"text": "Vydane",
"leaf": true,
"dbName": "demo"
},
{
"text": "Prijate",
"leaf": true,
"dbName": "demo"
}
]
},
{
"text": "Já Živnostník",
"leaf": false,
"expanded": false,
"children": [
{
"text": "Vydane",
"leaf": true,
"dbName": "demo_de"
},
{
"text": "Prijate",
"leaf": true,
"dbName": "demo_de"
}
]
},
{
"text": "Nezisková organizace",
"leaf": false,
"expanded": false,
"children": [
{
"text": "Vydane",
"leaf": true,
"dbName": "demo_neziskova"
},
{
"text": "Prijate",
"leaf": true,
"dbName": "demo_neziskova"
}
]
},
{
"text": "Příspěvková organizace",
"leaf": false,
"expanded": false,
"children": [
{
"text": "Vydane",
"leaf": true,
"dbName": "demo_prispevkovka"
},
{
"text": "Prijate",
"leaf": true,
"dbName": "demo_prispevkovka"
}
]
},
{
"text": "Moje Firma SK s.r.o.",
"leaf": false,
"expanded": false,
"children": [
{
"text": "Vydane",
"leaf": true,
"dbName": "demo_sk"
},
{
"text": "Prijate",
"leaf": true,
"dbName": "demo_sk"
}
]
}
]
My store:
Ext.define('Statistics.store.Menu', {
extend: 'Ext.data.TreeStore',
model: 'Menu',
autoLoad: true,
autoSync: true,
proxy : {
type : 'ajax',
url : 'data.json',
reader: {
type: 'json'
}
}
});
And model:
Ext.define('Statistics.model.Menu', {
extend: 'Ext.data.Model',
fields: [
{name: 'text', type: 'string'},
{name: 'leaf', type: 'boolean'},
{name: 'expanded', type: 'boolean', defaultValue: false},
{name: 'dbName', type: 'string', defaultValue: 'NULL'}
],
});
This configuration works, when the data are saved in a .json file. But id doesn't work, when they are loaded from a php source.
Thanks for any answer.
The server response must look like this:
{
success: true,
children: // here is the array of items
}
Your field says db_name and json response says 'dbName'. Is it a typo can you check?
I am trying to load some data from the json file hosted on the local server but I am getting an error "XMLHttpRequest cannot load http://localhost:8080/data.json?_dc=1355779280677&page=1&start=0&limit=25. Origin null is not allowed by Access-Control-Allow-Origin. " as soon as the application loads. My list is not populated with the records.
My code is as below.
Ext.define('POC.view.HomePage', {
extend: 'Ext.TabPanel',
requires:['Ext.TitleBar','Ext.dataview.List',
'Ext.Ajax','Ext.data.proxy.Ajax'],
xtype:'homePage',
alias: 'widget.wuHomePageView',
config: {
fullscreen: true,
items: [
{
title: 'Home',
iconCls: 'home',
items: [
{
xtype: 'list',
title: 'Sample',
height: '100%',
onItemDisclosure: true,
store: {
autoLoad: true,
fields: ['name'],
proxy: {
type: 'json',
url: 'http://localhost:8080/data.json',
reader: {
type: 'ajax',
rootProperty: 'stores'
}
}
},
itemTpl: '{name}',
}],
},
{
title: 'Contact',
iconCls: 'user',
html: 'Contact Screen'
}
]
},
});
My Json File is as below.
{
"stores": [
{
"name": "Science Gallery",
"logo": "sciencegallery.jpg",
"desc": "Get some food",
"telephone": "016261234",
"city": "Dublin",
"add1": "Pearse Street",
"post": "2",
"country": "Ireland",
"latitude": "53.34422",
"longitude": "-6.25006",
"menu": [
{
"item": "SC Sandwich"
},
{
"item": "SC Toasted Sandwich"
},
{
"item": "SC Panini"
},
{
"item": "SC Ciabatta"
},
{
"item": "SC Burrito"
}
]
},
{
"name": "Spar",
"logo": "spar.jpg",
"desc": "Get some food",
"telephone": "016261234",
"city": "Dublin",
"add1": "Mayor Street",
"post": "2",
"country": "Ireland",
"latitude": "53.34422",
"longitude": "-6.25006",
"menu": [
{
"item": "Spar Sandwich"
},
{
"item": "Spar Toasted Sandwich"
},
{
"item": "Spar Panini"
},
{
"item": "Spar Ciabatta"
},
{
"item": "Spar Burrito"
}
]
}
]
}
Please help.
Thanks
There is no such a thing like a json proxy! You have to use an ajax proxy:
proxy: {
type: 'ajax',
.....
}
My question is: How can I load the TreeStore at once?
Because right now, if I'm using proxy, to get Tree after rendering, when I expand the leaf, there is one more request with GET parameter 'node' - the id of leaf node. So I need to response with the tree of this leaf. but I want to load ALL tree at once and no more requests for that tree.
Right now I have below code:
Ext.define('AdminPanel.TreeNavigation', {
extend: 'Ext.data.Model',
fields: ['id', 'text', 'leaf', 'children']
});
var store = Ext.create('Ext.data.TreeStore', {
model: 'AdminPanel.TreeNavigation',
proxy: {
type: 'ajax',
url : 'admin/getTreeNav',
reader: {
type: 'json',
root: 'result'
}
},
root: {
expanded: true
}
});
In store I set the reader root as 'result'.
But in the json_data I've sent the 'children' attribute, like that:
{
"result": [{
"text": "\u041d\u043e\u0432\u043e\u0441\u0442\u0438",
"leaf": true,
"children": []
}, {
"text": "\u0410\u043a\u0446\u0438\u0438",
"leaf": true,
"children": []
}, {
"text": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438",
"leaf": true,
"children": []
}, {
"id": "lang",
"text": "\u042f\u0437\u044b\u043a",
"leaf": false,
"children": [{
"text": "\u041a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b",
"leaf": true,
"children": []
}]
}]
}
But needed like this:
{
"result": [{
"text": "\u041d\u043e\u0432\u043e\u0441\u0442\u0438",
"leaf": true,
"result": []
}, {
"text": "\u0410\u043a\u0446\u0438\u0438",
"leaf": true,
"result": []
}, {
"text": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438",
"leaf": true,
"result": []
}, {
"id": "lang",
"text": "\u042f\u0437\u044b\u043a",
"leaf": false,
"result": [{
"text": "\u041a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b",
"leaf": true,
"result": []
}]
}]
}
So, Tree will load all data at the TreePanel.
You need the children nodes to be sent up from the server in the children array recursively.
You do not need leaf and children attributes on the model as the model will be automatically wrapped with the NodeInterface class that will have those and more attributes (see API for the full attribute list)