Quickie – Dynamic select and search size

Generally the select box of the Select and Search prompt is wide enough to display all the information you need. But there are times where you need it to show everything.

Is the first option there Chaun Yang Sport Equipment Company? Org? IBM does have a way to fix this issue, but it involves modifying one of the internals, specifically the webcontentpromptingproperties.js file. In several of my clients, modifying any internal files is expressly forbidden. So I’ve written a quick and somewhat dirty javascript to handle it.

Drag an HTML item to the left of the prompt:

<div id="selectSearch">

Drag an HTML item to the right of the prompt:

</div>
<script>
  var e=document.getElementById('selectSearch');
  var myselect = e.getElementsByTagName('select')[0];
  if(myselect.childNodes.length>0){myselect.style.width=''}
</script>

This code will find the selectSearch div you wrapped the prompt with, find all of the select tags, and if there are any options the select will expand or shrink to fit.

And finally, as usual (when I remember) the report XML:

<report xmlns="http://developer.cognos.com/schemas/report/8.0/" useStyleVersion="10" expressionLocale="en-us">
				<modelPath>/content/folder[@name='Samples']/folder[@name='Models']/package[@name='GO Data Warehouse (query)']/model[@name='model']</modelPath>
				<drillBehavior modelBasedDrillThru="true"/>
				<layouts>
					<layout>
						<reportPages>
							<page name="Page1">
								<style>
									<defaultStyles>
										<defaultStyle refStyle="pg"/>
									</defaultStyles>
								</style>
								<pageBody>
									<style>
										<defaultStyles>
											<defaultStyle refStyle="pb"/>
										</defaultStyles>
									</style>
									<contents><HTMLItem>
			<dataSource>
				<staticValue>&lt;div id="selectSearch"&gt;</staticValue>
			</dataSource>
		</HTMLItem><selectWithSearch parameter="Parameter1" refQuery="Query1"><useItem refDataItem="Retailer"/></selectWithSearch><HTMLItem>
			<dataSource>
				<staticValue>&lt;/div&gt;
&lt;script&gt;
  var e=document.getElementById('selectSearch');
  var myselect = e.getElementsByTagName('select')[0];
  if(myselect.childNodes.length&gt;0){myselect.style.width=''}
&lt;/script&gt;</staticValue>
			</dataSource>
		</HTMLItem></contents>
								</pageBody>
							</page>
						</reportPages>
					</layout>
				</layouts>
			<XMLAttributes><XMLAttribute name="RS_CreateExtendedDataItems" value="false" output="no"/><XMLAttribute name="listSeparator" value="," output="no"/><XMLAttribute name="RS_modelModificationTime" value="2011-06-09T13:50:33.233Z" output="no"/></XMLAttributes><queries><query name="Query1"><source><model/></source><selection><dataItem name="Retailer" aggregate="none"><expression>[Sales (query)].[Retailers].[Retailer]</expression></dataItem></selection></query></queries></report>

The XML is for Cognos 10, but this code was tested successfully on all the flavors of Cognos 8.4.

Accessing Tree Prompts with Javascript (on Cognos 10.1.1)

There are many reasons why you may want to interact with a Tree Prompt with JavaScript. Maybe you want to enable the finish button if a member on the bottom level is selected, or to select the last member, or to ensure only 5 members are selected.

This post isn’t to detail every possible scenario, but to detail the some functions available and how to use them. It’s important to note that I am hardly a JavaScript expert, so there may be better ways to do anything I say here.

First you need to identify your tree prompt. Unlike most prompt controls, where the identifier changes based on the type viewer being used, the tree prompt can be called using window.treePROMPTNAME. Unfortunately we can’t apply an onmousedown event to the tree prompt, so we have to wrap it in a div.

Createa tree prompt and give it the name “Time”. Drag an HTML item to the left of the tree prompt

<div id='myTree'>

and an HTML item to the right

</div>

.

Now we can attach an event to capture the clicks:

<script>
document.getElementById('myTree').onmousedown=function(){runTree('Time')};
</script>

Any click inside that div will now trigger the runTree function passing ‘Time’ as an argument.

Because there are a number of JavaScript functions are run upon selecting an element we can’t immediately get the value of the element. So we can use the setTimeout function to wait 200 milliseconds before getting the data.

<script>
function runTree(id)
{
 t=setTimeout('checkTree("'+id+'")',200);
}
</script>

After 200 milliseconds the checkTree function will run, also passing Time as the argument.

<script>
function checkTree(id)
{
  selectedTreeNode  = window['tree'+id].getLastSelectedNode();
  if(!selectedTreeNode) {return}
  alert(selectedTreeNode.getName());
  alert(selectedTreeNode.getValue());
  alert(selectedTreeNode.getLevel());

}
</script>

The checkTree function will now alert the selected elements Name, MUN, and Tree level. Note the Tree Level is from the tree prompt, not the member’s hierarchy level. But knowing these, we can then call other functions. You could check the level number of the selected element and enable or disable the tree prompt while popping up a message.

You can programmatically set the default value of the tree prompt using JavaScript. Unfortunately it appears it is only possible to do this on the first level.

<script>
var node = window.treeTime.getRootNode().getChildren()[window.treeTime.getRootNode().getChildren().length-1];
node.setSelected(true);
node.updateNodeSelection();
node.updateParent();
window.treeTime.setLastSelectedNode(node);
</script>

This will only effect the prompt after the page has been loaded. Prompt pages should be fine, but prompts on the report page will need to have a default value set in the prompt macro.

I learned about these functions by going through the js file associated with tree prompts. Check out ..webcontentpromptingCTreeIE5NS6.js for more Tree Prompt functions.

It worth noting that these functions are written by IBM, and are liable to change on upgrade. I’d be interested in hearing if these work in any of the previous versions of Cognos.

JavaScript stopped working in Cognos portal

Today I got a call from a friend. Shortly before going to production it was noticed that a report that works flawlessly from Report Studio, and from clicking on the report link in the portal, doesn’t work in the Cognos Portal.

The report relies on JavaScript to alter the prompts. When he runs the report from RS, everything is beautiful. Prompt headers are removed, default options are set, and everything behaves as expected. However, once the report was placedin a Cognos Viewer portlet in the portal an “Object Expected” error would be thrown every time the report was run.

It turns out there are several significant differences between the Report Viewer (from RS) and the Cogons Viewer (what’s used in the portlets). I cordially invite (okay, I’m begging. I really don’t want to go through a few thousand lines of JS.) any actual Cognos Devs to explain the differences between RV and CV.

An example of the original code:

<script language="javascript">
var f = getFormWarpRequest();
var list = f._oLstChoicesPrompt_Years;

list.remove(1);
list.remove(0);
list.removeAttribute("hasLabel");

canSubmitPrompt();
</script>

It removes the first two rows from the prompt (prompt label and the —), then removes the “hasLabel” attribute (which prevents those two rows values from being selected).

The corrected code is:

<script language="javascript">
var fW = (typeof getFormWarpRequest == "function" ? getFormWarpRequest() : document.forms["formWarpRequest"]);
if ( !fW || fW == undefined)
   { fW = ( formWarpRequest_THIS_ ? formWarpRequest_THIS_ : formWarpRequest_NS_ );}

var list = fW._oLstChoicesPrompt_Years;

list.remove(1);
list.remove(0);
list.removeAttribute("hasLabel");

canSubmitPrompt();
</script>

It was a very simple adaptation of the code found at IBM here.

This method will work in all versions from 8.3 and above (at least until they change the engine again).