PDA

View Full Version : [FIXED] Grouped LIst not working with AJAX proxy loading



stan229
11 Nov 2011, 9:27 AM
REQUIRED INFORMATION Ext version tested:

Sencha Touch 2.0 rev PR2

Browser versions tested against:

Chrome 15
Safari 5

DOCTYPE tested against:

html

Description:

When having a Grouped list backed by a REST proxy, it does not function.
It throws an error.
When there is data hardcoded into the store it's fine.
Digging through the source it looks like it tries to attach header to the list's DOM items that have not been rendered yet.

Steps to reproduce the problem:

Create grouped list
Call store.load() on grouped list's store.

The result that was expected:

List would render fine

The result that occurs instead:

Loading mask keeps spinning, nothing gets rendered
Error gets thrown:

. Uncaught TypeError: Cannot call method 'insertFirst' of null
. Ext.define.doAddHeadersencha-touch-all-debug.js:44659

. Ext.define.findGroupHeaderIndicessencha-touch-all-debug.js:44651

. Ext.define.doRefreshHeaderssencha-touch-all-debug.js:44385

. Ext.define.doFiresencha-touch-all-debug.js:12851

. Ext.define.firesencha-touch-all-debug.js:12777

. Ext.define.doDispatchEventsencha-touch-all-debug.js:18568

. Ext.define.dispatchEventsencha-touch-all-debug.js:18539

. Ext.define.doFireEventsencha-touch-all-debug.js:21070

. Ext.define.fireEventsencha-touch-all-debug.js:21040

. Ext.define.loadRecordssencha-touch-all-debug.js:26966

. Ext.define.onProxyLoadsencha-touch-all-debug.js:26727

. Ext.define.processResponsesencha-touch-all-debug.js:22715

. (anonymous function)sencha-touch-all-debug.js:25310

. Ext.apply.callbacksencha-touch-all-debug.js:5774

. Ext.define.onCompletesencha-touch-all-debug.js:22073

. Ext.define.onStateChangesencha-touch-all-debug.js:22024

. (anonymous function)sencha-touch-all-debug.js:1964




Test Case:
Ext.define('SuperQualifier.model.Borrower', {
extend : 'Ext.data.Model',
fields : [{
name : "id",
type : "int"
}, {
name : "lastName",
type : "string"
}, {
name : "firstName",
type : "string"
}],
proxy : {
type : "rest",
url : '../borrower/getBorrowers',
reader : {
type : 'json'
}
}
})

//Store
Ext.define('SuperQualifier.store.Borrowers', {
extend : 'Ext.data.Store',
model : 'SuperQualifier.model.Borrower',
requires : ['SuperQualifier.model.Borrower'],
getGroupString : function(record) {
return record.get('lastName')[0];
},
sorters : 'lastName',
// data : [{
// "class" : "com.breakpoint.Borrower",
// "id" : 1,
// "dateCreated" : "2011-11-02T05:26:32Z",
// "firstName" : "Testfirst",
// "lastName" : "Testlast",
// "lastUpdated" : "2011-11-02T05:26:32Z",
// "qualifiers" : []
// }]
});

//List
Ext.define('SuperQualifier.view.BorrowerList', {
extend : 'Ext.List',
xtype : 'borrowerlist',
config : {
store : 'Borrowers',
itemTpl : '<div class="contact"><strong>{firstName}</strong> {lastName}</div>',
grouped : true,
indexBar : true
}
});
Ext.setup({
onReady : function() {

Ext.create('SuperQualifier.view.BorrowerList', {
fullscreen : true,
store : Ext.create('SuperQualifier.store.Borrowers'),
listeners : {
show : function() {
this.getStore().load({
params : {
id : 1
}
});
}
}
});

}
});

HELPFUL INFORMATION Debugging already done:

Through chrome debugger

Possible fix:

Load data through Ext.Ajax.request
Populate store's data

Additional CSS used:

only default ext-all.css
custom css (include details)

Operating System:

Mac OSX 10.7.2

Jamie Avins
11 Nov 2011, 9:37 AM
Thank you for the report.

Brendan Carroll
15 Nov 2011, 11:59 AM
first argument in doAddHeader is undefiend.

Jamie Avins
15 Nov 2011, 2:01 PM
Do either of you have a bit of an easier to reproduce test case?

stan229
15 Nov 2011, 3:23 PM
Unfortunately this requires an AJAX proxy. If I give a public link that shows the error would that help?

Jamie Avins
15 Nov 2011, 3:33 PM
Anything would be great or you can PM it to me if you wish.

Brendan Carroll
15 Nov 2011, 6:08 PM
Here's my use case. The list itself:


Ext.define('Sha.view.ResultsList', {
extend: 'Ext.List',
xtype: 'resultslist',
layout: 'fit',
headerTitle: 'Search Results',
config: {
store: 'Pois',
itemTpl: '{name}',
grouped: true
//onItemDisclosure: true
},

initialize: function () {
console.log('initialize countylist');
this.callParent();
}
});


The model pulling from a .json file but really a c# WCF service with validated JSON:


Ext.define('Sha.model.Poi', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'theme', 'tname'],
proxy: {
type: 'ajax',
url: 'data/pois.json',
extraParams: {
format: 'json',
category: null,
filtertype: null,
filterid: null,
x: null,
y: null,
distance: null
},
reader: {
type: 'json',
root: 'results'
}
}
});

The store:


Ext.define('Sha.store.Pois', {
extend: 'Ext.data.Store',
requires: 'Sha.model.Poi',
model: 'Sha.model.Poi',
autoLoad: false,
sorters: 'name',
groupField: 'tname'
});


The controller. The notable part being I set the AJAX proxy extrParams then reload the store based on user selected item. In PR1 the same code worked but would end up producing multiple, empty, stacked headers if I went back to the same category over and over. The bottom header in the stack would container the data. This is why you see me trying to purge the bounded store. It never worked, though. PR2 thows an error as noted in my earlier post. If I set don't group the store it works wonderfully:


Ext.define('Sha.controller.Poi', {
extend: 'Ext.app.Controller',
views: ['SearchContainer', 'CatagoriesList', 'SearchList', 'CountiesList', 'TownsList', 'AddressGeocoder', 'ResultsList'],
stores: ['Catagories', 'SearchTypes', 'Counties', 'Towns', 'Addresses', 'Pois'],
requires: [
'Sha.class.UserInput'
],
config: {
profile: Ext.os.deviceType.toLowerCase(),
userinputs: null
},
refs: [{
selector: 'searchcontainer > navigationbar',
ref: 'navBar'
}, {
selector: 'catagorieslist',
ref: 'CatagoriesList'
}, {
selector: 'searchlist',
ref: 'SearchList'
}, {
selector: 'addressgeocoder',
ref: 'AddressGeocoder'
}, {
selector: 'townslist',
ref: 'TownsList'
}, {
selector: 'countieslist',
ref: 'CountiesList'
}, {
selector: 'poislist',
ref: 'PoisList'
}],

init: function () {
this.callParent();
this.application.addListener('GisUpdated', this.onGisUpdated, this);
//console.log('Init home controller');
// Start listening for events on views
this.control({
'list': { 'select': function (m, r) {
console.log(m.xtype);
var d = null;
switch (m.xtype) {
case 'catagorieslist':
d = this.getSearchList();
this.userinputs.setCategory(r.get('ID'));
break;
case 'townslist':
this.userinputs.setFilterId(r.get('ID'));
this.loadPois();
break;
case 'countieslist':
this.userinputs.setFilterId(r.get('ID'));
this.loadPois();
break;
case 'searchlist':
switch (r.get('LocatedBy')) {
case 'Address':
d = this.getAddressGeocoder();
//this.userinputs.setFilterId(r.get('ID'));
break;
case 'County':
d = this.getCountiesList();
this.userinputs.setFilterType('county');
break;
case 'Town':
d = this.getTownsList();
this.userinputs.setFilterType('town');
break;
case 'Current Location':
//d = this.getTownsList();
break;
case 'List':
//d = this.getTownsList();
break;
}
break;
}
if (d !== null) {
this.getNavBar().up('container').setActiveItem(d);
this.getNavBar().setTitle(d.headerTitle);
}
this.application.fireEvent('PoiUpdated', this.userinputs);
}
},
'container': { 'activeitemchange': function (cont, newVal, oldVal, opts) {
//console.log('changed to ' + newVal + ' from ' + oldVal);
if (!Ext.isEmpty(oldVal)) {
var nb = this.getNavBar();
if (!Ext.isEmpty(nb)) {
//console.log(newVal.headerTitle);
if (newVal.headerTitle === 'Choose Catagory') {
nb.down('button').setHidden(true);
} else {
nb.down('button').setHidden(false);
}
}
}
}
},
'#navBack': { 'tap': function () {
//console.log('navigating back');
var m = this.getNavBar().up().getActiveItem();
//console.log(m.xtype);
var d = null;
switch (m.xtype) {
case 'catagorieslist':
d = null;
break;
case 'searchlist':
d = this.getCatagoriesList();
break
default:
d = this.getSearchList();
break;
}
if (d !== null) {
this.getNavBar().setTitle(d.headerTitle);
this.getNavBar().up('container').setActiveItem(d);
}
}
}
});
},

loadPois: function () {
var poistore = this.getPoisStore();
//poistore.removeAll(true);

var poiproxy = poistore.getProxy();

poiproxy.setExtraParam('category', this.userinputs.getCategory());
poiproxy.setExtraParam('filtertype', this.userinputs.getFilterType());
poiproxy.setExtraParam('filterid', this.userinputs.getFilterId());

poistore.load();
//poistore.group();
},

onGisUpdated: function (ui) {
console.log('POI reports GIS updated: ' + ui.getCategory());

},

onLaunch: function () {

}
});



pois.json file extract:



{
'success': true,
'results': [
{
'id': 6182,
'cid': 1,
'name': 'PerryvillePoliceDepartment',
'theme': 'Police Stations'
},
{
'id': 6184,
'cid': 1,
'name': 'RisingSunPoliceDeptment',
'theme': 'Police Stations'
},
{
'id': 5781,
'cid': 1,
'name': 'CumberlandPoliceDepartment',
'theme': 'Police Stations'
},
{
'id': 3055,
'cid': 2,
'name': 'CapitolCollege',
'theme': 'Colleges'
},
{
'id': 2871,
'cid': 2,
'name': 'UniversityofMarylandUniversityCollege',
'theme': 'Colleges'
},
{
'id': 2872,
'cid': 2,
'name': 'PrinceGeorgesCommunityCollege',
'theme': 'Colleges'
},
{
'id': 2873,
'cid': 2,
'name': 'WashingtonBibleCollegeCapitolBibleSeminary',
'theme': 'Colleges'
},
{
'id': 2875,
'cid': 2,
'name': 'BowieStateUniversity',
'theme': 'Colleges'
},
{
'id': 3097,
'cid': 2,
'name': 'MountSaintMarysUniversity',
'theme': 'Colleges'
},
{
'id': 2700,
'cid': 2,
'name': 'FrederickCommunityCollege',
'theme': 'Colleges'
},
{
'id': 6314,
'cid': 3,
'name': 'HiltonAreacampground PatapscoValleyStatePark',
'theme': 'Parks'
},
{
'id': 6315,
'cid': 3,
'name': 'Hart-MillerIslandCampground',
'theme': 'Parks'
},
{
'id': 6316,
'cid': 3,
'name': 'FortWhaleyCampground',
'theme': 'Parks'
},
{
'id': 6317,
'cid': 3,
'name': 'CastawaysRVResortCampground',
'theme': 'Parks'
},
{
'id': 547,
'cid': 4,
'name': 'TheJohnsHopkinsHospital',
'theme': 'Parks'
},
{
'id': 549,
'cid': 4,
'name': 'DivisionofRehabilitation',
'theme': 'Parks'
},
{
'id': 550,
'cid': 4,
'name': 'KennedyKriegerInstitute',
'theme': 'Parks'
},
{
'id': 551,
'cid': 4,
'name': 'St.AgnesHospital',
'theme': 'Parks'
},
{
'id': 1178,
'cid': 4,
'name': 'BaltimoreWashingtonMedicalCenter',
'theme': 'Parks'
},
{
'id': 1180,
'cid': 4,
'name': 'AnneArundelMedicalCenter',
'theme': 'Parks'
},
{
'id': 1352,
'cid': 4,
'name': 'KimbroughAmbulatoryCareCenter',
'theme': 'Parks'
},
{
'id': 1078,
'cid': 5,
'name': 'ForestParkGolfCourse',
'theme': 'Parks'
},
{
'id': 1041,
'cid': 5,
'name': 'GlennDaleGolfClub',
'theme': 'Parks'
},
{
'id': 987,
'cid': 5,
'name': 'MarltonGolfClub',
'theme': 'Parks'
},
{
'id': 991,
'cid': 5,
'name': 'NationalGolfClub',
'theme': 'Parks'
},
{
'id': 1000,
'cid': 5,
'name': 'CountryClubatWoodmore',
'theme': 'Parks'
},
{
'id': 1001,
'cid': 5,
'name': 'LakeArborGolfClub',
'theme': 'Parks'
},
{
'id': 3338,
'cid': 6,
'name': 'AccokeekFringeParking',
'theme': 'Parks'
},
{
'id': 3818,
'cid': 6,
'name': 'JOHNSHOPSKINSHOSPITAL',
'theme': 'Parks'
},
{
'id': 3819,
'cid': 6,
'name': 'LEXINGTONMARKETSTATION',
'theme': 'Parks'
},
{
'id': 3849,
'cid': 6,
'name': 'Wheaton-DCMetroRedLine',
'theme': 'Parks'
},
{
'id': 3857,
'cid': 6,
'name': 'CollegeParkAirport',
'theme': 'Parks'
},
{
'id': 3413,
'cid': 6,
'name': 'ParkandRide',
'theme': 'Parks'
},
{
'id': 4195,
'cid': 6,
'name': 'Rockville-DCMetroRedLine',
'theme': 'Parks'
},
{
'id': 3078,
'cid': 6,
'name': 'ColesvilleCommuterLotParkandRide',
'theme': 'Parks'
},
{
'id': 7459,
'cid': 7,
'name': 'CarrollCountyFarmersMarket',
'theme': 'Parks'
},
{
'id': 7460,
'cid': 7,
'name': 'MtAiryFarmersMarket',
'theme': 'Parks'
},
{
'id': 7461,
'cid': 7,
'name': 'DowntownWestminsterFarmers Market',
'theme': 'Parks'
},
{
'id': 7462,
'cid': 7,
'name': 'TaneytownFarmers Market',
'theme': 'Parks'
},
{
'id': 6895,
'cid': 7,
'name': 'ChestertownFarmers Market',
'theme': 'Parks'
},
{
'id': 7275,
'cid': 7,
'name': 'BrunswickAreaFarmers Market',
'theme': 'Parks'
},
{
'id': 7284,
'cid': 7,
'name': 'MiddletownFarmers Market',
'theme': 'Parks'
},
{
'id': 7285,
'cid': 7,
'name': 'TheGreatFrederickFairFarmers Market',
'theme': 'Parks'
},
{
'id': 6935,
'cid': 7,
'name': 'StateCenterCommunityFarmersMarket',
'theme': 'Parks'
},
{
'id': 6936,
'cid': 7,
'name': 'UniversityFarmersMarket',
'theme': 'Parks'
},
{
'id': 6937,
'cid': 7,
'name': 'JohnHopkinsHospitalFarmersMarket',
'theme': 'Parks'
},
{
'id': 6247,
'cid': 8,
'name': 'JohnONeillMonument',
'theme': 'Parks'
},
{
'id': 6029,
'cid': 8,
'name': 'CraighillChannelRearUpperRange',
'theme': 'Parks'
},
{
'id': 5462,
'cid': 8,
'name': 'FenwickLighthouse',
'theme': 'Parks'
},
{
'id': 5969,
'cid': 8,
'name': 'CraighillChannelRearLowerRange',
'theme': 'Parks'
},
{
'id': 440,
'cid': 8,
'name': 'SANDYPOINTSHOAL',
'theme': 'Parks'
},
{
'id': 622,
'cid': 8,
'name': 'WyeGristMill',
'theme': 'Parks'
},
{
'id': 614,
'cid': 8,
'name': 'StillPondNavigationalLighthouse',
'theme': 'Parks'
},
{
'id': 722,
'cid': 8,
'name': 'PhoenixShotTower',
'theme': 'Parks'
},
{
'id': 1063,
'cid': 8,
'name': 'LazarettoLighthouse',
'theme': 'Parks'
},
{
'id': 1177,
'cid': 8,
'name': 'FortGarrison',
'theme': 'Parks'
}
]
}

Jamie Avins
16 Nov 2011, 9:34 AM
Thank you both for the detailed test cases. There were a bunch of small issues related to this problem that should now be resolved for the next release.

quocble
1 Dec 2011, 3:54 PM
GAH, I just spent 3 hrs figuring why then realized this is a bug. This is really bad.

dbwelch
7 Dec 2011, 4:54 AM
Is there a workaround for this? I have also spent a few hours looking at how to resolve...please help if any way to use grouped lists with Ajax requests!

Why does the heading on post say this was fixed? Is it in code that hasn't been released?

If so, you should probably change the verbiage in the heading.

stan229
7 Dec 2011, 8:12 AM
By fixed they mean it will/should be in the next release (PR3)

A work around (untested) is to populate the store using an Ext.request and set the store's data. Then after that you would render the list.