Starting in Cognos 10.2, IBM released a way to freeze crosstab headers and rows. This method works in all major browsers, and doesn’t rely on dirty CSS hacks. To get it working, simply right-click on the list or crosstab, and select Freeze Headers. The report will even remember the state of the crosstab after the page refreshes (from a prompt, possibly).
While this method works well, there are many times where we’d want to have the lists or crosstab start off frozen; or maybe we want to give the user a button to freeze one or all of the crosstabs in one go. Somewhat surprisingly, the JavaScript is very easy to use.
First, let’s define the initial variables:
var paulScripts = {} , win=window['oCV'+'_THIS_']; paulScripts.oCV = win.getRV().getCV();
Reports run from Report Studio need to use window[‘oCVRS’] while reports from the connection need window[‘oCV_NS_’]. Cognos will automatically replace _THIS_ to the correct fragment. Most of the Cognos functions we need are found inside win.getRV().getCV(), so we’re aliasing that into “paulScripts.oCV”.
The first function I’ll define is:
paulScripts.freezeContainer = function(objectName){ var pFMngr = paulScripts.oCV.getPinFreezeManager(); pFMngr.freezeContainer(objectName,true,true); window.onResizeViewerEvent() };
All of the freezing functions are found inside getPinFreezeManager. The function getPinFreezeManager().freezeContainer() takes the object name (“Crosstab1”), and a Boolean to freeze/unfreeze the headers, and another Boolean to freeze/unfreeze the rows.
The freezing mechanism seems to have a small bug in the way it handles resizing. In my tests, it always resizes to a much smaller window than I need. The window.onResizeViewerEvent() function tricks the browser into thinking the window has been resized, and Cognos will then correctly recalculate the size of the frozen crosstab.
The unfreezing function is simple:
paulScripts.unfreezeContainer = function(objectName){ var pFMngr = paulScripts.oCV.getPinFreezeManager(); pFMngr.freezeContainer(objectName,false,false); };
These two functions will let us automatically freeze a crosstab as soon as the page loads. But say we want to toggle it on and off.
/* paulScripts.toggleContainer * Paul Mendelson - 2014-03-25 * This wil check if a container has frozen headers. If so, it unfreezes it, if not, it freezes the container. */ paulScripts.toggleAll = function(objectName) { var pFMngr = paulScripts.oCV.getPinFreezeManager(); if(pFMngr.hasFrozenColumnHeadings(objectName)) { paulScripts.unfreezeContainer (objectName); } else { paulScripts.freezeContainer (objectName); window.onResizeViewerEvent() } }
The hasFrozenColumnHeadings function returns a Boolean, true or false, on the state of the column headers.
And finally let’s say that we want to freeze all the crosstabs on the page in one go.
/* paulScripts.toggleAll * Paul Mendelson - 2014-03-25 * in: type {string - crosstab or list} * This wil loop through every "type" on the page, and freezing or unfreezing, depending if the column header is frozen. */ paulScripts.toggleAll = function(type) { setTimeout(function(){ var xts = win._getContainers(type) , xtLen = xts.length , pFMngr = paulScripts.oCV.getPinFreezeManager(); for(var i =0;i<xtLen;++i){ var lid = pFMngr.removeNamespace(xts[i].getAttribute('lid')); if(i<xtLen-1 && lid==pFMngr.removeNamespace(xts[i+1].getAttribute('lid'))) continue; //when the panes are frozen the crosstab is split into four elements, all with the same lid. Without this hack, the xtab would toggle four times! if(pFMngr.hasFrozenColumnHeadings(lid)) { pFMngr.freezeContainer(lid,false,false); } else { pFMngr.freezeContainer(lid,true,true); window.onResizeViewerEvent() } } } ,200); }
That was a little bit more complex than before. We can use the _getContainers functions to get an array of all the lists or crosstabs on the page. The lid of the object is the name, plus the namespace. We can use the removeNamespace function to get it back to the name the freezeContainer functions expect.
The toggleAll function should only be used in a button. As Cognos stores the state of the object; if the headers are locked, they will remain locked after refreshing the page. Toggling them will cause them to unlock. Instead, it’s best to use a freezeAll function when loading the page:
paulScripts.freezeAll = function(type){ var xts = win._getContainers(type) , xtLen = xts.length , pFMngr = paulScripts.oCV.getPinFreezeManager(); for(var i =0;i<xtLen;++i){ var lid = pFMngr.removeNamespace(xts[i].getAttribute('lid')); if(pFMngr.hasFrozenColumnHeadings(lid)) continue; paulScripts.freezeContainer (lid); } };
Once everything is working, we can see how it works.
The example report in using 10.2.1, against the sales and marketing cube.
Freezing Panes report XML (1926 downloads)
Thanks Paul! This is really interesting. I’ve noted though, that many of these solutions only work in IE. I work for a university and we see all manner of browsers and Operating Systems. Is this solution platform independent?
Hi Kevin,
Browser compatibility is a bit of an issue. IE has such a wonderfully unique way of doing things, and I tend to forget that some companies and organizations let people use real browsers. The usual problems with compatibility are in attaching events (attachEvent instead of addEventListener) and setting attributes (object.attribute=something instead of object.setAttribute(attribute,something).
Fortunately this technique doesn’t need such crazy JS, and works across browsers. I’ve tested it with Firefox and it works without any issues at all.
Hi Paul,
thanks. Works very good.
I have a crosstab with lot’s of columns and I would like to get the scrollbar on the left side and not on the right. Do you think this is possible?
Without modifying the script, I don’t think this is possible. You might be able to do this if you set the direction right-to-left.
Hi Paul,
At first. Thanks for your cognos contributions. I’m a cognos solution expert and want to use one script of you for freezing columns in a cognos report. This works perfect with the interactive run of the report. But because of performance our report is scheduled and saved as HTML report.
And with the saved html report the script doesn’t work (but it there in the html source).
Do you maybe know how to solve it? I alreadys spend a half day about it and don’t see the solution.
My gratitude will be great if you can help me.
Thanks
This is the script
var paulScripts = {};
paulScripts.oCV = window[‘oCV’+’_THIS_’].getRV().getCV();
paulScripts.freezeContainer = function(objectName){
setTimeout(function(){
paulScripts.oCV.getPinFreezeManager().freezeContainerRowHeadings(objectName);
paulScripts.oCV.getPinFreezeManager().freezeContainerColumnHeadings(objectName);}
,200);
};
paulScripts.freezeContainer(‘CrosstabContinental’);
window.onResizeViewerEvent()
Hi Maarten,
Unfortunately this script relies on some internal Cognos functionality to set up the freeze. Specifically it calls on the getPinFreezeManager function which is only available in the CognosViewer. In a static HTML, you can call the functions:
oCV_THIS_.getRV().getCV().getPinFreezeManager().freezeContainer(‘Crosstab1′,’true’,’true’)
I suspect there’s an element I’m missing. Theoretically it should be possible find a way to copy the way the function works.
The meat of the function is in: ..\webcontent\rv\PinFreezeContainer.js
From a quick glance, it looks like it’s finding and moving the nodes, but it’s doing it with more internal Cognos functions.
thanks paul for your help
Thanks Paul !!!! Its working but we have to manually scroll it. Mouse scroll is not working.
Hi,
i try to use it in cognos analytics (cognos 11), but dosent work. When we run reports as HTML
HTML report output is not well formed. If your report uses “HTML Item” elements ensure that they result in well-formed HTML.
Przyczyna:error parsing attribute name
Adres URL:null
line:300
chart:23
Źródło:
This page contains the following errors:error on line 300 at column 23: error parsing attribute name
Below is a rendering of the page up to the first error.
Are you using the new interactive mode? That is sufficiently different where I don’t expect anything to work. If it’s using the old presentation mode, it should still work fine. Why don’t you email me a copy of the xml and I’ll try to take a look.
Hi Paul,
Your code is working for single crosstab in a certain page. However, when I am adding crosstabs, they tend to be distorted in a way that I cannot control its size anymore. I am using Cognos 11 anyways. Thank you in advance.
My JavaScript basically calls the same function that’s use when you right click on the crosstab and select “Freeze Rows” and “Freeze columns”. Test those, if you get the same problem I’d strongly recommend opening a PMR with IBM. If not, can you send me the specs? If I can replicate it, I might be able to find a solution.
Thanks for the immediate response Paul. Manually freezing rows and columns in Cognos Viewer does not distort the crosstabs. So I was thinking that the code should work fine. Besides, though there are multiple crosstabs in my report, they are only shown one by one per scenario as defined by the prompt parameters. How should I email you the specs? Thank you.
HI PAUL
This script is not working for cognos11.1.6 version.Please provide me the updated script.