An Alternative to getElementById for Active Reports


A major frustration of mine with Cognos Active Reports has been that when the report is created, it renames the ids of every element.  This makes it very difficult to write Javascript that affects a specific element.  As far as I can tell, there is no way around this, so function getElementById() becomes useless to us.

The technique I came up with to work around this issue involves giving each element you need to identify a custom attribute (I call it “ARId”), and adding an array to the document that contains each of those elements.  To accomplish this I created four functions:

  1. ARIdExists(ARId) – Tests for the existence of the ARId in the array.  This is used to prevent us from accidentally adding the element to the array twice.
  2. pushNewAEId(node) – This adds a node to the array.
  3. registerARElements(init) – This initializes the array (if the first parameter is 1), and then goes through the document looking for any elements with an ARId attribute.  If it finds any, it adds them to the array.  To improve the speed of this, the function includes a list of tagNames that could possibly be tagged with an ARId.  You’ll want to edit this list to match your requirements.
  4. getElementByARId(ARId) – This is the replacement for getElementById.  Pass into it the ARId and it returns the corresponding element.

To get the functions to be created automatically, I use a hidden image and build them off the image’s onLoad event (see my post Creating JavaScript Functions in Active Reports).

The following script creates the functions above and then runs registerARElements(1) to initialize the array and load it.  It needs to be in an HTML item placed on the report’s page, outside any decks.

<img src="hal/imagesirot/progress.gif" width="1" height="1"  style="display:none;" onload="
while( ! alert) {} 
if(!document.ARIdExists ) { 
	ARIdExists = function(value) { 
		for (var i = 0; document.registeredARElements.length > i; i++ ) { 
			if (document.registeredARElements[i] == value) { 
				return true; 
			} 
		} 
		return false;	
	} 
} 
if (!document.pushNewARId) { 
	pushNewARId = function(node) { 
		if ( ARIdExists(node.arid) == false ) { 
			document.registeredARElements.push( node ); 
		} 
	} 
} 
if (!document.registerARElements ) { 
	registerARElements = function(init) { 
		if (init == 1) { 
			document.registeredARElements = []; 
		} 
		tagNames=['SPAN', 'DIV', 'TABLE', 'IMG']; /* edit this list to include any tagnames you give an arid */ 
		for (var i = 0; tagNames.length > i; i++) { 
			es = document.getElementsByTagName( tagNames[i] ); 
			for (var x = 0; es.length > x; x++) { 
				pushNewARId( es[x] );  
			} 
		}  
	} 
} 
if (!document.getElementByARId ) { 
	getElementByARId = function(id) { 
		for (var i=0; document.registeredARElements.length > i; i++) { 
			if ( document.registeredARElements[i].getAttribute('arid') == id ) { 
				return document.registeredARElements[i]; 
			} 
		} 
	} 
} 
registerARElements(1); 

"/>

If you have any decks on the page, Cognos does not render these when the page first loads, so you’ll need to register the deck’s elements separately by placing this HTML item in each deck:

<img src="hal/imagesirot/progress.gif" width="1" height="1"  style="display:none;" onload="
registerARElements();  
"/>

No, all you need to do is tag any elements you’ll need to get with the new ARId.  For example:

<span arid="spanElementA" style="background-color: silver;">Span Element A</span>

And then to get the element, use the new get function:

<div onClick=" 
	getElementByARId('spanElementA').style.backgroundColor='red'; 
 ">

As always, if you can think of any ways to improve this technique, please leave a comment.

Advertisements

5 Responses to An Alternative to getElementById for Active Reports

  1. Turner says:

    This is really clever, thank-you. Do you have any instructions or articles as to how to add the custom attribute to the elements? I’m not sure where to do that from.

    • Bob Reddert says:

      Turner,

      You are most welcome.

      Are you sure you want to add a custom attribute, or a property?

      Attributes can be added in this way:

      var elem = getElementByARId('spanElementA')
      var attr = document.createAttrribute('myCustomAttribute');
      attr.value = 'The value of the custom attribute';
      elem.setAttributeNode(attr);

      Properties can be added automatically simply by referencing them:

      var elem = getElementByARId('spanElementA')
      elem.myCustomProperty = 'The value of the custom property';

  2. Pingback: How to Set an Active Report Variable in JavaScript | Bob's Business Intelligence Blog

  3. Ray says:

    Thanks for this workaround solution.
    I’m trying to do this approach in order to get innerHTML property for some of the visualizations, but I haven’t had much success.

    Do you know how we can get values that are displayed in report from visualizations using javascript. Is that even possible?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: