Extjs tree store set leaf property value based on children property - extjs

I am using a TreeStore to load data that looks like this:
{
"categories": [{
"text": "Ext JS",
"expanded": "true",
"categories": [{
"text": "app",
"categories": [{
"text": "Application.js",
"categories": "null"
}]
},
{
"text": "button",
"expanded": "true",
"categories": [{
"text": "Button.js",
"categories": "null"
},
{
"text": "Cycle.js",
"categories": "null"
},
{
"text": "Split.js",
"categories": "null"
}]
}
]
}]
}
What I want is to set the leaf property to true or false if the categories property is null or not.
My model looks like this :
Ext.define('TestTree.model.MyModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.Boolean'
],
fields: [
{
name: 'text'
},
{
type: 'boolean',
name: 'leaf'
}
]
});
The idea was to use the calculate config of the leaf field for that but if I try to use data.get('categories') I get Field leaf depends on undefined field get and if I try to define the field categories in my model an use data.categories, nothing happens.
I don't know what I am missing!
My store looks like this:
Ext.define('TestTree.store.MyTreeStore', {
extend: 'Ext.data.TreeStore',
requires: [
'TestTree.model.MyModel',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'MyTreeStore',
autoLoad: true,
model: 'TestTree.model.MyModel',
proxy: {
type: 'ajax',
url: 'resources/data/treeData.json',
reader: {
type: 'json',
rootProperty: 'categories'
}
}
}, cfg)]);
}
});
Thank you!

Create your model with the following init method:
Ext.define("Files", {
extend : "Ext.data.Model",
fields : [{
name: 'categories'
},{
name: 'leaf',
convert : function(value, record) {
return record.get('categories') == 'null';
}
}]
});
This should fix your issue, and here is a fiddle so you can take a look: https://fiddle.sencha.com/#fiddle/gq8

I used calculate instead of convert.
From the doc
Using calculate is the simplest and safest way to define a calculated field.
So the code becomes
Ext.define("Files", {
extend : "Ext.data.Model",
fields : [{
name: 'categories'
},{
name: 'leaf',
calculate : function(data) {
return data.categories === null;
},
depends: ['categories']
}]
});

Related

Need help setting up hasMany model relationship for nested JSON and showing data in grid - EXTJS 6

I am getting some search results back from Elastic in this format
{
"took": 267,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1911,
"max_score": 29.118078,
"hits": [
{
"_index": "myIndex",
"_type": "doc",
"_id": "27c9d14495f7732c6756f0d2688874f",
"_score": 21.179974,
"_source": {
"file": {
"filename": "file1.pdf"
},
"content": "samplecontent"
}
},
{
"_index": "myIndex",
"_type": "doc",
"_id": "27c9d14495f7732c6756f0d2688874f",
"_score": 21.179974,
"_source": {
"file": {
"filename": "file2.pdf"
},
"content": "samplecontent"
}
},
{
"_index": "myIndex",
"_type": "doc",
"_id": "27c9d14495f7732c6756f0d2688874f",
"_score": 21.179974,
"_source": {
"file": {
"filename": "file3.pdf"
},
"content": "samplecontent"
}
}
]
}
}
and would like to display the hits.total (1911) in the header of my grid for example, and hits.hits._source.file.filename and hits.hits._source.content in my grid. I believe I need to setup a hasMany/belongsTo model but am a bit confused by any documentation/examples that I've found as to how to setup that relationship, as well as pick and choose those nested fields to display in the grid. Any help or clarification would be appreciated
My store is defined as
Ext.define('search.store.results', {
extend: 'Ext.data.Store',
alias: 'store.results',
model: 'search.model.hits',
autoLoad: false,
proxy: {
type: 'ajax',
url: 'http://myServer:9200/_search',
reader: {
type: 'json',
rootProperty: 'hits'
}
}
});
And my models are defined as
base
Ext.define('search.model.Base', {
extend: 'Ext.data.Model',
schema: {
namespace: 'search.model'
}
});
hits
Ext.define('search.model.hits', {
extend: 'search.model.Base',
fields: [
{name: 'total', type: 'number'}
],
hasMany:{
model: 'hit',
name: 'hit'
}
});
hit
Ext.define('search.model.hit', {
extend: 'search.model.Base',
fields: [
{name: '_source', type: 'source'}
]
});
source
Ext.define('search.model.source', {
extend: 'search.model.Base',
fields: [
{name: 'file', type: 'file'},
{name: 'content', type: 'string'}
]
});
and file
Ext.define('search.model.file', {
extend: 'search.model.Base',
fields: [
{name: 'filename', type: 'string'}
]
});
however when I load my page I get these errors right off the bat
Uncaught Error: [Ext.createByAlias] Unrecognized alias: data.field.source
and
Uncaught Error: [Ext.createByAlias] Unrecognized alias: data.field.file
UPDATE: This is what the results look like if I change my models to use 'reference' instead of hasMany
Ext.define('search.model.hits', {
extend: 'search.model.Base',
fields: [
{name: 'total', type: 'number'},
{name: 'hits', reference: 'hit'}
]
});
Ext.define('search.model.hit', {
extend: 'search.model.Base',
fields: [
{name: '_source', reference: 'source'}
]
});
Ext.define('search.model.source', {
extend: 'search.model.Base',
fields: [
{name: 'file', reference: 'file'},
{name: 'content', type: 'string'}
]
});
Ext.define('search.model.file', {
extend: 'search.model.Base',
fields: [
{name: 'filename', type: 'string'}
]
});
My store 'load' listener shows this information, broken into separate data structures instead of all being under the 'data' structure where the arrow is (where I'm used to finding my store records)
UPDATE #2:
If I modify my 'hits' model to use hasMany but leave the rest using 'reference' it appears to work as far as grouping my data properly in the records - now I just need to know how to display the nested results in a grid
Ext.define('search.model.hits', {
extend: 'search.model.Base',
fields: [
{name: 'total', type: 'number'}
],
hasMany:{
model: 'hit',
name: 'hit'
}
});
produces

Extjs TreeStore data being ignored

I think I have everything correct here :
A simple model :
Ext.define('js.model.MyModel', {
extend: 'Ext.data.Model',
fields: [
{
name: "name",
type: "string"
},
{
name: "type",
type: "string"
}
]
});
A tree panel with tree store :
Ext.define('js.packageDialog.ReleaseTreeView.PackageTree', {
extend: 'Ext.tree.Panel',
rootVisible: true,
singleExpand: false,
initComponent: function () {
//Ext.create('js.model.MyModel');
Ext.apply(this, {
store: new Ext.data.TreeStore({
model: 'js.model.MyModel',
"root": {
"expanded": true,
"name": "",
"type": ""
},
proxy: {
type: 'memory'
//data: data
}
}),
columns: [
{
xtype: 'treecolumn',
text: 'Name',
dataIndex: 'name'
},
{
text: 'Parents',
dataIndex: 'parents'
}
]
});
this.callParent();
},
loadData : function() {
this.store.setRootNode(data);
}
});
Some data :
var data = Ext.JSON.encode({
"children": [{
"type": "folder",
"name": "Photos",
"children": [{
"type": "JPEG",
"name": "wedding picture"
}, {
"type": "JPEG",
"name": "holiday picture"
}
]
}]
});
I put all this together. See the fiddle :
http://jsfiddle.net/x527x57t/
And nothing is shown in the tree panel. The columns are correct, however my loadData() method does not work.
I have got it to work like so:
var data = {
children: [{
text: "Photos",
leaf:false,
children: [{
"type": "JPEG",
text: "wedding picture",
leaf:true
}, {
text: "holiday picture",
leaf:true
}]
}]
};
Ext.define('js.model.MyModel', {
extend: 'Ext.data.Model',
fields: [
{
name: "text",
type: "string"
},
{
name: "type",
type: "string"
},
{
name:"leaf"
}
]
});
Ext.define('js.packageDialog.ReleaseTreeView.PackageTree', {
extend: 'Ext.tree.Panel',
rootVisible: true,
singleExpand: false,
initComponent: function () {
Ext.apply(this, {
store: new Ext.data.TreeStore({
model: 'js.model.MyModel',
root: {
expanded: true
//type: ""
},
proxy: {
type: 'memory'
//data: data
}
})
});
this.callParent();
},
loadData : function() {
this.store.setRootNode(data);
}
});
So specifying which are leaf nodes in the data, also properties like the root of your TreeStore was wrapped in quotes, so I just amended. The data is now displaying. This may not be the 'correct' answer but one I can offer so far for you. Hope it helps.

Extjs load combobox from store

i want to load my Combobox in a Panel from Store.
var colors = new Object();
Ext.onReady(function(){
colors = Ext.create('Ext.data.Store', {
fields: ['id', 'name'],
autoLoad: true,
proxy: {
type: 'ajax',
url: 'app/view/main/loadFromDatabase.php',
reader: {
type: 'json',
rootProperty: 'name'
}
},
});
The colors i want load a little bit later in my Panel like this:
{ xtype: 'combo',
fieldLabel: 'Farbe',
name: 'farbe',
store: colors ,
queryMode: 'local',
displayField: 'name',
valueField: 'id' }
The response of my ajax request of loadFromDatabase.php is:
[
{
"id": "1",
"name": "Red"
},
{
"id": "2",
"name": "Blue"
},
{
"id": "3",
"name": "Green"}]
this seems like a valid json.
But when i click on the combobox the box is empty. Whats wrong?
Add these to your combo:
listeners : {
added : function(tis) {
tis.getStore().load();
}
}
and add these to your store:
listeners : {
load : function() {
Ext.getCmp('yourcomboid').setValue(Ext.getCmp('yourcomboid').getValue());
}
}
at last, to avoid second loading, add the following to the combo:
mode : 'local'
full code :
{
xtype : 'combo',
fieldLabel : 'Role Selection',
id : 'role',
hiddenName : 'role',
hiddenValue : 1,
editable : false,
emptyText : 'Please select a role',
typeAhead : true,
triggerAction : 'all',
lazyRender : true,
mode : 'local',
listeners : {
added : function(
tis) {
tis.getStore().load();
}
},
store : new Ext.data.JsonStore(
{
url : 'getRole',
listeners : {
load : function() {
Ext.getCmp('role').setValue(Ext.getCmp('role').getValue());
}
},
fields : ['id','name' ],
root : 'resultList',
}),
displayField : 'name',
valueField : 'id'
}
Your json should look like the below
'items': [{
'name': 'Lisa',
"email": "lisa#simpsons.com",
"phone": "555-111-1224"
}, {
'name': 'Bart',
"email": "bart#simpsons.com",
"phone": "555-222-1234"
}, {
'name': 'Homer',
"email": "home#simpsons.com",
"phone": "555-222-1244"
}]
Then you can specify your store as
var myStore = Ext.create('Ext.data.Store', {
fields:['name','email','phone'],
proxy: {
type: 'ajax',
url: '/yourpath.json',
reader: {
type: 'json',
root: 'items'
}
},
autoLoad: true
});
So you have to make your json as key with array of objects and specify that key in the root property in reader config.There is also no rootProperty property for a normal store.Remove that as well.
Hope this helps you.
i have found an other solution
i donĀ“t know if this solution is better then the other, but it works :)
var colorsFromDB = [];
var colors = Ext.create('Ext.data.Store', {
id: "colors",
fields: ['id', 'name'],
data : colorsFromDB
});
Ext.Ajax.request({
url: "app/view/main/loadFromDatabase.php",
method: 'POST',
success: function( r ) {
var res = Ext.decode(r.responseText);
if (res !== null) {
Ext.each(res.colors, function(obj) {
colorsFromDB.push({
id: obj.id,
name: obj.name
})
});
colors.loadData(colorsFromDB);
}
},
failure: function( r ) {
console.log(r.responseText);
}
});

JSON data is not getting populated in tree panel in extjs 4.2.x

With below configuration i am not able to populated json data in tree panel.
After loading store from server i am not able to see any records in console logs.
Is there any specific json structure need to be send from server?
Is there any configuration miss?
Below is the config i am using
MODEL
Ext.define('nsoapp.model.nso.Client', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field'
],
fields: [
{
name: 'jsxid'
},
{
name: 'name'
},
{
name: 'type'
},
{
name: 'countryId'
},
{
name: 'contact'
},
{
name: 'email'
}
]
});
STORE
Ext.define('nsoapp.store.nso.Client', {
extend: 'Ext.data.TreeStore',
requires: [
'nsoapp.model.nso.Client',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
model: 'nsoapp.model.nso.Client',
storeId: 'nso.Client',
defaultRootProperty: 'record',
proxy: {
type: 'ajax',
url: '/client/',
reader: {
type: 'json',
root: 'populateClientRes'
}
}
}, cfg)]);
}
});
TREE PANEL
xtype: 'treepanel',
flex: 1,
margins: '0 0 3 0',
itemId: 'treeClient',
overlapHeader: false,
title: 'Clients',
titleCollapse: false,
animate: true,
displayField: 'name',
rootVisible: false,
viewConfig: {
rootVisible: false
}
In controller i am binding tree store to tree panel
var storeClient=this.getStore('nso.ordermanagement.clientcustomization.Client');
storeClient.load({
callback: function(records, operation, success) {
var treeClient=Ext.ComponentQuery.query("#treeClient")[0];
treeClient.bindStore(storeClient);
}
});
JSON DATA
{
"populateClientRes":{
"record":[
{
"name":"A_KPI",
"type":"CLIENT",
"jsxid":"14487361",
"countryId":"484",
"contact":"34434334",
"email":"",
"record":[
{
"name":"Products",
"value":"1",
"type":"PRODUCT"
},
{
"name":"Stores",
"value":"1",
"type":"STORE"
}
]
},
{
"name":"aCCStudyTest",
"type":"CLIENT",
"jsxid":"14425073",
"countryId":"484",
"contact":"1234567890",
"email":"",
"record":[
{
"name":"Products",
"value":"1",
"type":"PRODUCT"
},
{
"name":"Stores",
"value":"1",
"type":"STORE"
}
]
}
]
}
}
Short answer: JSON response is wrong!
Long answer
You specify as root populateClientRes so all children (and children of children) must use this tag.
Standard JSON response:
{
"success": true,
"children": [
{
"id": 1,
"name": "Phil",
"leaf": true
},
{
"id": 2,
"name": "Nico",
"expanded": true,
"children": [
{
"id": 3,
"name": "Mitchell",
"leaf": true
}
]},
{
"id": 4,
"name": "Sue",
"loaded": true
}
]
}
In your case you have to replace record with populateClientRes:
{
"success": true,
"populateClientRes": [
{
"name":"A_KPI",
"type":"CLIENT",
"jsxid":"14487361",
"countryId":"484",
"contact":"34434334",
"email":"",
"populateClientRes": [
{
...
}, {
...
populateClientRes: [{...},{...}]
},
]
},
{
...
}
]
}
Important notes
For all non-leaf nodes that do not have children (for example, Person with name Sue above), the server response MUST set the loaded property to true. Otherwise the proxy will attempt to load children for these nodes when they are expanded.
You find more information's here

How to create Extjs Models and its association with other models

Hello Everyone,
I am new to EXTJS and want to grasp Extjs models and its complexity as per the json response. For Example I have a sample Json response for which I want to create a model
This is my app.js file
Ext.application({
requires: ['Ext.container.Viewport'],
name: 'AM',
appFolder: 'app',
launch: function() {
console.log('I am in app');
var store = Ext.create('AM.store.ExampleStore');
store.load();
console.log('After Loading the records');
}
});
This is json sample
[
{
"page": "0",
"data": [
{
"firstname": "puneet",
"id": "28170",
"lastname": "srivastava",
"area": "bangalore",
"profession": "Engineer"
},
{
"firstname": "v Durga",
"id": "28171",
"lastname": "Mallikrjuna",
"area": "bangalore",
"profession": "Extjs developer"
}
]
}
]
I created models as per my understanding. Model belongs to data part of json
Ext.define('AM.model.Example', {
extend: 'Ext.data.Model',
fields: ["firstname", "id", "lastname", "area", "profession"],
belongsTo : 'AM.model.Page'
});
Ext.define('AM.model.Page', {
extend: 'Ext.data.Model',
fields: ["page", "data"],
hasMany:{ model:"AM.model.Example", name: "example", associationKey : "data" }
});
Ext.define('AM.store.ExampleStore', {
extend: 'Ext.data.Store',
model : "AM.model.Page",
proxy: {
type: 'ajax',
url: 'example.json',
reader: {
type: 'json',
root: 'spaces'
}
},
listeners : {
'load' : function(store, records, successful) {
console.log('Loading the records');
console.log(store.data);
}
}
})
The data which I am getting after logging the store that contains only {page : 0} and the data part is missing.
Just want to know Where I am making the mistake or Any thing I am not including in the store or models.
Thanks
The Model should be:
Ext.define('AM.model.Example', {
extend: 'Ext.data.Model',
fields: [
{name: 'firstname', type: 'string'},
{name: 'id', type: 'int'},
...
});
in your case, root should be data. Root means master node of your Json object.
Ext.define('AM.store.ExampleStore', {
extend: 'Ext.data.Store',
model : "AM.model.Page",
proxy: {
type: 'ajax',
url: 'example.json',
reader: {
type: 'json',
root: 'data'
}
},
listeners : {
'load' : function(store, records, successful) {
console.log('Loading the records');
console.log(store.data);
}
}
})

Resources