ExtJS 4.0: Keeping a row at the top position in a GridPanel

I’ve had the need for a grid I am working on keep a row representing the user currently logged in as the top row in the grid. Mind you there is no paging on this grid. I am using a slightly outdated version of ExtJS, i.e 4.0. I tried listening to the viewready event on the grid itself or its view but those events were not firing. Seems the viewready event is only available on the view as of ExtJS 4.1. To alleviate this problem the next best thing available to me was the refresh event, which event though would be called many times over did the job of informing me of when the view rows are actually displayed, which the afterrender event does not provide.

I ended adding the following listener to my grid’s viewConfig definition:


viewConfig:{
     loadingUseMsg:true,
     listeners:{
          refresh:{
                fn:me.moveUserRowToTop,
                scope:this
          }
    }
}

and the moveUserRowToTop function does this:


moveUserRowToTop:function(gridView, eOpts)
{
var store = gridView.getStore();
var currentUserRecordIndex = store.find('id',currentUser.get('id'))
if(currentUserRecordIndex > 0)
{
    var currentUserRecord = store.getAt(currentUserRecordIndex);
    store.removeAt(currentUserRecordIndex);
    store.insert(0, [currentUserRecord]);
    gridView.refresh();

}

}

So as you can see even though the event gets fired a lot depending on your grid usage, mine is average it will only move the row if it is present and at an index greater than 0, which is exactly my use case.

Hope it helps

Advertisements

ExtJS: Printing Panels and Grids

One of the features i had to implement in one of the ExtJS application I’ve worked on  is printing. I was surprised to find out that there was no official print stylesheet for ExtJS. Overall, my strategy was to bring up the print layout within a popup window and call the window.print() command once rendering was done. My application being composed of a mixture of form fields, text and grids within the same screen, the number one issue here for me was how to show that same information in a printable format. No magic from ExtJS here, i referenced a PDF version of the application to redesign the UI for printing purposes. As far as the data itself, i could simply grab everything i needed by referencing the Ext object in the parent window:


var parentExt = window.opener.Ext;

My first issue was dealing with Grids. For that, i used the excellent Ext.ux.Printer extension by Ed Spencer that i had to tweak it a bit to get it to work with that i was trying to do since it is designed to print a grid within a popup window. The grid being part of my print page, i just modified its GridRenderer object to render the grid as an HTML table to the DOM. Note that, because of dimensions requirements being different for a print layout, and also display columns requirement being different between the application grid and its printed version, the more convenient resolution was to create a second hidden gridpanel within the application, with its dimensions and columns optimized for printing. The Ext.us.Printer also comes with a print stylesheet that i used as a base for my own.

The second issue i ran into once the layout was completed and rendered fine was that only the first of my two print pages would actually print content. The second page would just be blank. This was in both Firefox and IE6. It took me a while to figure out that this was due to the overflow:hidden CSS property set by the ExtJS stylesheet on most DIVs. Coupled with the way ExtJS renders content by nesting DIV even setting overflow to visible on the body tag of my popup window’s HTML did not yield the necessary results. I created a couple of CSS class for printing and used the bodyCfg property of the Panel object to finally get the necessary CSS to apply and the pages to print correctly.

Here is a summary of the code:


/* Added to my print style sheet */

.x-print-body

{
 overflow: visible;
}
.x-print-bwrap
{
 left: 0;
 overflow: visible;
 top: 0;
}

/* My Panel definition for printing*/

var printPanel = new Ext.Panel(
 {
 id:'printPanel',
 border:false,
 width:650,
 autoHeight:true,
 style:'padding:5px; overflow:visible',
 renderTo:'printContent',
 bodyStyle:'overflow:visible',
 bodyCfg:
 {
 tag: 'div',
 cls: 'x-print-body'  // Default class not applied if Custom element specified
 },
 bwrapCfg:
 {
 tag: 'div',
 cls: 'x-print-bwrap'  // Default class not applied if Custom element specified
 },
 items:
 []

}

 

 

Until such time!