PDA

View Full Version : [Ext.ux.Accordion] Unable to autoCreate content - possible bug?



staticboy
21 Aug 2007, 3:33 AM
Message for jsakalos (http://extjs.com/forum/member.php?u=2178).

Firstly, thank you for the fantastic Accordion extension widget!

However, I think I may have found a tiny bug, but not sure because my JavaScript just isn't good enough to know exactly. I'm trying to dynamically build an accordion (ultimately from JSON received from an XHR). I started out using the 3. Create Accordion with two panels sample code on http://aariadne.com/accordion/, to which I added a third Ext.ux.InfoPanel assigned to variable autopanel1:




var acc = new Ext.ux.Accordion('acc-ct', {
fitHeight: true
})

// create panel 1
var panel1 = acc.add(new Ext.ux.InfoPanel('panel-1', {
}));

// create panel 2
var panel2 = acc.add(new Ext.ux.InfoPanel('panel-2', {
}));

// auto create a panel
var autopanel1 = acc.add(new Ext.ux.InfoPanel(Ext.id(), {
autoCreate:true,
icon: iconPath + 'calendar_view_month.png',
title: '<b>autoCreat</b>ed Title',
content: '<p>Here is some <b>autoCreat</b>ed content!</p>'
}));The result was an Accordion widget with three bars, but the third didn't contain any content. So I started to poke around in the Ext.ux.InfoPanel.js file to see how it worked. I noticed on lines 84-102 the state of autoCreate is handled as follows:




// handle autoCreate
if(this.autoCreate) {
oldHtml = this.el.dom.innerHTML;
this.el.update('');
this.desktop.appendChild(this.el);
this.el.removeClass('x-layout-inactive-content');
}
// handle markup
else {
this.el.clean();
if(this.el.dom.firstChild && !this.bodyEl) {
this.title = this.title || this.el.dom.firstChild.innerHTML;
if(this.el.dom.firstChild.nextSibling) {
this.body = Ext.get(this.el.dom.firstChild.nextSibling);
}
oldTitleEl = this.el.dom.firstChild;
oldTitleEl = oldTitleEl.parentNode.removeChild(oldTitleEl);
oldTitleEl = null;
}
}
It appears that if autoCreate == true then oldHtml = this.el.dom.innerHTML, but for an auto-created InfoPanel el.dom.innerHTML will be "". As oldHtml is used later to set the content then it will be empty regardless of what is set by config.content.

My fix was to comment out line 85 as follow, and it worked for me, but I can't get my head around if this 100% correct!




// handle autoCreate
if(this.autoCreate) {
//oldHtml = this.el.dom.innerHTML;
this.el.update('');
this.desktop.appendChild(this.el);
this.el.removeClass('x-layout-inactive-content');
}
// handle markup
else {
this.el.clean();
if(this.el.dom.firstChild && !this.bodyEl) {
this.title = this.title || this.el.dom.firstChild.innerHTML;
if(this.el.dom.firstChild.nextSibling) {
this.body = Ext.get(this.el.dom.firstChild.nextSibling);
}
oldTitleEl = this.el.dom.firstChild;
oldTitleEl = oldTitleEl.parentNode.removeChild(oldTitleEl);
oldTitleEl = null;
}
}

mystix
21 Aug 2007, 3:58 AM
hi staticboy, user extension bugs are not offcially supported by Ext, and should be addressed in the User Extensions forum.

thanks.

staticboy
21 Aug 2007, 5:15 AM
Oops, sorry mystix. Thanks for moving my post into the appropriate forum. I completely over-looked its existence!

jsakalos
21 Aug 2007, 11:02 AM
Try to use newest beta version. http://aariadne.com/accordion-preview. There are many bug fixes and improvements including auto-creation logic.

staticboy
22 Aug 2007, 5:08 AM
Hi jsakalos, I pulled the latest versions of both Ext.ux.Accordion.js and Ext.ux.InfoPanel.js from the site. Looks as though I was using 151 and the new files are version 152.

I'm afraid that the version 152 files reinstated the original problem as descibed above and only commenting out the code on line 86 of Ext.ux.InfoPanel.js got it working again:




oldHtml = this.el.dom.innerHTML;

Is it that I am misunderstanding the intended purpose of the autoCreate flag? Is content a supported config option?

jsakalos
22 Aug 2007, 1:59 PM
Hi jsakalos, I pulled the latest versions of both Ext.ux.Accordion.js and Ext.ux.InfoPanel.js from the site. Looks as though I was using 151 and the new files are version 152.

I'm afraid that the version 152 files reinstated the original problem as descibed above and only commenting out the code on line 86 of Ext.ux.InfoPanel.js got it working again:




oldHtml = this.el.dom.innerHTML;Is it that I am misunderstanding the intended purpose of the autoCreate flag? Is content a supported config option?


I've never used content in fact... I always specified content by html of autoCreate object or update method or html markup or I dynamically loaded it. Try one of these as a workaround.

staticboy
24 Aug 2007, 7:32 AM
Hello again jsakalos.

The reason I'm trying to do this is because I want to build an accordion contain tickers and stock prices with the data coming from an XHR JSON response. Clicking each item will expand it to show more info. It easy to see why I want to add items dynamically. Would you be willing to share with me how you "dynamically load it"?

Here is what I'm doing, but it only works if line 86 in Ext.ux.InfoPanel.js is commented out, which presumably would break someother usage of the contructor? This works for me, but if there's a right way to do I'd prefer not to modify your code.

Regards.




for (var i = 0; i < dsStocks.getCount(); i++) {
var stock = dsStocks.getAt(i);

// auto create panels in accordion
accordionStocks.add(new Ext.ux.InfoPanel(Ext.id(), {
autoCreate:true,
icon: stock.data['Change'] == '' ? (imagePath + 'stock.gif') : stock.data['Change'] < 0 ? (imagePath + 'stock_dn.gif') : (imagePath + 'stock_up.gif'),
title: renderStockTitle(stock), // Function to build HTML string
content: renderStock(stock) // Function to build HTML string
}));
}

jsakalos
24 Aug 2007, 7:53 AM
There is example of this on preview page (http://aariadne.com/accordion-preview). You just set the url and the panel content is loaded from this url on expand. If you set loadOnce:true content is loaded only once if not it's reloaded with each expand.

See line 940 of application source code.

jsakalos
24 Aug 2007, 7:55 AM
One more note: don't specify content like that. Better is either to load it dynamically or first create panel and then call panel.update('put content here');

staticboy
30 Aug 2007, 1:53 AM
I altered my loop around the Ext.data.Store of stocks data so that accordion widgets are added as you suggested. Works like a charm and no need for the hack in the Ext.ux.InfoPanel.js file! I knew I wasn't doing something right, I just couldn't work out what.

Thanks.




for (var i = 0; i < dsStocks.getCount(); i++) {
var stock = dsStocks.getAt(i);

accordionStocks.add(new Ext.ux.InfoPanel(Ext.id(), {
title: renderStockTitle(stock),
icon: renderStockIcon(stock),
draggable: false,
autoCreate: {
tag: 'div',
children:[{
tag: 'div',
cls: 'text-content',
html: renderStockDetail(stock)
}]
}
}));
}

jsakalos
30 Aug 2007, 10:31 AM
Perfect!

I'm glad it works for you.