As you will notice JSON returns different values within same field name and thusly I've binded to required value with dot notation. But I'm using same panel on different classes, so I need to figure out a better way to bind specified value. I've tried to use mapping on BookStatModel but couldn't be success.
How can I achieve for a shorten/roboust usage of data binding to JSON which have different values on same field name.
I can't alter server response;
{
"success": true,
"msg": "OK",
"count": 5,
"data": [
{
"bid": 1000655,
"code": "TOTALPENDING",
"totalcount": 1
},
{
"bid": 1000655,
"code": "TOTALLEFT",
"totalcount": 2
},
I'm getting JSON through VM stores;
// VM
stores: {
bookStore: {
model: 'MyApp.model.base.BookStatModel',
autoLoad: true,
session: true,
proxy: {
url: MyApp.Globals.getUrl() + '/bonustrans/stat/book',
type: 'ajax',
reader: {
type: 'json',
rootProperty: 'data'
}
}
},
// Model itself
Ext.define('MyApp.model.base.BookStatModel', {
extend: 'MyApp.model.base.StatResultModel',
requires: [
'MyApp.Globals',
'MyApp.FldNames'
],
fields: [
{name: 'bid', type: MyApp.FldTypes.INT},
{name: 'code'}
//{name: 'currentBonus', mapping: 'bookStore.data.items.1.totalcount', type: 'integer'},
//{name: 'pendingBonus', mapping: 'bookStore.data.items.0.totalcount', type: 'integer'},
//{name: 'totalBonus', mapping: 'bookStore.data.items.2.totalcount', type: 'integer'}
]
});
and finally bind those data to panel with bind config;
{
xtype: 'infocard',
flex: 1,
margin: '0 5 0 0',
bodyStyle: {
"background-color": "#DFE684"
},
items: [{
xtype: 'container',
layout: {
type: 'hbox'
},
items: [{
xtype: 'container',
layout: {
type: 'vbox',
align: 'middle',
pack: 'end'
},
flex: 2,
items: [{
xtype: 'container',
userCls: 'infocardCount',
bind: {
//In another 'infocard' binds to 'items.0.totalcount'
html: '{bookStore.data.items.1.totalcount}'
//html: '{currentBonus}' //Couldn't render value
},
flex: 1
}, {
xtype: 'component',
height: 10
}, {
xtype: 'container',
userCls: 'infocardCode',
padding: '10',
bind: {
//In another 'infocard' binds to 'items.0.code'
html: '{bookStore.data.items.1.code}'
},
flex: 1
}]
},
Formulas is the answer For your design this should work :
https://fiddle.sencha.com/#view/editor&fiddle/2edq
But my suggestion is to use a bonuses grid where bonustype is a column (currentBonus,pendingBonus,totalBonus)
Related
I wish to GET JSON from Django API to model for my ext js Grid.
There is JSON pseudo code :
"type": "FeatureCollection",
"features": [
{
"id": 31,
"type": "Feature",
"geometry": {
"coordinates": [
[
[
[],
[],
[],
[],
[]
]
]
],
"type": "MultiPolygon"
},
"properties": {
"subject": null,
"num_of_agree": 16,
"uroch": "",
"num_allot": null,
"num_fca": "prob-01",
"ar_fca": "34.80",
"expl_ar": 32.2,
"cel_nazn": 3,
"cat_zas": 3,
"video_cat": "D:/work/"
}
},
You can see that there is nested JSON. I need to GET fields from "properties".
So after some google searching, I tried 2 ways.
First it is using of mapping congig.
model:
extend:'Ext.data.Model',
config:'features' ,
fields: [{
name: 'subject',
mapping:features.properties.subject
},{
name:'num_of_agree',
mapping:properties.num_of_agree
},{
name:'uroch',
mapping: properties.uroch
},{...}```
there is grid code:
Ext.define('Foresto.view.cutworkpanel.CutareaGrid', {
extend:'Ext.grid.Grid',
xtype: 'cut-area-grid',
id: 'cut-area-grid',
requires: [
'Ext.grid.plugin.Editable',
on',
'Ext.grid.plugin.RowExpander',
'Foresto.view.cutworkpanel.CutareaModel',
],
title: 'List',
width: '100%',
height: '90%',
hideHeaders: false,
autoScroll: true,
tools: [{
type:'help'
}],
store: {
model:'Foresto.view.cutworkpanel.CutareaModel',
autoLoad: true,
pageSize:0,
proxy: {
type:'ajax',
url:'/api/cutarea-fca/',
reader:{
type:'json',
rootProperty: 'results'
var requestURL = '/api/cutarea-fca/'
}
}
},
plugins: [{
type: 'grideditable',
triggerEvent: 'doubletap',
enableDeleteButton: true,
formConfig: null, // See more below
renderTo: 'map-panel',
defaultFormConfig: {
xtype: 'formpanel',
title:'EDIT',
scrollable: true,
items: {
xtype: 'fieldset'
}
},
columns: [{
text: 'subject',
flex: 1,
minWidth: 200,
dataIndex: 'subject',
editable:true
},{
text:'agreement',
dataIndex:'num_of_agree',
minWidth: 200,
editable:true
},{
text:'сфоткай',
dataIndex:'num_fca',
minWidth: 220,
editable:true
}
and another variant of mod:
``` Ext.define('Foresto.view.cutworkpanel.CutareaModel',{
extend:'Ext.data.Model',
config:'features' ,
fields: [{
name: 'subject',
mapping:function(properties){
return properties.subject;
}
},{
name:'num_of_agree',
mapping:function(properties){
return properties.num_of_agree;
}
},{
name:'uroch',
mapping:function(properties){
return properties.uroch;
}
Both approaches aren't working for me. Please tell me how to fix and what to use.
UPD I use an answer information. I used this method (define record config in store) like that: rootProperty: 'results', record: 'features' //in Store. And config: 'propetries' //in the CutareaModel.js
And it give me only 1 row in grid with: [object Object] [object Object] [object Object] etc. for all of my nubers of fields
You can use the proper rootProperty and record config in the store reader as below
store: {
model:'Foresto.view.cutworkpanel.CutareaModel',
autoLoad: true,
pageSize:0,
proxy: {
type:'ajax',
url:'/api/cutarea-fca/',
reader:{
type:'json',
rootProperty: 'features',
record: 'properties'
}
}
}
rootProperty:'results.features[0].properties', cause features in my JSON is arrive.
so:
store: {
model:'Foresto.view.cutworkpanel.CutareaModel',
proxy: {
type:'ajax',
url:'/api/',
reader:{
type:'json',
rootProperty:'results.features[0].properties',
}
}
}
I'm getting this JSON below and need to format code field' string value to some other text. For example 'TOTALPENDING' will render as "Pending Bonus" and 'TOTALLEFT' to "Current Bonus". How can i achieve to this?
{
"success": true,
"msg": "OK",
"count": 5,
"data": [
{
"bookerid": 103083420,
"code": "TOTALPENDING",
"totalcount": 1
},
{
"bookerid": 103083420,
"code": "TOTALLEFT",
"totalcount": 2
},
Data fetchs through ViewModel stores;
stores: {
bookStore: {
model: 'MyApp.model.base.BookStatModel',
autoLoad: true,
session: true,
proxy: {
url: MyApp.Globals.getUrl() + '/bonustrans/stat/book',
type: 'ajax',
reader: {
type: 'json',
rootProperty: 'data'
}
}
},
For this you need to use convert config inside of model.
In this FIDDLE, I have created a demo using grid, store and model. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('Book', {
extend: 'Ext.data.Model',
fields: ['bookerid', {
name: 'code',
convert: function (v, rec) {
switch (v) {
case 'TOTALPENDING':
v = 'Pending Bonus';
break;
case 'TOTALLEFT':
v = 'Current Bonus';
break;
default:
v = '';
break;
}
return v;
}
}, 'totalcount'],
});
Ext.define('TestViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.test',
stores: {
books: {
model: 'Book',
proxy: {
type: 'ajax',
url: 'book.json',
reader: {
type: 'json',
rootProperty: 'data',
keepRawData: true
}
},
autoLoad: true
}
}
});
Ext.create({
xtype: 'container',
layout: 'vbox',
fullscreen: true,
renderTo: Ext.getBody(),
viewModel: {
type: 'test'
},
items: [{
xtype: 'container',
userCls: 'infocardCount',
margin: 10,
bind: {
html: '<small>If value is 0 then we can use pipes and in that case you need to pass 0 inside of string like this <b> books.data.items.0.totalcount || "0"</b> </small><br><br> <b style="color: #3c3c3c;background: #ccc;padding: 10px;margin: 10px;">{books.data.items.0.totalcount || "0"}</b>'
}
}, {
xtype: 'grid',
flex: 1,
width: '100%',
title: 'Book Data',
bind: {
store: '{books}'
},
columns: [{
text: 'BOOK ID',
flex: 1,
dataIndex: 'bookerid'
}, {
text: 'CODE',
dataIndex: 'code',
flex: 1
}, {
text: 'TOTAL',
flex: 1,
dataIndex: 'totalcount'
}]
}]
});
}
});
JSON FILE
{
"success": true,
"msg": "OK",
"count": 5,
"data": [{
"bookerid": 103083420,
"code": "TOTALPENDING",
"totalcount": 0
}, {
"bookerid": 103083421,
"code": "TOTALLEFT",
"totalcount": 15
}, {
"bookerid": 103083422,
"code": "TOTALPENDING",
"totalcount": 12
}, {
"bookerid": 103083423,
"code": "TOTALLEFT",
"totalcount": 10
}, {
"bookerid": 103083424,
"code": "TOTALLEFT",
"totalcount": 16
}]
}
I have this json data:
{
id: 1,
name: 'something',
description: 'somethingsomething',
customers: [{
id: 1,
username: 'cust1'
}, {
id: 2,
username: 'cust2'
}]
}
While I have no problems displaying the first three fields on the gridpanel, I however have an issue retrieving the array object for the customers field. My model goes like this:
fields: [
'id', {
name: 'name',
sortType: Ext.data.SortTypes.asUCString
},
'permanent', {
name: 'description',
Type: Ext.data.SortTypes.asUCString
}, {
name: 'customers',
Type: Ext.data.SortTypes.asUCString
}, {
name: 'username',
Type: Ext.data.SortTypes.asUCString,
mapping: 'customers[0].username'
}
]
When I try to access customers[0].username, it only retrieves the ones on that specified index. Removing the index number returns undefined as I assume it is looking for what index to return from. How do I properly retrieve all of customers: [] and display it to my grid where it is structured as:
{
xtype: 'gridpanel',
store: oStore,
viewConfig: {
loadMask: false,
enableTextSelection: true
},
hideHeaders: false,
bodyBorder: true,
columns: [{
text: 'Customer',
dataIndex: 'username',
flex: 1
}, {
header: '',
xtype: 'actioncolumn',
itemId: 'remove-player-btn',
width: 50,
sortable: false,
resizable: false,
menuDisabled: true,
items: [{
icon: 'resources/img/x.png',
tooltip: 'Remove Player',
scope: oMe
}],
editor: {
xtype: 'text',
name: 'deleteRow'
}
}]
}
You can use convert function available in model.This convert function is used for some calculation purpose & map response data for our needs.For example I will map username as below:
fields: [
{
name:'username',
convert:function(value,model)
{
return model.data.customers.username;
}
}
]
Use same technique for id field.Reply if any issues.
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.
I want to get an infinite scrolling grid with extjs4 and a c# backend... i am setting the proxy api in my controller..
My Model:
Ext.define('SCT.model.training.course.TrainingRequirementList', {
extend: 'Ext.data.Model',
idProperty: 'ID',
fields: [
{ name: 'ID', type: 'int', convert: null },
{ name: 'EmployeeName', type: 'string' },
{ name: 'Description', type: 'string' },
{ name: 'StatusText', type: 'string' },
{ name: 'Status', type: 'int' },
{ name: 'Priority', type: 'string' },
{ name: 'Date', type: 'string' },
{ name: 'Cost', type: 'string' },
{ name: 'CanApprove', type: 'bool' },
{ name: 'CanRequest', type: 'bool' },
{ name: 'ConfirmStatus', type: 'string' },
{ name: 'PlanId', type: 'int'}
]
});
My Grid:
{
xtype: 'gridpanel',
flex: 1,
padding: '0 10 10 10',
minHeight: 200,
verticalScroller: {
xtype: 'paginggridscroller'
},
store: {
model: 'SCT.model.training.course.TrainingRequirementList',
pageSize: 200,
autoLoad: true,
remoteSort: true,
sorters: {
property: 'Date',
direction: 'DESC'
},
proxy: {
type: 'direct',
extraParams: {
total: 50000
},
reader: {
type: 'json',
root: 'ID',
totalProperty: 'totalCount'
},
simpleSortMode: true
}
},
columns:
[{
text: Lang.Main.Employeee,
dataIndex: 'EmployeeName',
flex: 1,
filterable: true
},
{
text: Lang.Main.Course,
dataIndex: 'Description',
flex: 1,
filterable: true
},
{
text: Lang.Main.Status,
dataIndex: 'StatusText',
flex: 1,
filterable: true
},
{
text: Lang.Main.Priority,
dataIndex: 'Priority',
flex: 1
},
{
text: Lang.Main.Date,
dataIndex: 'Date',
flex: 1
},
{
text: Lang.Main.Cost,
dataIndex: 'Cost',
flex: 1,
filterable: true
},
{
text: Lang.Main.Actions,
flex: 1,
align: 'center',
xtype: 'actioncolumn',
width: 50,
items: [{
icon: 'Design/icons/cog_edit.png',
tooltip: Lang.Main.Open,
handler: function (grid, rowIndex, colIndex, item) {
this.onGridOpen(grid.getStore().getAt(rowIndex));
}
}]
}],
selModel: { mode: 'MULTI', selType: 'checkboxmodel' },
}
setting proxy in controoler:
view.grid.getStore().setProxy({
type: 'direct',
model: 'SCT.model.training.course.TrainingRequirementList',
api: { read: SCT.Service.Training.Plan.GetFilteredRequirements },
extraParams: { total: 50000 },
reader: {
type: 'json',
root: 'ID',
totalProperty: 'totalCount'
},
simpleSortMode: true
});
additional information about my view:
Ext.define('SCT.view.training.course.TrainingRequirements',
{
extend: 'Ext.panel.Panel',
require: [ 'Ext.grid.PagingScroller', 'Ext.ux.grid.FiltersFeature'],
My grid is still loading all data at once (about 8000 rows...) ...
i've searched for solutions and worked through tutorials.. i still dont get it.
please help me out... i dont get it at all...
UPDATE
this is my srv request:
and the response got 3MB (about 8k datasets... ) ..??
Your request dump shows that Ext effectively sends the limit param, so that's your server that is not handling it...
Just a piece of advice, but you should consider upgrading to last version of Ext, since buffered grid seems to have been simplified, and that will avoid you having to rework it if you eventually upgrade.