Extjs 6 grid + JSON - javascript

I have this JSON:
{
"aaa": {
"list": {
"count":"1",
"data": [
{"id":"1","username":"user1","email":"user1#test.com"}
]
}
}
}
And this is my Store:
var store = Ext.create('Ext.data.Store', {
fields : [ 'id',
'username',
'email'],
autoLoad : true,
proxy: {
type: 'ajax',
api: {
read: 'server/users'
},
reader: {
type: 'json',
successProperty: 'success',
root: 'data',
messageProperty: 'message'
}
}
});
And this is my Grid:
xtype: 'grid',
title: 'Users',
id: 'users',
store: store,
columns: {
items: [
{text: 'ID', dataIndex: 'id', editor: 'textfield'},
{text: 'Name', dataIndex: 'name', editor: 'textfield' },
{text: 'Email', dataIndex: 'email', editor: 'textfield' },
]
},
But this code is not working. I don't show JSON data on my grid. I think the problem is that I don't reach JSON elements.
How can I reach this elements? (aaa.data.id, aaa.data.name, aaa.data.email is not working)

Since you don't want (or can't) change the structure of your JSON, change the reader of the proxy on your store to correspondent with the data structure of your JSON.
reader: {
type: 'json',
rootProperty: 'aaa.list.data',
totalProperty: 'aaa.list.count'
}

The root should be root: 'aaa.list.data'. The root is supposed to point to the array of records. data doesn't appear in the top level object returned at all. It would be like saying:
var o = {
aaa: {
data: [{}]
}
}
console.log(o.data); // Nothing

You can use the reader's transform method to format the data before the store processing takes place.

Related

Extjs combobox to display records with value fetched from data store rest/jsp request

With ExtJs (4.2) version, wanted to know how to filter the empty records from the combobox dropdown list.
The code uses Extjs store to fetch a data from jsp, the result is a json object. Say below is the results rendered,
{ "data" : [
{"source":"system1","key1" : "value system1", "key2" : " value for system1"},
{"source":"system2","key1" : "value 11", "key2" : " value for key1, value 12"},
{"source":"system3" }, //Blank or empty key1, key2 record.
....
}
Js code with ExtJs
I am using ExtJs to display a combobox (Dropdown) below is the code fragment
var dataStore = Ext.create('Ext.data.Store', {
autoLoad: true,
fields: ['key1', 'key2'],
proxy:
{
type: 'ajax',
url: '<url to a jsp file which retruns json data>',
reader:
{
type: 'json',
root: 'templates'
}
}
});
...
var screenPanel = {
xtype: 'fieldset',
title: 'Panel - Data',
margin: '0 10 15 15',
padding: 10,
flex: 1,
width:"100%",
layout: 'anchor',
defaults: {
labelWidth: 160,
},
items: [
{
xtype: 'checkbox',
name: 'visibility',
id: 'visibility',
fieldLabel : 'Check to enable',
value:false
},
{
xtype: 'combobox',
anchor: '80%',
name: 'combodropdown',
itemId: 'combo1',
fieldLabel: 'Dropdown selection',
displayField: 'key2',
valueField: 'key1',
store: dataStore,
},{
xtype: 'container',
anchor: '80%',
....
The combox dropdown is listing the empty record as well. Is there a way to filter that value. In the above case the "source" : "system3" doesn't have key1 and key2 value but the xtype:combo (name: combodropdown) is listing a blank item as well.
Is there any example, on using an event to filter the data that are empty. like onClick event to filter the data like below
....
{
xtype: 'combobox',
anchor: '80%',
name: 'combodropdown',
itemId: 'combo1',
fieldLabel: 'Dropdown selection',
displayField: 'key2',
valueField: 'key1',
store: dataStore,
//some thing like this
onClick: function(value1,value2){
alert('clicked combox dropdown')
//data store value empty return something
}
You can use store filter. Something like:
Ext.application({
name: 'Fiddle',
launch: function () {
var dataStore = Ext.create('Ext.data.Store', {
autoLoad: true,
fields: ['key1', 'key2'],
proxy: {
type: 'ajax',
url: 'comboData.json',
reader: {
type: 'json',
root: 'data'
}
},
filters: [
function (item) {
return !Ext.isEmpty(item.get('key1')) && !Ext.isEmpty(item.get('key2'));
}
]
});
Ext.create('Ext.form.Panel', {
title: "Sample Panel",
items: [{
xtype: 'combobox',
name: 'combodropdown',
itemId: 'combo1',
fieldLabel: 'Dropdown selection',
displayField: 'key2',
valueField: 'key1',
store: dataStore,
listeners: {
expand: function(comboBox) {
console.log(comboBox.getStore().getRange());
}
}
}],
renderTo: Ext.getBody()
})
}
});

Extjs issue with PagingToolbar - same data on the next page

There are so many issues I found about different problems with grid paging but still can't find the answer to mine.
I want to load some data from googleapis to extjs grid with ability of paging.
Let say we can query Google JSON API using the following link.
https://www.googleapis.com/books/v1/volumes?fields=totalItems,items(id,volumeInfo/title,volumeInfo/subtitle,volumeInfo/authors,volumeInfo/publishedDate,volumeInfo/description,volumeInfo/imageLinks)&q=Neuromarketing&maxResults=40&startIndex=0
As you can see, I can query as much records per time as 'maxResults' and from the 'startIndex' position.
The short example of json is
{
"totalItems": 298,
"items": [
{
..
First, I've defined a Model and a Store:
Ext.define('MyApp.view.main.Book', {
extend: 'Ext.data.Model',
fields: [
{name: 'id'},
{name: 'publishedDate', mapping: 'volumeInfo.publishedDate'},
{name: 'title', mapping: 'volumeInfo.title'}
]
});
Ext.define('MyApp.view.main.Books', {
extend: 'Ext.data.Store',
model: 'MyApp.view.main.Book',
buffered: true,
pageSize: 15,
alias: 'store.books',
autoLoad: true,
proxy: {
type: 'jsonp',
url: 'https://www.googleapis.com/books/v1/volumes?fields=totalItems,items(id,volumeInfo/title,volumeInfo/subtitle,volumeInfo/authors,volumeInfo/publishedDate,volumeInfo/description,volumeInfo/imageLinks)',
extraParams: {
q : 'Javascript',
maxResults : 15,
startIndex : 0
},
reader: {
type: 'json',
rootProperty: 'items',
totalProperty: 'totalItems'
}
}
});
Second, I've defined a View
Ext.define('MyApp.view.main.Main', {
extend: 'Ext.container.Container',
requires: [
'MyApp.view.main.MainModel'
],
xtype: 'app-main',
controller: 'main',
viewModel: {
type: 'main'
},
layout: {
type: 'border'
},
items: [
{
region: 'center',
xtype: 'tabpanel',
reference: 'tabPanel',
items:[
{
title: 'Result',
reference: 'tabPanelResultTab',
layout: 'fit',
items: [{
xtype: 'grid',
reference: 'grid',
title: 'Books',
dockedItems: [{
xtype: 'pagingtoolbar',
bind: {
store: '{summary}'
},
dock: 'bottom',
displayInfo: true
}],
bind: {
store: '{summary}'
},
columns: [
{ text: 'Google ID', dataIndex: 'id', flex: 1 },
{ text: 'Title', dataIndex: 'title', flex: 4 },
{ text: 'Published Date', dataIndex: 'publishedDate', flex: 1}
]
}]
}]
}]
});
Third, I've defined ViewModel
Ext.define('MyApp.view.main.MainModel', {
extend: 'Ext.app.ViewModel',
requires: [
'MyApp.view.main.Books'
],
alias: 'viewmodel.main',
data: {
name: 'MyApp'
},
stores: {
summary: {
type: 'books'
}
}
});
So now, when I click next page on pagingtoolbar, the loading image pops up, then loads exact the same data on the 2nd page I saw on the 1st page. I still don't understand, how to tell PagingToolbar to query from next 'startIndex'. Is it possible to change 'start' and 'limit' variables to my 'startIndex' and maxResults'?
Yes, you can configure it at the proxy level. See startParam and limitParam.

EXTjs grid model json noob

What am I doing wrong? Of all the fields displayed in the grid only Working Group. EXTjs 4.2.1.
Tried different variants that have been found here, but, alas, nothing has helped understand what is wrong here.
Ext.define('myModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'WorckGroup', type: 'string' },
{ name: 'Statistics', type: 'auto' },
{ name: 'Specialist', type: 'string', mapping: 'Statistics.Specialist' },
{ name: 'ScallCount', type: 'int', mapping: 'Statistics.SCallCount' },
{ name: 'AverageDuration', type: 'auto', mapping: 'Statistics.AverageDuration' }
]
});
var store = Ext.create('Ext.data.Store', {
model: 'myModel',
proxy: {
type: 'ajax',
url: '/omnireports/ajaxgrid',
reader: {
type: 'json',
}
},
autoLoad: true
});
var basegrid = Ext.create('Ext.grid.Panel', {
store: store,
columns: [
{ header: 'WG', width: 200, dataIndex: 'WorckGroup' },
{ header: 'SP', dataIndex: 'Specialist' },
{ header: 'SCC', dataIndex: 'SCallCount' },
{ header: 'AD', dataindex: 'AverageDuration' }
], });
json
[
{"WorckGroup":"3D",
"Statistics":[
{"Specialist":"В А","SCallCount":64,"AverageDuration":0.1136067},
{"Specialist":"К Т","SCallCount":170,"AverageDuration":0.1045816}]
{"WorckGroup":"SD",
"Statistics":[
{"Specialist":"B A","SCallCount":197,"AverageDuration":0.1364689}]
}
]
Your mappings don't make sense. Statistics is an array, so Statistics.Specialist doesn't map to anything.
Your root for the reader should probably be WorckGroup.Statistics and you should include the WorckGroup in each item.
reader: {
type: 'json',
root: 'WorckGroup.Statistics'
}
Then remove the mapping from each field in the model.

ExtJS store, cannot load data to grid

Console is clear. Grid is empty (only column titles are shown). How can I check if data is correctly loaded to the store? It seems to me that the store's autoLoad method is not triggered somehow. Here is the grid:
Ext.define('NameSpace.view.Clients', {
requires: [
'Ext.tree.Panel',
'Ext.grid.Panel'
],
extend: 'Ext.tab.Panel',
title: 'Clients',
alias: 'widget.viewClients',
items: [
{
xtype: 'panel',
title: 'All Clients',
layout: {
type: 'hbox',
align: 'stretch'
},
items: [
{
xtype: 'treepanel',
title: 'Tree Panel',
width: 200,
resizable: true
},
{
xtype: 'gridpanel',
title: 'Clients List',
store: Ext.getStore('storeClients'),
flex: '1',
columns: [
{ text: 'Name', dataIndex: 'first_name' },
{ text: 'Last Name', dataIndex: 'last_name' },
{ text: 'Phone Number', dataIndex: 'phone' }
]
}
]
}
],
initComponent: function () {
this.callParent(arguments);
}
});
And here is the store (Model contains nothing but extend and fields configs):
Ext.define('NameSpace.store.Clients', {
extend: 'Ext.data.JsonStore',
proxy: {
type: 'ajax',
url: 'http://test.local/client',
reader: {
type: 'json',
root: 'records'
}
},
autoLoad: true,
constructor: function (config) {
this.initConfig(config);
}
});
Ext.create('NameSpace.store.Clients', {
model: 'Clients',
storeId: 'storeClients'
});
Move
model: 'Clients',
storeId: 'storeClients'
into store definition, and get rid of store creation call. Store will be created automatically.
Why do you override the store constructor?
If you actually need to do it, you should add this.callParent(arguments) to the constructor, otherwise the original constructor (which does a lot) won't run.
You just need to change
store: Ext.getStore('storeClients')
To This :
store: 'Clients'
I think you need to write field when you create store.
i.e.
fields:[ 'first_name', 'last_name', 'phone']

ExtJs 4 Grid Paging

I'm trying to make data grid with paging using ExtJs framework, but unfortunately my code doesn't work. Maybe some of you has already settled this such problem.
Json-reply from server is:
{
"totalCount":"2",
"companies":[
{
"id":"1",
"name":"Name1",
"region":"Reg1",
"address":"Addr1",
"dealCount":"3",
"dealAmount":"19250",
"latestDealDate":"2012-01-09"
},
{
"id":"2",
"name":"Name2",
"region":"Reg2",
"address":"Addr2",
"dealCount":"2",
"dealAmount":"12150",
"latestDealDate":"2012-01-08"
}
]
}
JavaScript code, which creates store, grid, e.t.c. is:
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.util.*',
'Ext.toolbar.Paging',
'Ext.ModelManager',
'Ext.layout.*'
]);
Ext.onReady(function(){
// Define data model
Ext.define('Company', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
type: 'int'
},
'name', 'region', 'address',
{
name: 'dealCount',
type: 'int'
},
{
name: 'dealAmount',
type: 'int'
},
{
name: 'latestDealDate',
type: 'string'
}
],
idProperty: 'id'
});
// Create data store
var companies = Ext.create('Ext.data.Store', {
pageSize: 50,
model: 'Company',
proxy: Ext.create('Ext.data.proxy.Ajax', {
url: 'service/companies-data.php'
}),
reader: Ext.create('Ext.data.reader.Json', {
root: 'companies',
totalProperty: 'totalCount'
}),
sorters: [{
property: 'name',
direction: 'ASC'
}]
});
// Create data grid
var grid = Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
width: 700,
height: 500,
store: companies,
columns: [
{
text: 'Name',
dataIndex: 'name'
},
{
text: 'Region',
dataIndex: 'region'
},
{
text: 'Address',
dataIndex: 'address'
},
{
text: 'Deal Count',
dataIndex: 'dealCount'
},
{
text: 'Deal Amount',
dataIndex: 'dealAmount'
},
{
text: 'Latest Deal Date',
dataIndex: 'latestDealDate'
}
],
bbar: Ext.create('Ext.PagingToolbar', {
store: companies,
displayInfo: true,
displayMsg: 'Displaying topics {0} - {1} of {2}',
emptyMsg: "No topics to display"
})
});
// Load first data page
companies.loadPage(1);
});
Firebug shows, that server responds with json-data, but grid remains empty. How can I fix it?
You should define reader inside proxy (at least that helped for me). Eg:
proxy: Ext.create('Ext.data.proxy.Ajax', {
url: 'service/companies-data.php',
reader: Ext.create('Ext.data.reader.Json', {
root: 'companies',
totalProperty: 'totalCount'
})
})
Working sample: http://jsfiddle.net/ycDzL/3/

Categories