PDA

View Full Version : Paging Toolbar sometimes (!) causes error



Arcomat
26 Nov 2007, 9:32 AM
Hello guys!

I have an extremely strange behaviour of a panel with a paging toolbar... I hope somebody can figure out why this happens. The problem is that my panel containing the data and paging toolbar works only sometimes! Sometimes the paging toolbar causes an "btn has no property error". I think this is quite strange because it is one and the same code which sometimes works and sometimes crashes! :-?

here we go, you can see the screens attached! the code is the same, just reloaded the site some times!!

my code


/*
* Ext JS Library 2.0 RC 1
* Copyright(c) 2006-2007, Ext JS, LLC.
* [email protected]
*
* http://extjs.com/license
*/

Ext.onReady(function(){
// get the companyId from DOM
var element = Ext.get('companyId');
var cid = element.dom.innerHTML;

var Person = Ext.data.Record.create([
{name: 'publicationId'},
{name: 'title'},
{name: 'type', mapping: 'publicationTypeName'},
{name: 'releaseYear'},
{name: 'isbn'},
{name: 'language', mapping: 'languageName'},
{name: 'persons'},
{name: 'price', mapping: 'brutto'},
{name: 'hits'},
{name: 'cover'},
{name: 'forSales'},
{name: 'availabilityCodeId', mapping: 'availability_code_id'},
{name: 'availabilityCode', mapping: 'availability_code'}
]);

var ds = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: DOMAIN + '/?path=/getCompanyPublications'
}),
reader: new Ext.data.JsonReader({
root: 'publications',
totalProperty: 'totalCount'
},
Person),
baseParams: {limit:7, companyId: cid}
});
// add event handler for load exceptions
ds.on('loadexception', function(){alert("load exception")});

var resultTpl = new Ext.XTemplate( /* template stuff */ );
var panel = new Ext.Panel({
applyTo: 'publications-panel',
title:'Veröffentlichungen',
autoHeight:true,
autoScroll:true,
baseCls:'publication-panel',

items: new Ext.DataView({
tpl: resultTpl,
store: ds,
itemSelector: 'div.search-item'
}),
/*
tbar: [
'Search: ', ' ',
new Ext.app.SearchField({
store: ds,
width:320
})
],
*/
bbar: new Ext.PagingToolbar({
store: ds,
autoHeight:true,
pageSize: 7,
cls: 'publication-panel-toolbar',
displayInfo: true,
displayMsg: 'Veröffentlichung {0} - {1} von {2}',
emptyMsg: 'Keine Veröffentlichungen',
beforePageText: 'Seite ',
afterPageText: 'von {0}'
})
});

/**
* Method enables the bottom paging toolbar if the
* size of the results are greater than 7
*/
function switchToolbar() {
var size = ds.getTotalCount();
if(size > 7) {
panel.getBottomToolbar().show();
} else {
panel.getBottomToolbar().hide();
}
}

ds.load({
params:{start:0, limit:7, companyId: cid},
callback: switchToolbar
});
});



so WHY does the code work only sometimes? why causes the paging toolbar crash with "btn has no property error"? :((

using ext-debug the significant line shows up in the onRender eventhandler (line 19014):

var btnEl = btn.child(this.buttonSelector);
btn seems to be undefinde SOMETIMES, but WHY?? :-?

26 Nov 2007, 9:42 AM
Just curious:

- Do you always put the copyright EXTJS in your code?
- You don't need to set page size if you're limiting the data in the store Level

can you figure out when it happens? Like what steps do you take (hide/show/etc) to cause the problem.

you need to record your steps so peeps can recreate the problem affectively.

hendricd
26 Nov 2007, 10:17 AM
You should probably wait on messing with toolbar visibility until after the panel is rendered.




var panel = new Ext.Panel({
applyTo: 'publications-panel',
title:'Veröffentlichungen',
autoHeight:true,
autoScroll:true,
deferredRender: false,
baseCls:'publication-panel',

items: new Ext.DataView({
tpl: resultTpl,
store: ds,
itemSelector: 'div.search-item'
}),
/*
tbar: [
'Search: ', ' ',
new Ext.app.SearchField({
store: ds,
width:320
})
],
*/
bbar: new Ext.PagingToolbar({
store: ds,
autoHeight:true,
pageSize: 7,
cls: 'publication-panel-toolbar',
displayInfo: true,
displayMsg: 'Veröffentlichung {0} - {1} von {2}',
emptyMsg: 'Keine Veröffentlichungen',
beforePageText: 'Seite ',
afterPageText: 'von {0}'
}),
listeners:{render: function(panel){

ds.load({
params:{start:0, limit:7, companyId: cid},
callback: switchToolbar
});

}}
});

Arcomat
26 Nov 2007, 10:36 AM
Just curious:
- Do you always put the copyright EXTJS in your code?

sry, that's because i adopted from an extjs example ;)


- You don't need to set page size if you're limiting the data in the store Level

ok, but i suppose that is not the cause here...


can you figure out when it happens? Like what steps do you take (hide/show/etc) to cause the problem.

It somteimes happens when the page containing the panel initially loads. I dont do anything to cause the problem! Just reload the page... :-?

Arcomat
26 Nov 2007, 10:37 AM
You should probably wait on messing with toolbar visibility until after the panel is rendered.
thx 4 the hint, I'll try that tomorrow and post my results

26 Nov 2007, 10:37 AM
Yeah i know it's not the cause but i just thought i'd point it out :)


so reloading (as in F5) makes it break? What browser + OS? are you using the state manager?

Arcomat
26 Nov 2007, 11:01 AM
so reloading (as in F5) makes it break? What browser + OS? are you using the state manager?
exactly!

I'm working on Linux, Webserver is Linux too. Tried it in FF and IE, problem happens with both brothers sometimes.

I am not using the state manager.

Feel free to test it yourself!!

http://dev.brainguide.de/schmidt-verlag-gmbh-co/companydetail,2,,,,,8773.html

Klick on the "Ver

26 Nov 2007, 11:15 AM
You should probably wait on messing with toolbar visibility until after the panel is rendered.




var panel = new Ext.Panel({
applyTo: 'publications-panel',
title:'Veröffentlichungen',
autoHeight:true,
autoScroll:true,
deferredRender: false,
baseCls:'publication-panel',

items: new Ext.DataView({
tpl: resultTpl,
store: ds,
itemSelector: 'div.search-item'
}),
/*
tbar: [
'Search: ', ' ',
new Ext.app.SearchField({
store: ds,
width:320
})
],
*/
bbar: new Ext.PagingToolbar({
store: ds,
autoHeight:true,
pageSize: 7,
cls: 'publication-panel-toolbar',
displayInfo: true,
displayMsg: 'Veröffentlichung {0} - {1} von {2}',
emptyMsg: 'Keine Veröffentlichungen',
beforePageText: 'Seite ',
afterPageText: 'von {0}'
}),
listeners:{render: function(panel){

ds.load({
params:{start:0, limit:7, companyId: cid},
callback: switchToolbar
});

}}
});



He's right. Only add/delete/modfy the tool bar after the grid is rendered.

26 Nov 2007, 11:20 AM
Which JS file is the grid in? That page is HUGE

Arcomat
26 Nov 2007, 11:22 AM
ok, I said it already, I'll immediatly try this tomorrow and report the results.

Thank you for your suggestions so far!! ;)

Edit: script is in company-publications.js

Arcomat
27 Nov 2007, 1:20 AM
I just applied the changes posted by hendricd but that is not a solution, same problem remains... :((

panel code is now


var panel = new Ext.Panel({
applyTo: 'publications-panel',
title:'Veröffentlichungen',
autoHeight:true,
autoScroll:true,
deferredRender:false,
baseCls:'publication-panel',

items: new Ext.DataView({
tpl: resultTpl,
store: ds,
itemSelector: 'div.search-item'
}),
bbar: new Ext.PagingToolbar({
store: ds,
autoHeight:true,
pageSize: 7,
cls: 'publication-panel-toolbar',
displayInfo: true,
displayMsg: 'Veröffentlichung {0} - {1} von {2}',
emptyMsg: 'Keine Veröffentlichungen',
beforePageText: 'Seite ',
afterPageText: 'von {0}'
}),
listeners:{render: function(panel){
ds.load({
params:{start:0, limit:7, companyId: cid},
callback: switchToolbar
});
}}
});

btw, why is there no documentation for the Ext.Panel class in the API Doc? :(

27 Nov 2007, 4:25 AM
Yeah there is documentation ;)

Arcomat
27 Nov 2007, 6:08 AM
using an alert statement i pointed out that the 'render' event is not fired in the error cases. that means that something prevents or interrupts the rendering of the panel. what could be reasons for the panel not finishing rendering proces sometimes? :-/

any ideas are highly appreciated ;)

27 Nov 2007, 6:14 AM
change: var panel = new Ext.Panel({
applyTo: 'publications-panel',

to
var panel = new Ext.Panel({
renderTo: 'publications-panel',

and see what happens.

hendricd
27 Nov 2007, 6:28 AM
Can you post your HTML?

Arcomat
27 Nov 2007, 7:10 AM
changing from 'applyTo' to 'renderTo' does not make a difference, problem remains the same...

html contains only one layer for the panel

<div id="publications-panel" style="margin-bottom: 20px;"></div>

perhaps the problem could be that there is further JS executed before? There is a JS layer navigation used to hide and show different layers within the page. one of this layer holds the DIV with the paging panel...

but why does the error occur only sometimes?? thats what makes me crazy, the code seems to work actually... :-/

27 Nov 2007, 7:36 AM
changing from 'applyTo' to 'renderTo' does not make a difference, problem remains the same...

html contains only one layer for the panel

<div id="publications-panel" style="margin-bottom: 20px;"></div>

perhaps the problem could be that there is further JS executed before? There is a JS layer navigation used to hide and show different layers within the page. one of this layer holds the DIV with the paging panel...

but why does the error occur only sometimes?? thats what makes me crazy, the code seems to work actually... :-/



is your HTML being dynamically added to the DOM or is it in the page when the page loads?

Arcomat
27 Nov 2007, 7:41 AM
is your HTML being dynamically added to the DOM or is it in the page when the page loads?
it is in the page when the page loads

hendricd
27 Nov 2007, 7:45 AM
What else (library, cardlayout ? ) is managing that div?

We're flying blind here, open our eyes /:)

Arcomat
27 Nov 2007, 8:22 AM
in short the HTML page looks as follows


[ ... ]

<div class="tabcontentstyle">

<!-- tab overview -->
<div id="overview" class="tabcontent">
[ ... ]
</div>

<!-- tab experts -->
<div id="experts" class="tabcontent">
[ ... ]
</div>

<!-- tab publications -->
<div id="publications" class="tabcontent">
<!-- LAYER WITH EXTJS PANEL -->
<div id="publications-panel" style="margin-bottom: 20px;"></div>
[ ... ]
</div>

<!-- tab events -->
<div id="events" class="tabcontent">
[ ... ]
</div>

</div>

[ ... ]

the 4 tabs are managed by other JS (tabcontent script from DynamicDrive). When you first load the page the first tab (overview) is visible.

Of course there is more HTML before and after the layer but thats simple HTML and nothing else. At the end there is some etracker JS...

27 Nov 2007, 8:39 AM
wow - what a mixture of stuff - no offense dude.

You can easily use the card layout manager to manage your own tabs. you can eliminate just about all other javascript from your site if you rewrite it in ext ;)

Arcomat
27 Nov 2007, 9:14 AM
hm, I am looking forward to trying the card layout manager but did not find any tutorial or manual for it. only the little example in the api docs, but I'll give it a try anyway... thx for your help! and if I can figure out what the problem is I'll let you know here ;)

Arcomat
28 Nov 2007, 3:13 AM
Further debugging using the ext-debug-all.js pointed out that the error happens in the insertHtml() method of Ext.DomHelper and might be a bug in Ext.

The insertHtml method of Ext.DomHelper looks like


insertHtml : function(where, el, html){
where = where.toLowerCase();
if(el.insertAdjacentHTML){
if(tableRe.test(el.tagName)){
var rs;
if(rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html)){
return rs;
}
}
switch(where){
case "beforebegin":
el.insertAdjacentHTML('BeforeBegin', html);
return el.previousSibling;
case "afterbegin":
el.insertAdjacentHTML('AfterBegin', html);
return el.firstChild;
case "beforeend":
el.insertAdjacentHTML('BeforeEnd', html);
return el.lastChild;
case "afterend":
el.insertAdjacentHTML('AfterEnd', html);
return el.nextSibling;
}
throw 'Illegal insertion point -> "' + where + '"';
}
var range = el.ownerDocument.createRange();
var frag;
switch(where){
case "beforebegin":
range.setStartBefore(el);
frag = range.createContextualFragment(html);
el.parentNode.insertBefore(frag, el);
return el.previousSibling;
case "afterbegin":
if(el.firstChild){
range.setStartBefore(el.firstChild);
frag = range.createContextualFragment(html);
el.insertBefore(frag, el.firstChild);
return el.firstChild;
}else{
el.innerHTML = html;
return el.firstChild;
}
case "beforeend":
if(el.lastChild){
range.setStartAfter(el.lastChild);
frag = range.createContextualFragment(html);
el.appendChild(frag);
return el.lastChild;
}else{
el.innerHTML = html;
return el.lastChild;
}
case "afterend":
range.setStartAfter(el);
frag = range.createContextualFragment(html);
el.parentNode.insertBefore(frag, el.nextSibling);
return el.nextSibling;
}
throw 'Illegal insertion point -> "' + where + '"';
},

I pointed out that the highlighted check sometimes evaluates to 'undefined', then it works (probable because el.insertAdjacentHTML() is not called any more) but sometimes evaluates to


function (where, htmlStr) {
var r = this.ownerDocument.createRange();
r.setStartBefore(this);
var parsedHTML = r.createContextualFragment(htmlStr);
this.insertAdjacentElement(where, parsedHTML);
}
In this case it does not work. I'm not sure but I could imagine that there is a problem with the reference to this within this method which is then called to insert the html... :-?

Apart from the fact that it does not work in that case I wonder why the check if(el.insertAdjacentHTML) evaluates variably each time without any changes to code or HTML. 8-|

What are you guys thinking about this stuff? If it's really a bug I could post it in the bug section too.