GridX Tree Expando REST call (large dataset) with Async datastore - json

I am using GridX and I am looking to create a grid with 'expandoes' similar to http://oria.github.io/gridx/demos/tree.html and the example 'All expandoes in one column, async store'
I want to populate the grid using a JSON that has been returned from a REST call.
However, the JSON is too big (50MB) so I want to break it down.
I want to be able to populate the grid with the minimum amount of data that the user needs to see, then when the click on an expando, another REST call is made and the row's children are returned and added to the grid.
require([
'dojo/parser',
'dojo/_base/Deferred',
'gridx/tests/support/data/TreeColumnarTestData',
'gridx/tests/support/data/TreeNestedTestData',
'gridx/tests/support/stores/ItemFileWriteStore',
'gridx/allModules',
'gridx/Grid',
'gridx/core/model/cache/Sync',
'gridx/core/model/cache/Async',
'dijit/ProgressBar',
'dijit/form/NumberTextBox',
'dojo/domReady!'
], function(parser, Deferred, dataSource, nestedDataSource, storeFactory, modules){
store = storeFactory({
dataSource: dataSource,
maxLevel: 4,
maxChildrenCount: 10
});
store.hasChildren = function(id, item){
return item && store.getValues(item, 'children').length;
};
store.getChildren = function(item){
return store.getValues(item, 'children');
};
storeAsync = storeFactory({
isAsync: true,
dataSource: dataSource,
maxLevel: 4,
maxChildrenCount: 10
});
storeAsync.hasChildren = function(id, item){
return item && storeAsync.getValues(item, 'children').length;
};
storeAsync.getChildren = function(item){
var d = new Deferred();
console.log('getChildren: ', storeAsync.getIdentity(item));
setTimeout(function(){
var children = storeAsync.getValues(item, 'children');
d.callback(children);
}, 1000);
return d;
};
storeNested = storeFactory({
dataSource: nestedDataSource,
maxLevel: 4,
maxChildrenCount: 10
});
storeNested.hasChildren = function(id, item){
return item && storeNested.getValues(item, 'children').length;
};
storeNested.getChildren = function(item){
var d = new Deferred();
setTimeout(function(){
var children = storeNested.getValues(item, 'children');
d.callback(children);
}, 1000);
return d;
};
var progressDecorator = function(){
return [
"<div data-dojo-type='dijit.ProgressBar' data-dojo-props='maximum: 10000' ",
"class='gridxHasGridCellValue' style='width: 100%;'></div>"
].join('');
};
layout1 = [
//Anything except natual number (1, 2, 3...) means all levels are expanded in this column.
{id: 'number', name: 'number', field: 'number',
expandLevel: 'all',
width: '200px',
widgetsInCell: true,
decorator: progressDecorator,
editable: true,
editor: 'dijit/form/NumberTextBox'
},
{id: 'id', name: 'id', field: 'id'},
{id: 'string', name: 'string', field: 'string'},
{id: 'date', name: 'date', field: 'date'},
{id: 'time', name: 'time', field: 'time'},
{id: 'bool', name: 'bool', field: 'bool'}
];
layout2 = [
//Expandable column defaults to the first one, if no expandLevel provided.
{id: 'id', name: 'id', field: 'id'},
{id: 'number', name: 'number', field: 'number',
widgetsInCell: true,
decorator: progressDecorator
},
{id: 'string', name: 'string', field: 'string'},
{id: 'date', name: 'date', field: 'date'},
{id: 'time', name: 'time', field: 'time'},
{id: 'bool', name: 'bool', field: 'bool'}
];
layout3 = [
{id: 'number', name: 'number', field: 'number'},
{id: 'string', name: 'string', field: 'string'},
{id: 'date', name: 'date', field: 'date'},
{id: 'time', name: 'time', field: 'time'},
{id: 'bool', name: 'bool', field: 'bool'},
{id: 'id', name: 'id', field: 'id'}
];
layout4 = [
{id: 'id', name: 'id', field: 'id'},
{id: 'number', name: 'number *', field: 'number', expandLevel: 1},
{id: 'string', name: 'string *', field: 'string', expandLevel: 2},
{id: 'date', name: 'date', field: 'date'},
{id: 'time', name: 'time *', field: 'time', expandLevel: 3},
{id: 'bool', name: 'bool', field: 'bool'}
];
mods = [
modules.Tree,
modules.Pagination,
modules.PaginationBar,
modules.ColumnResizer,
// modules.SelectRow,
modules.ExtendedSelectRow,
modules.CellWidget,
modules.Edit,
modules.IndirectSelectColumn,
modules.SingleSort,
modules.VirtualVScroller
];
parser.parse();
});
<div id='grid2' jsid='grid2' data-dojo-type='gridx.Grid' data-dojo-props='
cacheClass: "gridx/core/model/cache/Async",
store: storeAsync,
structure: layout2,
paginationBarSizes: [1, 2, 0],
modules: mods
'></div>
Here is the code that is used in the example. I've removed the non-async stores and the nested stores from the code. I'm not sure how to create:
A. the original data store. What type does it have to be? dojo.store.memory? or should it be a jsonrest store?
B. I assume that I need to make changes to the getChildren function and add in something here to be responsible for fetching the additional data (the children of the expanded row)?
Can I just call back the children and will they be added to the async store automatically.
Has anyone done something like this before? Any advice or recommendations would be greatly appreciated.
Thanks

Look into dojo's JsonRest and see if that helps.
Your getChildren method would look like this:
store.getChildren = function(item) {
return this.query(item.childId);
};

Related

Add column values together in jqGrid and insert into label

I have a jqGrid inside of a div orderForm that can have a verifying number of rows added to it by a user.
What I would like to do is: whenever a user adds a row to the jqGrid, the totals in the TOTAL_LINE_AMOUNT column are added together and inserted into the label Subtotal
$('#orderForm).jqGrid({
data: details,
datatype: 'local',
colNames: ['ID', 'QUANTITY', 'MODEL_ORDER_NUM', 'DESCRIPTION', 'PRICE_EACH', 'TOTAL_LINE_AMOUNT'],
colModel: [
{ name: 'DETAIL_RECORD_ID', index: 'DETAIL_RECORD_ID', sorttype: 'string' },
{ name: 'QUANTITY', index: 'QUANTITY', sorttype: 'string' },
{ name: 'MODEL_ORDER_NUM', index: 'MODEL_ORDER_NUM', sorttype: 'string' },
{ name: 'DESCRIPTION', index: 'DESCRIPTION', sorttype: 'string' },
{ name: 'PRICE_EACH', index: 'PRICE_EACH', sorttype: 'string' },
{ name: 'TOTAL_LINE_AMOUNT', index: 'TOTAL_LINE_AMOUNT', sorttype: 'string' }
],
search: true,
onSelectRow: LoadInput,
loadonce: false,
jsonReader: { cell: '' },
sortname: 'DETAIL_RECORD_ID',
sortorder: 'asc',
sortable: true,
ignoreCase: true,
viewrecords: true,
height: 'auto',
width: 'auto',
shrinkToFit: false,
hiddengrid: false,
caption: 'Detail Records'
});
UPDATE: Here is how I load data into my grid
Form.Controller.orderForm = new function () {
var _detailRecordId = 1;
this.Create = function () {
var requestData = Controller.GetRequestData();
requestData.orderForm.push({
DETAIL_RECORD_ID: "T" + _detailRecordId++,
REQUEST_RECORD_ID: requestData.REQUEST_RECORD_ID,
QUANTITY: $('#orderForm_QUANTITY_INPUT').val(),
MODEL_ORDER_NUM: $('#orderForm_MODEL_ORDER_NUM_INPUT').val(),
DESCRIPTION: $('#orderForm_DESCRIPTION_INPUT').val(),
PRICE_EACH: $('#orderForm_PRICE_EACH_INPUT').val(),
TOTAL_LINE_AMOUNT: $('#orderForm_TOTAL_LINE_AMOUNT_INPUT').text()
});
Form.View.orderFrom.LoadGrid(requestData.orderForm);
};
Your code doesn't show which editing mechanism your are using with jqGrid so it is hard to say on which event you should subscribe (most porobably it should be either jqGridInlineAfterSaveRow or jqGridAddEditAfterComplete).
Getting the sum of column is very simple as jqGrid has a ready to use method for this:
var subTotal = $('#orderForm').jqGrid('getCol', 'TOTAL_LINE_AMOUNT', false, 'sum');
Depending of what kinf of HTML element your label is you should be able to set its text with one of following:
$('#Subtotal').text(subTotal);
or
$('#Subtotal').val(subTotal);

sencha touch local storage insert ID

I have a small problem if you can help me it would be great. I cant insert my own ID to the local storage.
ext.define('EMC.model.ReferenceData', {
extend: 'Ext.data.Model',
config: {
identifier: {
type: 'simple'
},
idProperty: 'Id',
fields: [
{name: 'Id', type: 'string'},
{name: 'Description', type: 'string'},
{name: 'syncChangeVersion', type: 'integer', mapping: 'SysChangeVersion'},
{name: 'TypeEnum', type: 'string'}
]
}
});
this is a model of my project and the store is shown below.
Ext.define("EMC.store.SyncReferenceData", {
extend : "Ext.data.Store",
requires : [ 'Ext.data.proxy.LocalStorage' ],
config : {
model : 'EMC.model.ReferenceData',
storeId : 'referenceStore',
sorters : 'Id',
proxy : {
type : 'localstorage',
id : 'reference_data'
},
autoSync : true,
autoLoad : true
}
});
this is the phrase I created to insert data to the local storage using controller.
var frmModel2 = Ext.create('EMC.model.ReferenceData',{
Id : '13',
Description : 'lole',
syncChangeVersion : 0,
TypeEnum : '199'
});
ReferenceStore.add(frmModel2);
ReferenceStore.sync();
But when I see the local storage it is empty. But If i comment Id : '13' then it will add to the local storage with a id of "ext-record-293".
why cant I inset my own Id to the store?
Try like this..
Ext.define('EMC.model.ReferenceData', {
extend: 'Ext.data.Model',
config: {
dProperty : 'uniqueid', // dummy name(not a field)
clientIdProperty : 'Id',
fields: [
{name: 'Id', type: 'string'},
{name: 'Description', type: 'string'},
{name: 'syncChangeVersion', type: 'integer', mapping: 'SysChangeVersion'},
{name: 'TypeEnum', type: 'string'}
]
}
});

Loading associations and binding grid to form

I've asked a similar question before, here: https://stackoverflow.com/questions/11707007/nested-json-form-submits-in-extjs4-getting-the-writer-to-remap-the-fields
Also asked in the Sencha forums, am pretty desperate:
I have many problems with reading and writing nested json files into an associated model.
I will write all the code that I can here, in the hope that some of you will find what I'm doing wrong.
Questions are emphasized in the text.
The json I am receiving looks like this, and can not be changed: tests:
[
{
"name":"qwerty",
"id":"1",
"uid":"1",
"created":"1341481071",
"changed":"1343804076",
"status":"1",
"jmeterOptions":{
"jmx":"\/files\/20141\/multi.jmx",
"engines":"0",
"version":"2.5.1",
"consoleArgs":" -t sample.jmx -JDelay=10000 -JEmbedded=1 -JRampup=1800 -JUsers=10",
"engineArgs":" -JDelay=10000 -JEmbedded=1 -JRampup=1800 -JUsers=10",
"instanceType":"m1.medium",
"overrideOptions":{
"threads":"50",
"rampUpTime":"300",
"iterations":"-1",
"duration":"-1"
}
},
"testOptions":{
"type":"BM_TEST_TYPE_AUTO",
"geo":"us-east-1",
"timeout":"1",
"reportByEmail":"1",
"launchTime":"0",
"sessionId":"",
"hosts":null,
"privateIps":null
},
"autoOptions":{
"users":"10",
"delay":"10",
"rampUpTime":"1800",
"pages":[
{
"label":"sencha",
"url":"http:\/\/sencha.com"
}
]
},
"seleniumOptions":{
"pages":[
{
"label":"sencha",
"url":"http:\/\/sencha.com"
}
]
}
},
{
"name":"Instant Load test",
"id":"2",
"uid":"1",
"created":"1336921297",
"changed":"1341132949",
"status":"1",
"jmeterOptions":{
"jmx":null,
"engines":"0",
"version":"2.5.1",
"consoleArgs":" -t sample.jmx -JDelay=10000 -JEmbedded=1 -JRampup=1800 -JUsers=10",
"engineArgs":" -JDelay=10000 -JEmbedded=1 -JRampup=1800 -JUsers=10",
"instanceType":"m1.medium",
"overrideOptions":null
},
"testOptions":{
"type":"BM_TEST_TYPE_AUTO",
"geo":null,
"timeout":"1",
"reportByEmail":"0",
"launchTime":"0",
"sessionId":"",
"hosts":null,
"privateIps":null
},
"autoOptions":{
"users":"10",
"delay":"10",
"rampUpTime":"1800",
"pages":[
{
"label":"",
"url":"http:\/\/cnn.com"
}
]
},
"seleniumOptions":{
"pages":[
{
"label":"",
"url":"http:\/\/cnn.com"
}
]
}
}
]
The model looks like this:
Ext.define('BM.model.Test', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'},
{name: 'id', type: 'id'},
{name: 'uid', type: 'mumber'},
{name: 'created', type: 'date', dateFormat: 'timestamp'},
{name: 'changed', type: 'date', dateFormat: 'timestamp'},
{name: 'status', type: 'number'},
{name: 'jmeterJmx', mapping: 'jmeterOptions.jmx', type: 'string'},
{name: 'jmeterEngines', mapping: 'jmeterOptions.engines', type: 'number'},
{name: 'jmeterVersion', mapping: 'jmeterOptions.version', type: 'string'},
{name: 'jmeterConsoleArgs', mapping: 'jmeterOptions.consoleArgs', type: 'string'},
{name: 'jmeterEngineArgs', mapping: 'jmeterOptions.engineArgs', type: 'string'},
{name: 'jmeterInstanceType', mapping: 'jmeterOptions.instanceType', type: 'string'},
{name: 'testOptionsType', mapping: 'testOptions.type', type: 'string'},
{name: 'testOptionsGeo', mapping: 'testOptions.geo', type: 'string'},
{name: 'testOptionsTimeout', mapping: 'testOptions.timeout', type: 'number'},
{name: 'testOptionsReportByEmail', mapping: 'testOptions.reportByEmail', type: 'string'},
{name: 'testOptionsLaunchTime', mapping: 'testOptions.launchTime', type: 'string'},
{name: 'testOptionsSessionId', mapping: 'testOptions.sessionId', type: 'string'},
{name: 'testOptionsHosts', mapping: 'testOptions.hosts', type: 'string'},
{name: 'testOptionsPrivateIps', mapping: 'testOptions.privateIps', type: 'string'},
{name: 'autoUsers', mapping: 'autoOptions.users', type: 'number'},
{name: 'autoDelay', mapping: 'autoOptions.delay', type: 'number'},
{name: 'autoRampUpTime', mapping: 'autoOptions.rampUpTime', type: 'number'}
],
hasMany: [
{model: 'Pages', name: 'autoPages', associationKey: 'autoOptions.pages'},
{model: 'Pages', name: 'seleniumPages', associationKey: 'seleniumOptions.pages'}
],
proxy: {
type: 'ajax',
api: {
read: '../webapp/get/tests',
update: '../webapp/set/test'
},
reader: {
type: 'json',
root: 'tests',
successProperty: 'success'
},
writer: new Ext.data.JsonWriter({
encode: false,
writeAllFields: true,
getRecordData: function (record) {
Ext.apply(record.data,record.getAssociatedData(true));
return record.getAssociatedData(true);
}
})
}
});
Ext.define('Pages', {
extend: 'Ext.data.Model',
fields: [
{name: 'label', type: 'string'},
{name: 'url', type: 'string'}
]
});
First Question: Including the following four lines causes the grid to load empty, why?
{name: 'jmeterOverrideThreads', mapping: 'jmeterOptions.overrideOptions.threads', type: 'number'},
{name: 'jmeterOverrideRampUpTime', mapping: 'jmeterOptions.overrideOptions.rampUpTime', type: 'number'},
{name: 'jmeterOverrideIterations', mapping: 'jmeterOptions.overrideOptions.iterations', type: 'number'},
{name: 'jmeterOverrideDuration', mapping: 'jmeterOptions.overrideOptions.duration', type: 'number'},
Second Question: The associated data comes up empty. rawData has the json as shown above, how do I make getAssociatedData to fill in the correct data?
Better yet, Why aren't my associations working?
Third Question: The writer now only sends the empty associated data, how do I send all data, exactly as I received it?
My solution to this is dead ugly:
updateTest: function(button) {
var form = button.up('panel');
var record = form.getRecord(),
values = form.getValues();
record.set(values);
var rd = record.data;
// this.getTestsStore().sync(); //No! Sends flattened data.
// var autoPages = record.getAssociatedData().autoPages; // Is currently empty
// var seleniumPages = record.getAssociatedData().seleniumPages; // Is currently empty
var autoPages = [];
var seleniumPages = [];
var iterator = 0;
var autoPagesLabel = record.data['autoPagesLabel' + iterator];
var autoPagesUrl = record.data['autoPagesUrl' + iterator];
while (autoPagesLabel != undefined){
autoPages.push({
'label': autoPagesLabel,
'url': autoPagesUrl
});
iterator++;
autoPagesLabel = record.data['autoPagesLabel' + iterator];
autoPagesUrl = record.data['autoPagesUrl' + iterator];
}
iterator = 0;
var seleniumPagesLabel = record.data['seleniumPagesLabel' + iterator];
var seleniumPagesUrl = record.data['seleniumPagesUrl' + iterator];
while (seleniumPagesLabel != undefined){
seleniumPages.push({
'label': seleniumPagesLabel,
'url': seleniumPagesUrl
});
iterator++;
seleniumPagesLabel = record.data['seleniumPagesLabel' + iterator];
seleniumPagesUrl = record.data['seleniumPagesUrl' + iterator];
}
var reformattedJson = {
"name": rd.name,
"id": rd.id,
"uid": rd.uid,
"created": rd.created,
"changed": rd.changed,
"status": rd.status,
"jmeterOptions":{
"jmx": rd.jmeterJmx,
"engines": rd.jmeterEngines,
"version": rd.jmeterVersion,
"consoleArgs": rd.jmeterConsoleArgs,
"engineArgs": rd.jmeterEngineArgs,
"instanceType": rd.jmeterInstanceType,
"overrideOptions": {
"threads": rd.jmeterOverrideThreads,
"rampUpTime": rd.jmeterOverrideRampUpTime,
"iterations": rd.jmeterOverrideIterations,
"duration": rd.jmeterOverrideDuration
}
},
"testOptions":{
"type": rd.testOptionsType,
"geo": rd.testOptionsGeo,
"timeout": rd.testOptionsTimeout,
"reportByEmail": rd.testOptionsReportByEmail,
"launchTime": rd.testOptionsLaunchTime,
"sessionId": rd.testOptionsSessionId,
"hosts": rd.testOptionsHosts,
"privateIps": rd.testOptionsPrivateIps
},
"autoOptions":{
"users": rd.autoUsers,
"delay": rd.autoDelay,
"rampUpTime": rd.autoRampUpTime,
"pages": autoPages
},
"seleniumOptions":{
"pages":seleniumPages
}
};
Ext.Ajax.request({
url: '../webapp/set/test',
method:'Post',
jsonData: reformattedJson,
success: function(response){
var text = response.responseText;
// process server response here
console.log('Post successfull! ');
}
});
}
This is the form:
Ext.define('BM.view.test.Edit', {
extend: 'Ext.form.Panel',
alias: 'widget.test-edit',
layout: 'anchor',
title: 'Edit Test',
defaultType: 'textfield',
items: [
{name: 'id', hidden: true},
{name: 'name', fieldLabel: 'Name'},
{name: 'status', fieldLabel: 'Status'},
{name: 'testOptionsType', fieldLabel: 'Type'},
{name: 'autoUsers', fieldLabel: 'User count'}
],
buttons: [
{
text: 'Save',
action: 'save'
},
{
text: 'Cancel',
scope: this,
handler: this.close
}
]
});
This is what calls the form: (Clicking on a grid row)
editTest: function(grid, record) {
var view = Ext.widget('test-edit');
var viewPort = Ext.ComponentQuery.query('viewport')[0];
var autoPages = record.raw.autoOptions.pages;
var seleniumPages = record.raw.seleniumOptions.pages;
for (var i =0; i < autoPages.length; i++){
var tf = Ext.create('Ext.form.field.Text', {
id: 'autoPagesLabel' + i,
name: 'autoPagesLabel' + i,
fieldLabel: 'Label',
value: autoPages[i].label,
columnWidth:0.5
});
view.add(tf);
tf = Ext.create('Ext.form.field.Text', {
id: 'autoPagesUrl' + i,
name: 'autoPagesUrl' + i,
fieldLabel: 'Url',
value: autoPages[i].url,
columnWidth:0.5
});
view.add(tf);
}
view.loadRecord(record);
viewPort.layout.centerRegion.removeAll();
viewPort.layout.centerRegion.add(view);
}
I tried following the MVC architecture of Ext JS 4, note by note from the tutorials, and failed miserably.
What am I doing wrong?
Do you need any other information or pieces of code? Just tell me and I'll post them.
I found a solution that works for some of my questions.
As a bypass to my first question, I find that mapping of more than two levels is problematic, so I added a hasOne relationship. I don't think it's a good solution, but have no others, would love a comment about this.
{name: 'jmeterOverrideThreads', mapping: 'jmeterOptions.overrideOptions.threads', type: 'number'},
{name: 'jmeterOverrideRampUpTime', mapping: 'jmeterOptions.overrideOptions.rampUpTime', type: 'number'},
{name: 'jmeterOverrideIterations', mapping: 'jmeterOptions.overrideOptions.iterations', type: 'number'},
{name: 'jmeterOverrideDuration', mapping: 'jmeterOptions.overrideOptions.duration', type: 'number'},
from the model, becomes:
hasOne: [
{model: 'OverrideOptions', associationKey: 'jmeterOptions', reader: {root: 'overrideOptions'}}
],
// and:
Ext.define('OverrideOptions', {
extend: 'Ext.data.Model',
fields: [
{name: 'jmeterOverrideThreads', mapping: 'threads', type: 'number'},
{name: 'jmeterOverrideRampUpTime', mapping: 'rampUpTime', type: 'number'},
{name: 'jmeterOverrideIterations', mapping: 'iterations', type: 'number'},
{name: 'jmeterOverrideDuration', mapping: 'duration', type: 'number'}
]
});
As for my second question about the associations not working:
In my model, instead of:
hasMany: [
{model: 'Pages', name: 'autoPages', associationKey: 'autoOptions.pages'},
{model: 'Pages', name: 'seleniumPages', associationKey: 'seleniumOptions.pages'}
],
I added:
hasMany: [
{model: 'Pages', name: 'autoPages', associationKey: 'autoOptions', reader: {root: 'pages'}},
{model: 'Pages', name: 'seleniumPages', associationKey: 'seleniumOptions', reader: {root: 'pages'}}
],
Suddenly, I am able to access my data from record.getAssociatedData(), it is still flattened, but at least I have the data.
I still don't have a good idea about having the writer output the data in its original format other than writing it as I did in brute force.
Would again love some feedback on that.
Other questions arose:
I want my associated data to be added to a form. As we are talking about arrays of objects, we don't know how many there will be, is there a better way to create the form from associated data than the one I used in my original question. Is there a better way to access the form data, other than naming the fields with a running iterator: a1, a2,...
Thanks in advance for any answer.

Ext.JS Prevent Proxy from sending extra fields

Here is my model:
Ext.define('A.model.Group', {
extend: 'Ext.data.Model',
fields:['id', 'name'],
proxy: {
type: 'rest',
url: '/group',
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json',
writeAllFields: false
}
}
});
The model is being used in a Tree via a TreeStore
The problem is that when a PUT, POST or DELETE method is done, instead of sending only fields from the model in the JSON payload, fields from Ext.data.NodeInterface are also sent. Here is an example payload:
{"id":"","name":"TestGroup","parentId":"8","index":0,"depth":3,"checked":null}
I don't want the extra fields parentId, index, depth, and checked to be sent. What is the best way to do this? I don't want to have to ignore them on the server.
If you wan't to send only specific data to server, writeAllFields is not the solution as if is set to false it only sends the modified fields.
The solution for your problem is defining your own writer and overriding the method getRecordData here is a posible example:
var newWriter = Ext.create('Ext.data.writer.Json',{
getRecordData: function(record){
return {'id':record.data.id,'name':record.data.name};
}
})
Ext.define('A.model.Group', {
extend: 'Ext.data.Model',
fields:['id', 'name'],
proxy: {
type: 'rest',
url: '/group',
reader: {
type: 'json',
root: 'data'
},
writer: newWriter
}
});
the NodeInterface adds these fields into your model:
{name: 'parentId', type: idType, defaultValue: null},
{name: 'index', type: 'int', defaultValue: null, persist: false},
{name: 'depth', type: 'int', defaultValue: 0, persist: false},
{name: 'expanded', type: 'bool', defaultValue: false, persist: false},
{name: 'expandable', type: 'bool', defaultValue: true, persist: false},
{name: 'checked', type: 'auto', defaultValue: null, persist: false},
{name: 'leaf', type: 'bool', defaultValue: false},
{name: 'cls', type: 'string', defaultValue: null, persist: false},
{name: 'iconCls', type: 'string', defaultValue: null, persist: false},
{name: 'icon', type: 'string', defaultValue: null, persist: false},
{name: 'root', type: 'boolean', defaultValue: false, persist: false},
{name: 'isLast', type: 'boolean', defaultValue: false, persist: false},
{name: 'isFirst', type: 'boolean', defaultValue: false, persist: false},
{name: 'allowDrop', type: 'boolean', defaultValue: true, persist: false},
{name: 'allowDrag', type: 'boolean', defaultValue: true, persist: false},
{name: 'loaded', type: 'boolean', defaultValue: false, persist: false},
{name: 'loading', type: 'boolean', defaultValue: false, persist: false},
{name: 'href', type: 'string', defaultValue: null, persist: false},
{name: 'hrefTarget', type: 'string', defaultValue: null, persist: false},
{name: 'qtip', type: 'string', defaultValue: null, persist: false},
{name: 'qtitle', type: 'string', defaultValue: null, persist: false},
{name: 'children', type: 'auto', defaultValue: null, persist: false}
two of them dont have `persist' property.
Most of NodeInterface's fields default to persist: false. This means they are non-persistent fields by default. Non-persistent fields will not be saved via the Proxy when calling the TreeStore's sync method or calling save() on the Model. In most cases, the majority of these fields can be left at their default persistence setting, but there are cases where it is necessary to override the persistence of some fields. The following example demonstrates how to override the persistence of a NodeInterface field. When overriding a NodeInterface field it is important to only change the persist property. name, type, and defaultValue should never be changed.
Override the fields like this:
{ name: 'iconCls', type: 'string', defaultValue: null, persist: true },
You can add a serializer to the fields in the model you do not want to send to the server.
var makeUndefined = function(value, record) {
return undefined;
}
var fieldsOfYourModel = [
{
serialize: makeUndefined,
name: 'parentId'
},
{
serialize: makeUndefined,
name: 'index'
}
];
serialize is a function which converts the Model's value for this Field into a form which can be used by whatever Writer is being used to sync data with the server. http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Field-cfg-serialize
serialize is available since Ext JS 4.1.1.

Unable to show JSON data into Grid Panel. Shows only one blank row in Grid

Unable to show JSON data into Grid. I got blank grid but you can see sequence no "1" and blank row, though number 1 is auto generated, it is not a JSON data.
code
Ext.onReady(function(){
// PRESSURE GRID - PRESSURE TAB //
var proxy=new Ext.data.HttpProxy( {url:'',method: 'POST'} );
Ext.define('pressureModel', {
extend: 'Ext.data.Model',
fields: ['month', 'KOD', 'timePeriod', 'beachBank', 'manMade', 'charterBoat', 'privateRentalBoat']
});
var pressureGridStore=new Ext.data.Store({
id: "pressureG",
model: 'pressureModel',
proxy: proxy,
reader:new Ext.data.JsonReader({
type : 'json',
root: 'pressureFi',
totalProperty: 'pressureResultLength'
},[{name:'month'},{name:'KOD'},{name:'timePeriod'},{name:'beachBank'},{name:'manMade'},{name:'charterBoat'},{name:'privateRentalBoat'}]
)
});
// Generic fields array to use in both store defs.
var pressureFields = [
{name: 'month', mapping: 'month', type: 'string'},
{name: 'KOD', mapping: 'KOD', type: 'string'},
{name: 'timePeriod', mapping: 'timePeriod', type: 'string'},
{name: 'beachBank', mapping: 'beachBank', type: 'string'},
{name: 'manMade', mapping: 'manMade', type: 'string'},
{name: 'charterBoat', mapping: 'charterBoat', type: 'string'},
{name: 'privateRentalBoat', mapping: 'privateRentalBoat', type: 'string'}
];
var pressureGrid = new Ext.grid.GridPanel({
id : "pressure-grid",
ddGroup : 'gridDDGroup',
store : pressureGridStore,
columns: [new Ext.grid.RowNumberer(),
{
text: 'Month',
width: 70,
dataIndex: 'month'
},{
text: 'Kind of Day',
width: 85,
dataIndex: 'KOD'
},{
text: 'Time Period',
width: 95,
dataIndex: 'month'
},{
text: 'Beach/Bank',
width: 65,
dataIndex: 'beachBank'
},{
text: 'Man/Made',
width: 65,
dataIndex: 'manMade'
},{
text: 'Charter Boat',
width: 75,
dataIndex: 'charterBoat'
},{
text: 'Private/Rental Boat',
width: 105,
dataIndex: 'privateRentalBoat'
}],
enableDragDrop : true,
stripeRows : true,
autoExpandColumn : 'name',
width : 624,
height : 325
});
function handleActivate(tab){ alert("in handle ");
pressureGridStore.proxy.url='siteUtil.jsp';
pressureGridStore.load({params:
{'method':'getSitePressureInfo'}
});
}
tabPanelObject = {
getTabPanel: function(siteId) {
var infoPanel = new Ext.tab.Panel({
id: 'tabPan',
xtype: 'tabpanel',
title: 'Site Information',
height: 1000,
width: '50.4%',
items:[
{
title: 'Pressure',
id: 'pressureTab',
listeners: {activate: handleActivate},
items:[
{
xtype: "panel",
width : '100%',
height : 300,
layout: 'fit',
items: [
pressureGrid
] }
]}
]
});
return infoPanel;
}
}
});
Json Response is as follow
{"pressureResultLength":"96","pressureFi":[{"charterBoat":9,"timePeriod":"0200- 0800","KOD":"WEEKDAY","beachBank":9,"month":"JAN","privateRentalBoat":9,"manMade":9}, {"charterBoat":0,"timePeriod":"0800-1400","KOD":"WEEKDAY","beachBank":9,"month":"JAN","privateRentalBoat":9,"manMade":9},{"charterBoat":0,"timePeriod":"1400-2000","KOD":"WEEKDAY","beachBank":9,"month":"JAN","privateRentalBoat":9,"manMade":9},{"charterBoat":9,"timePeriod":"2000-0200","KOD":"WEEKDAY","beachBank":9,"month":"JAN","privateRentalBoat":9,"manMade":9},{"charterBoat":9,"timePeriod":"0200-0800","KOD":"WEEKEND","beachBank":9,"month":"JAN","privateRentalBoat":9,"manMade":9},{"charterBoat":0,"timePeriod":"0800-1400","KOD":"WEEKEND","beachBank":9,"month":"JAN","privateRentalBoat":9,"manMade":9},{"charterBoat":0,"timePeriod":"1400-2000","KOD":"WEEKEND","beachBank":9,"month":"JAN","privateRentalBoat":9,"manMade":9},{"charterBoat":9,"timePeriod":"2000-0200","KOD":"WEEKEND","beachBank":9,"month":"JAN","privateRentalBoat":9,"manMade":9},{"charterBoat":9,"timePeriod":"0200-0800","KOD":"WEEKDAY","beachBank":9,"month":"FEB","privateRentalBoat":9,"manMade":9},{"charterBoat":0,"timePeriod":"0800-1400","KOD":"WEEKDAY","beachBank":9,"month":"FEB","privateRentalBoat":9,"manMade":9},{"charterBoat":0,"timePeriod":"1400-2000","KOD":"WEEKDAY","beachBank":9,"month":"FEB","privateRentalBoat":9,"manMade":9},{"charterBoat":9,"timePeriod":"2000-0200","KOD":"WEEKDAY","beachBank":9,"month":"FEB","privateRentalBoat":9,"manMade":9},{"charterBoat":9,"timePeriod":"0200-0800","KOD":"WEEKEND","beachBank":9,"month":"FEB","privateRentalBoat":9,"manMade":9},{"charterBoat":0,"timePeriod":"0800-1400","KOD":"WEEKEND","beachBank":9,"month":"FEB","privateRentalBoat":9,"manMade":9},{"charterBoat":0,"timePeriod":"1400-2000","KOD":"WEEKEND","beachBank":9,"month":"FEB","privateRentalBoat":9,"manMade":9},{"charterBoat":9,"timePeriod":"2000-0200","KOD":"WEEKEND","beachBank":9,"month":"FEB","privateRentalBoat":9,"manMade":9},{"charterBoat":9,"timePeriod":"0200-0800","KOD":"WEEKDAY","beachBank":9,"month":"MAR","privateRentalBoat":9,"manMade":9}]}
I checked the FireBug Console. It returns the response as above but it is of type(actionmethod) 'GET'
When I did
pressureGridStore.on({
'load':{
fn: function(store, records, options){
//store is loaded, now you can work with it's records, etc.
console.info('store load, arguments:', arguments);
console.info('Store count = ', store.getCount());
},
scope:this
}
});
I got Store Count = 1.
-Ankit
the problem is that your components aren't defined correctly. for instance, the reader config in extjs4 doesn't belong to store, it belongs to proxy see http://dev.sencha.com/deploy/ext-4.0.2a/docs/#/api/Ext.data.proxy.Ajax so for the proxy you should have
var proxy=new Ext.data.HttpProxy( {
url:'',
reader:new Ext.data.JsonReader({
type : 'json',
root: 'pressureFi',
totalProperty: 'pressureResultLength'
})
})
I think with this modification it should work