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('appname.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: 'appname.model.training.course.TrainingRequirementList',
pageSize: 200,
autoLoad: true,
buffered: 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: 'appname.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('appname.view.training.course.TrainingRequirements',
{
extend: 'Ext.panel.Panel',
require: [ 'Ext.grid.PagingScroller'],
My grid is only loading the first 200 rows and the scrollbar is only as big as it would be for 200 rows.. :/ ...
the server response with entries like this:
{"ID":99,"PlanId":23,"firstname":"name","lastname":"name","Comment":"","Status":3,"ConfirmType":0,"Priority":"entry","DesiredDate":null,"StartDate":new Date(1354107600000),"ActualCost":180,"EstimatedCost":0,"row":201,"TotalCount":8568,"EmployeeName":"some, name","Description":"","StatusText":"state","Date":"28.11.2012","Cost":"EUR 180"}
what am i missing???
UPDATE
When i scroll down the script is loading the second page also.. still nothing more...
if you ned more information dont hesitate to ask
Does your server include the correct TotalCount value in the response?
Edit:
According to your reader's configuration, your server should answer with data formatted this way (of course your response should also be valid JSON, here Javascript is used for illustration):
{
// total property at the root level of response object
TotalCount: 8568,
// root for items data, configured as "ID" in your reader (you should probably
// change that to something like "records" or "data" to better express meaning)
ID: [
// individual fields data
{ID: 1, EmployeeName: 'Foo', ...},
{ID: 2, EmployeeName: 'Bar', ...},
...
]
// if you had, for example, a successProperty, it would go here too
,success: true
}
In your case, it seems that your TotalCount is mixed in every item data?
You're right about the implementation on the server side: it should simply be the total number of records, so something like COUNT(*) in the database.
One more thing: new Date(1354107600000) is not valid JSON. You should use a string and cast it to a date once the JSON has been decoded. For example, in your model, your could configure the field type to have Ext handle this for your: {name: 'Date', type: 'date', format: 'd.m.Y'}.
Related
I have a grid with a pagination. When I set a filter, the ajax request is successfully executed, the json return value looks fine and the filtered rows appear in my grid.
But the Loading... popup won't disappear and Firebug reports an error in ext-all-debug.js: TypeError: data is null (Line 134684). The code at that point is:
data = store.getData();
items = data.items; // error
I've checked my JS several times, but I can't find the problem.
Unfortunately I can't create a fiddle, since I use remote filtering. So here's the script:
Ext.onReady (function () {
Ext.define('FooModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'myId', type: 'int' },
{ name: 'myDate', type: 'date', dateFormat: 'Y-m-d H:i:s' },
{ name: 'myString', type: 'string' },
{ name: 'myFilename', type: 'string' },
{ name: 'myUser', type: 'string' }
]
});
Ext.define('FooStore', {
extend: 'Ext.data.Store',
model: 'FooModel',
autoLoad: true,
autoDestroy: true,
proxy: {
type: 'ajax',
url: 'test.php',
reader: {
type: 'json',
rootProperty: 'import_files',
messageProperty: 'error',
}
},
remoteFilter: true,
remoteSort: true,
sorters: [{
property: 'myId',
direction: 'ASC'
}],
pageSize: 5
});
var theFooStore = new FooStore();
theFooStore.load({
callback: function(records, operation, success) {
if(!success) {
Ext.Msg.alert('Error', operation.getError());
}
}
});
Ext.define('FooGrid', {
extend: 'Ext.grid.Panel',
xtype: 'grid-filtering',
requires: [ 'Ext.grid.filters.Filters' ],
width: 1000,
height: 700,
renderTo: 'content',
plugins: 'gridfilters',
emptyText: 'No Matching Records',
loadMask: true,
stateful: true,
store: theFooStore,
defaultListenerScope: true,
columns: [
{ dataIndex: 'myId', text: 'My Id', filter: 'number' },
{ xtype: 'datecolumn', dataIndex: 'myDate', text: 'My Date', renderer: Ext.util.Format.dateRenderer('d.m.Y'), filter: true },
{ dataIndex: 'myString', text: 'My String', filter: 'list' },
{ dataIndex: 'myFilename', text: 'My Filename',
renderer: function(value, meta, record) {
return Ext.String.format('{1}', record.data.myId, value);
},
filter: {
type: 'string',
itemDefaults: { emptyText: 'Search for...' }
}
},
{
dataIndex: 'myUser', text: 'My User',
filter: {
type: 'string',
itemDefaults: { emptyText: 'Search for...' }
}
},
],
dockedItems: [{
xtype: 'pagingtoolbar',
store: theFooStore,
dock: 'bottom',
displayInfo: true
}]
});
new FooGrid();
});
And here's a sample json return value:
{
"success" : true,
"total" : 19,
"import_files" : [{
"myId" : "1",
"myFilename" : "foo bar.xlsx",
"myDate" : "2015-05-19 13:23:21",
"myUser" : "ABC",
"myString" : "Lorem ipsum"
},
...
]
}
Has someone experienced the same issue? What could it cause?
Just my luck. Found the answer shortly after posting the question.
Deleting the filter: 'list' option at my My String column is the solution.
Model
Ext.define('XXX.User', {
extend: 'Ext.data.Model',
fields: [
'name',
'email',
'nick',
'mobile',
{ name: 'create_time', type: 'date', dateFormat: 'Y-m-d H:i:s' }
]
});
Ajax Response
{
"error": "",
"errno": 0,
"success": true,
"message": "Operation performed successfully",
"data": [{
"nick": "muquaddim1",
"name": "Muquaddim One",
"id": "141",
"mobile": "01710000***",
"email": "muquaddim+1#example.com",
"create_time": "2012-02-26 14:58:29"
}]
}
Store
var user_store = Ext.create('Ext.data.Store', {
// destroy the store if the grid is destroyed
autoDestroy: true,
autoLoad: true,
model: 'XXX.User',
sotreId: 'user-store',
proxy: {
type: 'ajax',
url : 'proxy/user'
},
sorters: [{
property: 'create_time',
direction: 'ASC'
}]
});
Grid
var user_grid = Ext.create('Ext.grid.Panel', {
title: 'List of Users',
store: user_store,
columns: [{
header: 'Nick',
dataIndex: 'nick',
editor: {
allowBlank: false
}
}, {
header: 'Name',
dataIndex: 'name',
flex: 1,
editor: {
allowBlank: false
}
}, {
header: 'Email',
dataIndex: 'email',
width: 160,
editor: {
allowBlank: false,
vtype: 'email'
}
}, {
header: 'Mobile',
dataIndex: 'mobile',
width: 100,
editor: {
allowBlank: false
}
}, {
xtype: 'datecolumn',
header: 'Join Date',
dataIndex: 'create_time',
width: 90,
editor: {
xtype: 'datefield',
allowBlank: false,
format: 'Y-m-d H:i:s',
maxValue: Ext.Date.format(new Date(), 'Y-m-d H:i:s')
}
}]
});
Panel
var users = Ext.create('Ext.panel.Panel', {
title: 'Users',
id: 'user_panel',
items:[user_grid]
});
I am using ExtJS 4.0.7. I modified the code found in Example. Example code works fine. But it does not work. What am I missing here?
Since your data is nested in your response you need to configure a reader in your store's proxy. Try setting up your proxy like this:
proxy: {
type: 'ajax',
url : 'proxy/user'
reader: {
type: 'json',
root: 'data'
}
}
I'm trying to create a grid (Ext.grid.Panel) and fill it with data. But something is going wrong so the grid shows empty rows without data.
Model is:
Ext.define('Order', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
type: 'int'
},
{
id: 'companyId',
type: 'int'
},
{
id: 'amount',
type: 'int'
},
{
id: 'dealDate',
type: 'date'
},
{
id: 'complete',
type: 'int' //boolean imitation
}
],
idProperty: 'id'
});
Grid & Store code is:
var orders = Ext.create('Ext.data.Store', {
model: 'Order',
proxy: Ext.create('Ext.data.proxy.Ajax', {
url: 'service/orders-data.php?',
reader: Ext.create('Ext.data.reader.Json', {
root: 'orders'
})
}),
sorters: [{
property: 'name',
direction: 'ASC'
}]
});
orders.load();
var ordersGrid = Ext.create('Ext.grid.Panel', {
width: 400,
height: 300,
store: orders,
columns: [
{
text: 'Amount',
dataIndex: 'amount',
width: 120
},
{
text: 'Deal date',
dataIndex: 'dealDate',
width: 120
},
{
text: 'Complete',
dataIndex: 'complete',
width: 120
}
]
});
JSON-response from server is:
{
"orders":[
{
"id":1,
"amount":5000,
"dealDate":"2012-01-05",
"complete":0
},
{
"id":2,
"amount":6850,
"dealDate":"2012-01-07",
"complete":0
},
{
"id":5,
"amount":7400,
"dealDate":"2012-01-09",
"complete":0
}
]
}
Why does the grid display empty rows?
All your model's fields but the first are being declared with 'id' properties where they should instead be using 'name':
{
name: 'id',
type: 'int'
},
{
name: 'companyId',
type: 'int'
},
{
name: 'amount',
type: 'int'
},
{
name: 'dealDate',
type: 'date'
},
{
name: 'complete',
type: 'int' //boolean imitation
}
I was creating Tree Panel similar to TreeGrid example with drag'n'drop. The only problem is that items are correctly shown in tree panel in Firefox browser whereas in Chromium tree grid is empty. How's that possible?
JSON data sent to server:
{"text":".","children": [
{
"id":null,
"name":"en",
"visible":false,
"expanded":true,
"leaf":false,
"children":{
"id":5,
"name":"/",
"visible":false,
"expanded":true,
"leaf":true,
"children":[]
}
}]
}
Model
Ext.define('Example.model.WebTreeItem', {
extend: 'Ext.data.Model',
idProperty: 'id',
fields: [
{name: 'id', type: 'int', defaultValue: 0},
{name: 'visible', type: 'boolean' },
{name: 'name', type: 'string' }
]
});
Store
Ext.define('Example.store.WebTreeItems', {
extend: 'Ext.data.TreeStore',
model: 'Example.model.WebTreeItem',
autoLoad: true,
proxy: {
type: 'ajax',
api: {
read : 'getlist.json'
},
reader: {
type: 'json'
}
}
});
View
Ext.define('Example.view.webitem.Tree', {
extend: 'Ext.tree.Panel',
alias : 'widget.webtreeitem',
title : 'Web items',
store: 'WebTreeItems',
rootVisible: false,
multiSelect: true,
singleExpand: false,
collapsible: true,
selModel: Ext.create('Ext.selection.CheckboxModel'),
height: 800,
renderTo: 'webstructure-tree',
columns: [{
xtype: 'treecolumn',
text: 'Name',
flex: 2,
sortable: true,
dataIndex: 'name'
},{
xtype: 'booleancolumn',
text: 'Visible',
flex: 1,
dataIndex: 'visible',
sortable: false
}],
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop'
}
}]
});
Dependencies are loaded automatically using
Ext.Loader.setConfig({enabled:true});
Ext.application({
...
});
Any suggestion will be highly appreciated.
Well I thought that I was sending aforementioned JSON, but in fact I was sending something like this (quoted response with escaped quotes) and Chromium couldn't read it correctly
"{\"text\":\".\",\"children\": [
{
\"id\":null,
\"name\":\"en\",
\"visible\":false,
\"expanded\":true,
\"leaf\":false,
\"children\":{
\"id\":5,
\"name\":\"/\",
\"visible\":false,
\"expanded\":true,
\"leaf\":true,
\"children\":[]
}
}]
}"
The Store
var timesheet = new Ext.data.JsonStore(
{
root: 'timesheetEntries',
url: 'php/scripts/timecardEntry.script.php',
storeId: 'timesheet',
autoLoad: true,
fields: [
{ name: 'id', type: 'integer' },
{ name: 'user_id', type: 'integer' },
{ name: 'ticket_number', type: 'integer' },
{ name: 'description', type: 'string' },
{ name: 'start_time', type: 'string' },
{ name: 'stop_time', type: 'string' },
{ name: 'client_id', type: 'integer' },
{ name: 'is_billable', type: 'integer' }
]
}
);
A section of my GridPanel code:
columns: [
{
id: 'ticket_number',
header: 'Ticket #',
dataIndex: 'ticket_number'
},
{
id: 'description',
header: 'Description',
dataIndex: 'description'
},
{
id: 'start_time',
header: 'Start',
dataIndex: 'start_time',
renderer: Ext.util.Format.dateRenderer('m/d/Y H:i:s')
}
...
From the server, I receive this JSON string:
{
timesheetEntries:[
{
"id":"1",
"user_id":"1",
"description":null,
"start_time":"2010-11-13 11:30:00",
"stop_time":"2010-11-13 15:50:10",
"client_id":null,
"is_billable":"0"
}
My grid panel renders fine. However, my start and stop time columns read 'NaN/NaN/NaN NaN:NaN:NaN' and I don't know why.
If your data has "2010-11-13 11:30:00" shouldn't your format be 'Y-m-d H:i:s'?
EDIT: Sorry, the grid config should be OK -- I was referring to the dateFormat value in your store's field definition, which should be 'Y-m-d H:i:s' so that your incoming data can be properly mapped to your column model. You should also include type: 'date'. You're not showing your store config, but the problem is likely one of those things being wrong.
Try this
function renderDate(v,params,record)
{
var dt = new Date(v);
if (!isNaN(dt.getDay())) {
return dt.format('d/m/Y');
}
return '-';
}
A very simple way to do it:
return Ext.util.Format.date(val,'m/d/Y');