Freezing headers in Cognos 10.2

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).

right click action

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.
Freezing panes

The example report in using 10.2.1, against the sales and marketing cube.
Freezing Panes report XML (1924 downloads)

Review: IBM Cognos BI v10.2 Administration Essentials

Part of my job as an Admin is to understand all aspects of the Cognos environment, from configuring and tuning distributed systems to being able to decipher the cryptic error messages that occasionally plague the users. Obviously this book is not for me. This book is more geared for beginners, as it says in the beginning:

Who this book is for
This book is for beginners planning to learn IBM Cognos BI Administration 10.

So, with that in mind it’s important to remember that experienced admins can skip the book. It is the people with little or no administrative experience who will benefit most from the book.

My concern is the length, at 128 pages there is simply not enough room to go into detail on everything. While it gives descriptions on the various tabs and settings of the administration page, I would have preferred more explanations on the settings and their effects.

Despite the brevity it does cover, albeit briefly, the various elements that are involved in the administrative process. The chapters are split by area of interest, configuration, components, security, etc. It describes the what happens when Cognos gets a request and the path the request takes from the gateway through the dispatcher. It explains the authentication and security system fairly well. Most importantly it also provides advice for new admins on how to run the system.

Ultimately I believe the book succeeds in its goal, namely taking people to the point where they can keep a Cognos server up and running.

You can find the book at the PacktPub website here.

Quick and painless way of accessing users’ folders

As part of my administrative duties for my various clients, I periodically trawl through the logs. Many times I’ll want to see exactly what the users are doing in the reports on my server. It becomes a headache when these reports are in the users’ “My Folders”. I need to go into the administration page, find the user, go into their “My Folders”, copy out the report, paste it into mine then run it. It’s a mess and I’m far too lazy for that.

Fortunately Cognos allows us to access objects through URL parameters. On my laptop, I’m using OpenDJ as my authentication provider, so the CAMID is slightly different than Active Directory. My CAMID here is CAMID(“OpenDJ:u:cn=administrator”). In AD, it might be CAMID(“AD:u:r7a1n7d8o8m3l1e4t9t2e2r4s01234567)

My user

I can just copy that CAMID and paste it into the URL as:
http://server/cognos/cgi-bin/cognosisapi.dll?b_action=xts.run&m=portal/cc.xts&m_path=CAMID(“OpenDJ:u:cn=administrator”)

2. Accessing my user

Obviously this is still predicated on the security in place. A user who doesn’t have permission to access another user’s folder will get an “Access Denied”

3. Thwarted again

UPDATE!
In the comments below, Ryan shared that a users’ folders can be accessed directly with the username:
http://server/cognos/cgi-bin/cognosisapi.dll?b_action=xts.run&m=portal/cc.xts&m_path=//account[@userName=’john.doe’]/folder[@name=’My Folders’]