Cannot load data in an ExtJS gridpanel with loadData() - javascript

I need to periodically add new data in the grid's store. The store is defined by the following code:
this.reader = new Ext.data.JsonReader({
idProperty: 'id',
fields: this.lesFields
});
this.ds = new Ext.data.GroupingStore({
reader: this.reader,
data: this.leData,
sortInfo: {field: 'dendisc', direction: 'ASC'},
groupField: 'categorie'
});
When I need to append some new data, I do this using this.getStore().loadData(this.leData). Technically the data does appear in the grid's store, but I see on the display only zeros (in the int fields) and blank strings (in the string fields). I did some researches in Chrome's console and I found out that the data property and the json property are not the same in this.getStore().data. In json there is the array with valid data, but in data there are only zeros and blank strings.
Am I missing something? Would the handleAs:'json' property save the situation?

JsonReader requires root to be defined. root points the sub-property which contains the records.
here a sample taken from ext documentation:
var myReader = new Ext.data.JsonReader({
idProperty: 'id'
root: 'rows',
totalProperty: 'totalRows',
fields: [
{name: 'id' },
{name: 'name' }
]
});
and a sample data to be read:
{
success: true,
totalRows: 100,
rows: [ // root
{ id: 1, name: 'Alf' },
{ id: 2, name: 'Ben' },
{ id: 3, name: 'Cod' },
...
]
}

I am not that used to GroupingStores but I think the Reader expect a json object like { Id:0, Name: 'MyName' } or a Array of such objects and then try to match them against the registered fieldnames. But I don't know what there is in your arrays so this is just a guess

Related

How to access the data in the associated models using ExtJS stores?

I have several components, mainly home made, in a page. Each one has its own store+model+view. For performance reasons, I want to make a single AJAX request to the backend in order to get all the data at once and then navigate through each data part and assign those parts to their corresponding component's stores.
But it seems I can't get / read those parts.
I've tried to follow the tips found here Extjs4: How to share data between multiple stores or models? but without any success.
The JSON data returned by the backend looks like:
{
"success":true,
"results":8,
"data":[{
"bv01":{
"success":true,
"count":1,
"data":[{
"active_learner_count":0,
"connected_learner_count":0,
"enrolled_learner_count":123999,
"registered_learner_count":120098
}]
}
},{
"bv02":{
"success":true,
"count":1,
"data":[{
// Blabla
}]
}
},{
// 6 other embedded responses
}]
}
Here's a snippet of the stores / models I use:
The inner-most model, holding the data that are linked to a template (not shown here):
Ext.define('Ckls.module.Graphs.Square.model.Learner', {
extend: 'Ext.data.Model',
fields: [
{name: 'hugeRectCount', type: 'int', mapping: 'registered_learner_count'},
{name: 'bigRectCount', type: 'int', mapping: 'enrolled_learner_count'},
{name: 'mediumRectCount', type: 'int', mapping: 'active_learner_count'},
{name: 'smallRectCount', type: 'int', mapping: 'connected_learner_count'}
]
});
The composed model:
Ext.define('Reporting.Reporting.model.Kpi.Bv01', {
extend: 'Ext.data.Model',
fields:[{
name: "success",
type: "auto"
},{
name: "count",
type: "auto"
}],
hasMany: {
model: 'Ckls.module.Graphs.Square.model.Learner',
name: 'data'
},
belongsTo: 'Reporting.Reporting.model.Block'
});
The one-call model:
Ext.define('Reporting.Reporting.model.Block', {
extend: 'Ext.data.Model',
hasOne: [{
model: 'Reporting.Reporting.model.Kpi.Bv01',
name : "bv01"
},{
model: 'Reporting.Reporting.model.Kpi.Bv02',
name : "bv02"
},{
... // several extra models inclusions come here
}]
});
The store definition for the one-call initialization:
Ext.define('Reporting.Reporting.store.Blocks', {
extend: 'Ext.data.Store',
model: 'Reporting.Reporting.model.Block',
proxy: {
type : 'ajax',
reader: {
type: 'json',
root: 'data'
},
url: '/some_url.php?some_parameter=some_value'
}
});
The controller:
Ext.define('Reporting.Reporting.controller.Reporting', {
extend: 'Ext.app.Controller',
init: function() {
// 'activities' is my main view
this.control({
'activities': {
afterrender: this.initAllStores
});
},
initAllStores: function() {
var blockStore = Ext.create('Reporting.Reporting.store.Blocks');
var blockStoreListeners = blockStore.on('load', this.blockStoreLoaded, this);
blockStore.load();
},
blockStoreLoaded: function(store, records, successful, eOpts) {
// As far as I can tell from the documentation, this should
// return the data as read in the sub-model but it throws an
// "undefined" error
var bv01results = store.data.getBbv01();
Ext.log({msg:"bv01results", dump: bv01results});
var bv01store = someFunctionToGetThatBv01Store();
bv01store.loadRawData(bv01results);
}
}
I don't know how to access the inner data and then load them into the bv01 store. In Chrome, the console gives the error Uncaught TypeError: undefined is not a function
Edit
I've added a memory proxy to the models (as suggested here https://stackoverflow.com/a/19361382/2732205):
Ext.define('Reporting.Reporting.model.Kpi.Bv01', {
// ....
proxy: {
type: 'memory',
reader: {
type: 'json'
}
}
}
And fixed the function call in the controller to get the data:
Ext.define('Reporting.Reporting.controller.Reporting', {
// ....
blockStoreLoaded: function(store, records, successful, eOpts) {
var record0 = store.getAt(0);
Ext.log({msg:"record0", dump: record0});
// It seems that it's now trying to load the "bv01" from the
// network instead of just reading it from the record
var bv01results = record0.getBv01();
Ext.log({msg:"bv01results", dump: bv01results});
var bv01store = someFunctionToGetThatBv01Store();
bv01store.loadRawData(bv01results);
}
}
Now the console reads Uncaught TypeError: Cannot read property 'hasId' of undefined. From the searches I've made, this seems to appear when there is an attempt to read the data from the network.
I'm getting a bit further but I still have the feeling to being stuck...

I want to read data from store for Extjs 4 but it shows [object object]

This is my model:
data: i
0: i
data: Object
events: Object
hasListeners: k
id: "region-ext-record-344"
index: 0
internalId: "ext-record-344"
modified: Object
phantom: false
raw: Array[2] // i want to get those two elements one displayField, another valueField
0: "01"
1: "Region 1"
length: 2
__proto__: Array[0]
store: i
stores: Array[1]
__proto__: Object
1: i
2: i
3: i
length: 4
__proto__: Array[0]
I can post the code if you want to!
I tried to read store like:
store: regionStore, but it is showing me an empty box with 4 empty lines equal to item count in my store, then I tried to do like store: regionStore.data.items and now it shows me [object object] lines, I totally get it why, but can't find solution for that. I am new to all ExtJs stuff, I am using ExtJs 4 though.
My model looks like that :
Ext.regModel('region', {
fields: [
{name: 'id', type: 'integer'},
{name: 'name', type: 'String'}
});
and my store looks like that:
var regionStore = new Ext.data.ArrayStore({
id: 'regionStore',
model: 'region',
data: MyDesktop.GridWindow.getRegionData() //that is data from ajax response
});
My combobox:
{
xtype: 'combobox',
value: "region",
store: regionStore,
width: 135,
id: 'regionCombo'
editable: false
}
You have tagged your question extjs 4.2, but your code is old style and not following recommendations. I really recommend you to read the manual, especially the introduction to MVC.
Ext.regModel is deprecated as of version 4.0.0. Change your code as follows and save it to the file app/model/Region.js :
Ext.define('MyApp.model.Region', {
extends: 'Ext.data.Model',
fields: [
{name: 'id', type: 'integer'},
{name: 'name', type: 'string'}
]
});
In file app/store/Regions.js :
Ext.define('MyApp.store.Regions', {
extends: 'Ext.data.ArrayStore',
//id: notice that id is no longer necessary
model: 'Region',
//data: you load the store from the server, so the data is loaded automatically
autoLoad: true
})
Your combobox becomes:
xtype: 'combobox',
value: 'region',
store: 'Regions',
width: 135,
id: 'regionCombo',
editable: false,
valueField: 'id',
displayField: 'name'
I never used extjs before 4.2, but it seems the changes introduced with version 4 are important. It may be difficult to adopt the new paradigms. But I'm sure it radically simplifies your code. You certainly never will regret this step.
Also with the release of version 5.0, I think it's time to develop new habits and leave ExtJs 2.0 coding style behind.
You started off correctly, but you didn't specify which fields to use. Add the missing configuration :
store: regionStore,
valueField: 'id',
displayField: 'name'
For a combobox you can define a store inline as :
store: [[1, 'first option'], [2, 'second option']],
In this case you will not need to declare the value and the display field. They are implicit.

Browser crashes when binding a foreign source datafield in jqx.dataAdapter

I'm trying to build a grid using jQWidgets (jqxGrid) with a column which displays values from a foreign data source, using jqx.dataAdapter, but the browser crashes when I try to call the dataBind() method.
Here's my (browser crashing!) jsfiddle:
http://jsfiddle.net/qYyRs/6/
Partial code:
var Area_DataSource = {
datatype: 'array',
localdata: Area_Data,
async: false,
datafields: [{
name: 'Id'
}, {
name: 'Name'
},{
name: 'PlantId'
},{
name: 'PlantName',
value: 'PlantId',
values: {
value: 'Value', // the problematic field
name: 'Name',
source: Plant_DataAdapter.records
}
}]
};
var Area_DataAdapter = new $.jqx.dataAdapter(Area_DataSource);
Area_DataAdapter.dataBind(); // booom!
Base example from jQWidgets website:
http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxgrid/index.htm#demos/jqxgrid/gridkeyvaluescolumnwitharray.htm
This is a confirmed issue:
http://www.jqwidgets.com/community/topic/browser-crashes-foreign-datafield-in-jqx-dataadapter/
"We debugged the issue and confirm it. It will be resolved in jQWidgets
2.8.
Best Regards, Peter Stoev
jQWidgets Team http://www.jqwidgets.com"

Populate ExtJS combobox with JSON

I am using ExtJS (3) and just trying to populate a combobox/drop down using records from the database that are being queried using JSON.
Here is my JSON call:
var projectDropDown = new Ext.data.Store({
autoLoad: true,
url: 'dropdown.json',
storeId: 'projectDropDown',
idProperty: 'ProjectID',
fields: [ 'ProjectID', 'ProjectName' ]
});
And then my combobox code:
{
xtype: 'combo',
id: 'ProjectName',
fieldLabel: 'Project Name',
valueField: 'ProjectID',
displayField: 'ProjectName',
store: projectDropDown,
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Select a Project...',
selectOnFocus:true
}
The JSON is returning my data like this:
[
{
"ProjectID":"1",
"ProjectName":"Mike's Test Project"
},
{
"ProjectID":"2",
"ProjectName":"My Second Test Project"
},
{
"ProjectID":"3",
"ProjectName":"My Third Project"
},
{
"ProjectID":"6",
"ProjectName":"More testing from me"
}
]
I think I am close, I just don't see what I am missing to make the connection.
Thanks for any assistance.
The first step I would do would be to output the store (or size of the store or something) to the console to see if the data is getting loaded properly into the store.
My guess would be that you need to enclose your JSON that is returned into some root object. Try giving your store a JSONReader with a root element specified like so:
var projectDropDown = new Ext.data.Store({
autoLoad: true,
url: 'dropdown.json',
storeId: 'projectDropDown',
reader: new Ext.data.JsonReader(
{
root: 'projects'
}),
idProperty: 'ProjectID',
fields: [ 'ProjectID', 'ProjectName' ]
});
Then change the JSON returned to look like this instead
{
"projects" : [
{"ProjectID":"1","ProjectName":"Mike's Test Project"},
{"ProjectID":"2","ProjectName":"My Second Test Project"},
....
]
}

ExtJS grid filters: how can I load 'list' filter options from external json?

I have a ExtJS (4.0) grid and it works fine. Now I want it to advance it a bit by adding filters to it. I want users to be able to filter items by the status.
I have created the following store:
var status_store = Ext.create('Ext.data.Store', {
model: 'Statuses',
proxy: {
type: 'ajax',
url: '/json/statuses/',
reader: 'json'
}
});
and I can see it loads, /json/statuses/ will return the following json object:
[
{
"name": "OK",
"isActive": true
},
{
"name": "Outdated",
"isActive": true
},
{
"name": "New",
"isActive": true
}
]
Now I define the filters:
var filters = {
ftype: 'filters',
encode: encode,
local: local,
filters: [{
type: 'list',
dataIndex: 'name',
store: 'status_store',
labelField: 'name'
}]
};
and add the filter to my column definition:
{text: 'Status', width: 120, dataIndex: 'status', sortable: true, filterable: true, filter: {type: 'list'}},
What happens is I get the following error when the grid loads:
Uncaught TypeError: Object json has no method 'read' (ext-all-debug.js:25702)
and when I click on the column header for the menu:
Uncaught TypeError: Object status_store has no method 'on' (ListMenu.js:69)
How can I fix this or am I doing something conceptually wrong?
Here is the full quote of my code just in case: http://pastebin.com/SNn6gFJz
Thanks for Diagnosing the problem. The 4.1 fix is this modify ListMenu.js
in the else part of the constructor
replace
me.store.on('load', me.onLoad, me);
with
// add a listener to the store object
var storeObject = Ext.StoreMgr.lookup(me.store);
storeObject.on('load', me.onLoad, me);
me.store = storeObject;
filters: [{
type: 'list',
dataIndex: 'name',
store: 'status_store',
labelField: 'name' ,
options:[a,b]
}]
You also have to give the options in list filters.
I was having a similar problem. I followed the #jd comment on the other answer here but the options menu just said "loading...". I resolved it with a bit of a hack here.

Categories

Resources