I was recently working on a project where there was specific help text that proved to be quite long in many cases. The original plan was to use Ext.Msg but that quickly became impractical due to the sheer amount of text. Next thing to use was Ext.Sheet which has the flexibility and options that I needed.

The Sheet ended up configured to have a toolbar and footer, docked to the top and bottom respectively. I further configured it to float in the center of the screen with about a 40 pixel margin around the sides. The lone item in the Sheet was a panel configured to use an XTemplate so that I could update it as needed with whatever help text came across the help web service.

The problem I encountered was that I could only populate the content panel within the Sheet once. It turns out that the activate listener for the content panel only ever fires one time – the very first time that the Sheet is displayed which is the first time the panel is activated.

After some thought this behavior makes sense. The panel is rendered the first time and the activate event fires. Thereafter, it doesn’t need to fire because it is always the lone active item of the sheet – it has already been activated/rendered. If I were to add another item to the sheet and switch between the two I would then get the activate event firing for both panels every time they are switched. As it is, the panel is activated the very first time out of necessity, activate naturally fires, and that is pretty much the end of it.

Back to the task at hand, I don’t have anything bound to stores, no proxies… I didn’t want to mess with that, I just wanted to push an object into the panel and I could only do it once with the panel’s activate event. Every other call to show the Sheet would not update the content with new text – only the very first item was ever displayed and all further use of the Sheet would only show the content that it was initially updated with.

See the following code which fits this scenario:

...
var helpSheet_tpl = new Ext.XTemplate(
    '',
        '
{data}
', '
', { compiled:true } ); var helpContent = new Ext.Panel({ id:'helpContent', layout:'card', scroll:'vertical', tpl:helpSheet_tpl, listeners:{ activate:function(e,o){ // this event will only ever fire once!!! helpContent.update(DATA); } } }); var helpSheet = new Ext.Sheet({ id:'helpSheet', cardSwitchAnimation:{type:'pop',duration:1000}, height: window.innerHeight - 40, width: window.innerWidth - 40, centered:true, floating:'true', layout: { type: 'card', align: 'stretch' }, items:[ helpContent ], dockedItems:[ { xtype:'toolbar', layout:'card', dock:'top', id:'help_header', title:'Help', }, { xtype:'button',text:'OK', layout:'card', dock:'bottom', listeners:{ tap:function(o,e){ helpSheet.hide(); } } } ] }); ...

The learning here is that the activate event for the above content panel will only fire once because it is the lone item – there is no item-switching happening and so therefore no opportunities for activate to fire again. Also, Ext.Sheet doesn’t have any events so you can’t put an activate event listener on it. At least, when I attempted this nothing happened at all. The Sencha docs imply that it is inherited but if you check the option to hide inherited you will see that there is nothing left event-wise for Ext.Sheet.

If you want to push an object into a panel in the above scenario by using the panel update() method you will have to do so outside of the panel, and not rely on the panel’s activate event. In my case I placed it within the JSONP callback. First I use the show() method to show the sheet and then I follow that up with the update() method on the panel.