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
Related
I have a treepanel in ExtJS 4.2.1.
The tree data is shown in the panel but everytime I expand a node, I get the same information below the node and so to the infinite.
I'm not getting the real children items. You can appreciate that the json response has children for the parent nodes but somehow everytime I expand one node, an ajax call to my service is done and thus I get again all the tree data structure.
This is my json:
[
{
"text": "QUALITY AREA",
"cls": null,
"expanded": false,
"checked": false,
"leaf": false,
"children": [
{
"text": "JUNIOR A",
"cls": null,
"expanded": false,
"checked": false,
"leaf": true,
"children": null
}
]
},
{
"text": "HUMAN RESOURCES",
"cls": null,
"expanded": false,
"checked": false,
"leaf": false,
"children": [
{
"text": "SENIOR C",
"cls": null,
"expanded": false,
"checked": false,
"leaf": true,
"children": null
}
]
},
{
"text": "IT DEPARTMENT",
"cls": null,
"expanded": false,
"checked": false,
"leaf": false,
"children": [
{
"text": "JUNIOR E",
"cls": null,
"expanded": false,
"checked": false,
"leaf": true,
"children": null
}
]
},
{
"text": "TRAINING",
"cls": null,
"expanded": false,
"checked": false,
"leaf": false,
"children": [
{
"text": "JUNIOR F",
"cls": null,
"expanded": false,
"checked": false,
"leaf": true,
"children": null
}
]
},
{
"text": "BENEFITS & COMP",
"cls": null,
"expanded": false,
"checked": false,
"leaf": false,
"children": [
{
"text": "SENIOR D",
"cls": null,
"expanded": false,
"checked": false,
"leaf": true,
"children": null
}
]
},
{
"text": "ADMIN",
"cls": null,
"expanded": false,
"checked": false,
"leaf": false,
"children": [
{
"text": "CHIEF A",
"cls": null,
"expanded": false,
"checked": false,
"leaf": true,
"children": null
}
]
}
],
This is my treepanel:
{
xtype: 'treepanel',
itemId: 'treepaneltest',
store: store,
rootVisible: false,
useArrows: true,
frame: true,
title: 'Check Tree',
width: 500,
height: 250,
}
Do I have to change something in my json?
Can you show the store.
Ideally the tree store should look like this as stated below.
Ext.define('MyApp.store.Hierarchies',{
extend: 'Ext.data.TreeStore',
model : 'MyApp.model.Hierarchy',
proxy: {
type: 'ajax',
url: 'path-to-json-file.json',
},
root: {
text: 'Root',
id: 'root',
iconCls: 'cls',
expanded: false,
}
});
I have a following JSON reply from server:
{
"stats": [
{
"text": "Home",
"leaf": true,
"dbName": "home"
},
{
"text": "Sveatlo",
"expanded": false,
"leaf": false,
"dbName": "sveatlo",
"children": [
{
"text": "Vydané faktúry",
"leaf": true,
"dbName": "vydane-faktury"
},
{
"text": "Prijaté faktúry",
"leaf": true,
"dbName": "prijate-faktury"
}
]
},
{
"text": "Hájočka",
"expanded": false,
"leaf": false,
"dbName": "hajocka",
"children": [
{
"text": "Vydané faktúry",
"leaf": true,
"dbName": "vydane-faktury"
},
{
"text": "Prijaté faktúry",
"leaf": true,
"dbName": "prijate-faktury"
}
]
}
],
"success": true,
"contacts": [
{
"text": "Address book",
"leaf": true,
"dbName": "addressbook"
},
{
"text": "Contacts",
"leaf": true,
"dbName": "contacts"
}
]
}
And I have two treepanels "stats" and "contacts". I want to load content for both of them with one request. Currently my treepanels' definition look like this:
items: [{
xtype: 'treepanel',
title: 'Statistics',
id: 'statsMenu',
store: Ext.getStore('MenuStats').load({
params: {
auth: sessionStorage.authSessionId,
hostname: sessionStorage.hostname
}
}),
rootVisible: false,
}{
xtype: 'treepanel',
title: 'Contacts',
id: 'contactsMenu',
store: Ext.getStore('MenuContacts'),
rootVisible: false,
}]
But I want the 2nd treepanel ("Contacts") to use the same treestore just with another root.
Is there any way to manage this?
Thanks for any answer.
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?
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)
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