PDA

View Full Version : Grid not rendering



mtdave
17 Jun 2011, 7:11 AM
Hi, I have a GridPanel with an ArrayStore and I am unable to get the grid to expand/render after filling the store. I am getting no errors and everything is seemingly identical to the code for a grid I have that works!?! Can't figure out the bug. Anyone?

The grid gets passes a reference to a TabPanel.



var providersInitialized = false;
var FillGridTimeout;

function initProviders(tab) {

var grd = new Ext.grid.GridPanel({
id: 'grdProviders',
title: 'Provider List',
store: new Ext.data.ArrayStore({
idIndex: 0,
fields: [{
'name': 'ProvId',
'type': 'int'
}, {
'name': 'Name',
'type': 'string'
}, {
'name': 'DBA',
'type': 'string'
}, {
'name': 'FRN',
'type': 'string'
}, {
'name': 'Abbrev',
'type': 'string'
}]
}),
cm: new Ext.grid.ColumnModel({
defaults: {
width: 100,
sortable: true,
columns: [{
'header': 'Provider Id',
'dataIndex': 'ProvId',
'sortable': true,
'width': 50
}, {
'header': 'Name',
'dataIndex': 'Name',
'sortable': true,
'width': 150
}, {
'header': 'DBA Name',
'dataIndex': 'DBA',
'sortable': true,
'width': 150
}, {
'header': 'FRN',
'dataIndex': 'FRN',
'sortable': true,
'width': 70
}, {
'header': 'Abbreviation',
'dataIndex': 'Abbrev',
'sortable': true,
'width': 50
}]
}
}),
sm: new Ext.grid.RowSelectionModel({singleSelect:true}),
width: 686,
height: 278,
frame: true/*,
listeners: {
'added': loadProviderGrid
}*/
});
tab.add(grd);
FillGridTimeout = setTimeout('loadProviderGrid()', 2000);
providersInitialized = true;
}

//function loadProviderGrid(grid, cont, idx) {
function loadProviderGrid() {
clearTimeout(FillGridTimeout);
Ext.Ajax.request({
url: 'providers.asmx/GetProviderList',
//jsonData: { 'projid': noteProjId },
headers: { 'Content-Type': 'application/json; charset=utf-8' },
method: 'POST',
failure: function(response, options) {
Ext.MessageBox.alert('ERROR', 'JSON Request Error Providers List');
},
success: function(response, options) {
try {
var jsontxt = response.responseText.replace(/\\/g, '').replace('"[', '[').replace(']"', ']');
//console.log(jsontxt);
var jo = Ext.decode(jsontxt);
if (jo.d.length > 0) {
if (jo.d[0].Output) {
if (jo.d[0].Output.IndexOf('ERROR:') > -1) {
Ext.MessageBox.alert('ERROR', jo.d[0].Output);
}
else {
Ext.MessageBox.alert('MESSAGE', jo.d[0].Output);
}
}
else {
//console.log(grid.id);
var grid = Ext.getCmp('grdProviders');
var store = grid.getStore();
//empty the grid store if filled
if (store.getCount() > 0) {
store.removeAll(false);
}
var res = [];
for (var i=0; i<jo.d.length; i++) {
var gridRow = new store.recordType({}, i);
for (itm in jo.d[i]) {
gridRow.data[itm] = jo.d[i][itm]
}
res.push(gridRow);
}
//console.log(Ext.encode(res));
store.add(res);
//console.log(store.getCount());
//grid.show();
}
}
else {
Ext.MessageBox.alert('ERROR', 'Providers List records not returned');
}
}
catch (ex) {
Ext.MessageBox.alert('ERROR', 'JSON Decode Error<br />' + ex.toString());
}
}
});
}
Here is the res array JSON literal that gets added to the Store.



[
{
"id": 0,
"data": {
"ProvId": 1,
"Name": "North Digest Typing Company",
"DBA": "North Digest Typing Company",
"FRN": "248371",
"Abbrev": "NDT"
}
},
{
"id": 1,
"data": {
"ProvId": 2,
"Name": "Consolidated Cookdom",
"DBA": "Consolidated Cookdom",
"FRN": "2443681",
"Abbrev": "COT"
}
},
{
"id": 2,
"data": {
"ProvId": 3,
"Name": "Dynamic Copperhead Cooperative",
"DBA": "Dynamic Copperhead Cooperative",
"FRN": "3759917",
"Abbrev": "DCT"
}
},
{
"id": 3,
"data": {
"ProvId": 4,
"Name": "Detailed Root Translation",
"DBA": "Detailed Root Translation",
"FRN": "3583453",
"Abbrev": "DRT"
}
}
]
Thanks, Dave

jarlau
17 Jun 2011, 5:39 PM
You should use JsonStore instead of ArrayStore, but your JSON return isn't correct too.

should be:


{
"roots": [{id: 1, ....}, {id: 2, ....}, {id: 3, ....}],
"total": 20
}


read JsonStore (http://dev.sencha.com/deploy/ext-3.4.0/docs/?class=Ext.data.JsonStore) for example format.

skirtle
18 Jun 2011, 6:30 PM
The docs are a little misleading on the format required. In some cases you can use data like this just by omitting the root. For nested keys like those in the JSON posted you'd need something like this:


new Ext.data.JsonStore({
...
fields: [
{
mapping: 'data.ProvId',
name: 'ProvId',
type: 'int'
}, ...
]
})

That said, all of this is irrelevant because you aren't using the store's proxy and reader correctly anyway. That Ajax success handler needs to be completely removed:


Specify a proxy on your store. The easiest way is just to specify a url.
The replace() calls you're doing on the responseText suggest major escaping issues. Fix them properly.
The error handling is reinventing the wheel... successProperty and messageProperty should be able to do all of that stuff, though generally I prefer to use HTTP response codes to signify an error rather than encoding it in my JSON response.
if (jo.d[0].Output.IndexOf('ERROR:') > -1) { - IndexOf should not have an uppercase first letter.

mtdave
20 Jun 2011, 12:45 PM
I did figure this out. I had an error in my Column Model code. I was missing the curly bracket after the defaults; it works now.



cm: new Ext.grid.ColumnModel({
defaults: {
width: 100,
sortable: true
},
columns: [{
header: 'ProviderId',
dataIndex: 'ProvId',
width: 75
}, {
header: 'Name',
dataIndex: 'Name',
width: 250
}, {
header: 'DBA',
dataIndex: 'DBA',
width: 250
}, {
header: 'FRN',
dataIndex: 'FRN',
width: 75
}, {
header: 'Abbrev',
dataIndex: 'Abbrev',
width: 50
}]
}),


I wish I could use the JsonStore but I have not figured out how to create a ASP.Net service that returns valid JSON. I have to do some search and replaces on the Json strings prior to decoding it.

Otherwise it is working great!

Thanks, Dave