Javascript drill up and down buttons

One of my more frequent requests is for a way to allow users to drill up without having to right click. Related, many developers also want a way to support both drill-throughs and drill-downs in a single click.

The way to handle this is actually fairly simple. It can be done with an inline onclick event inside an HTML item.

<img 
  src="..\hal\images\btn_arrow_up.gif" 
  onclick="
    var oCV = window['oCV'+'_THIS_'].getRV().getCV();
    oCV.getSelectionController().selectNode(this.parentNode,this.parentNode.nodeType);
    oCV.goDrillManager.rvDrillUp();" 
  onmouseover="this.style.cursor='pointer'"
/>

drill up down buttons

Stick this inside the crosstab node or list cell next to the label, make sure that drilling is enabled and test away. This behaves exactly as if you did a right-click->drill up. If drilling is disabled, this won’t do anything but select the node. This method will not override drill behaviors or security. If a user can’t right-click/drill up past a certain level, this will not let him either.

So how does this work?

The drill manager works by finding the selected node and performing the requested action on that. So whenever you click on the background of a node and it turns orange, that node has been selected. Notice that when you drill down normally, the moment before the action triggers the cell turns orange. That is the engine selecting that node before it runs the drill.

You can test this fairly easily by creating an input anywhere on the page with test drill Put that in an HTML item, run the report, highlight a node and click the button.

The next bit is getting this to work with charts. Unfortunately charts are a little more difficult. Charts themselves are composed (basically) of two parts, an image and an HTML map containing different areas. The areas are the parts of the chart that you can hover over for tooltips and click events. The map HTML of a fairly complex chart, revenue by year/product line, looks like:

<MAP class=chart_map name=RSrsvptt0 LID="rsvptt0RS">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Product line" tabIndex=-1 href="#" shape=POLY coords="352, 6, 495, 6, 495, 20, 352, 20" isChartTitle="true" ctx="11" type="legendTitle">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Product line = Camping Equipment" tabIndex=-1 href="#" shape=POLY coords="370, 20, 495, 20, 495, 36, 370, 36" ctx="5" type="legendLabel">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Product line = Mountaineering Equipment" tabIndex=-1 href="#" shape=POLY coords="370, 36, 495, 36, 495, 52, 370, 52" ctx="6" type="legendLabel">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Product line = Personal Accessories" tabIndex=-1 href="#" shape=POLY coords="370, 52, 495, 52, 495, 68, 370, 68" ctx="7" type="legendLabel">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Product line = Outdoor Protection" tabIndex=-1 href="#" shape=POLY coords="370, 68, 495, 68, 495, 84, 370, 84" ctx="8" type="legendLabel">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Product line = Golf Equipment" tabIndex=-1 href="#" shape=POLY coords="370, 84, 495, 84, 495, 100, 370, 100" ctx="9" type="legendLabel">
  <AREA class=chart_area title=Revenue tabIndex=-1 shape=POLY coords="19, 182, 19, 139, 7, 139, 7, 183, 19, 183" type="numericAxisTitle">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title=Year tabIndex=-1 href="#" shape=POLY coords="239, 344, 239, 334, 214, 334, 214, 345, 239, 345" isChartTitle="true" ctx="10" type="ordinalAxisTitle">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2010" tabIndex=-1 href="#" shape=POLY coords="148, 330, 148, 320, 122, 320, 122, 331, 148, 331" ctx="1" type="ordinalAxisLabel">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2011" tabIndex=-1 href="#" shape=POLY coords="209, 330, 209, 320, 183, 320, 183, 331, 209, 331" ctx="2" type="ordinalAxisLabel">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2012" tabIndex=-1 href="#" shape=POLY coords="269, 330, 269, 320, 243, 320, 243, 331, 269, 331" ctx="3" type="ordinalAxisLabel">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2013" tabIndex=-1 href="#" shape=POLY coords="330, 330, 330, 320, 304, 320, 304, 331, 330, 331" ctx="4" type="ordinalAxisLabel">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2013 
Product line = Golf Equipment 
Revenue = 174,740,819.29" tabIndex=-1 href="#" shape=POLY coords="341, 310, 341, 224, 332, 224, 332, 311, 341, 311" ctx="30::9::4" type="chartElement" display="174,740,819.29">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2013 
Product line = Outdoor Protection 
Revenue = 4,471,025.26" tabIndex=-1 href="#" shape=POLY coords="332, 310, 322, 308, 322, 311, 332, 311" ctx="26::8::4" type="chartElement" display="4,471,025.26">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2013 
Product line = Personal Accessories 
Revenue = 443,693,449.85" tabIndex=-1 href="#" shape=POLY coords="322, 310, 322, 90, 312, 90, 312, 311, 322, 311" ctx="22::7::4" type="chartElement" display="443,693,449.85">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2013 
Product line = Mountaineering Equipment 
Revenue = 141,520,649.70" tabIndex=-1 href="#" shape=POLY coords="312, 310, 312, 240, 302, 240, 302, 311, 312, 311" ctx="18::6::4" type="chartElement" display="141,520,649.70">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2013 
Product line = Camping Equipment 
Revenue = 352,910,329.97" tabIndex=-1 href="#" shape=POLY coords="302, 310, 302, 135, 293, 135, 293, 311, 302, 311" ctx="15::5::4" type="chartElement" display="352,910,329.97">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2012 
Product line = Golf Equipment 
Revenue = 230,110,270.55" tabIndex=-1 href="#" shape=POLY coords="281, 310, 281, 196, 271, 196, 271, 311, 281, 311" ctx="29::9::3" type="chartElement" display="230,110,270.55">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2012 
Product line = Outdoor Protection 
Revenue = 10,349,175.84" tabIndex=-1 href="#" shape=POLY coords="271, 310, 271, 306, 261, 306, 261, 311, 271, 311" ctx="25::8::3" type="chartElement" display="10,349,175.84">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2012 
Product line = Personal Accessories 
Revenue = 594,009,408.42" tabIndex=-1 href="#" shape=POLY coords="261, 310, 261, 15, 252, 15, 252, 311, 261, 311" ctx="21::7::3" type="chartElement" display="594,009,408.42">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2012 
Product line = Mountaineering Equipment 
Revenue = 161,039,823.26" tabIndex=-1 href="#" shape=POLY coords="252, 310, 252, 230, 242, 230, 242, 311, 252, 311" ctx="17::6::3" type="chartElement" display="161,039,823.26">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2012 
Product line = Camping Equipment 
Revenue = 500,382,422.83" tabIndex=-1 href="#" shape=POLY coords="242, 310, 242, 61, 232, 61, 232, 311, 242, 311" ctx="14::5::3" type="chartElement" display="500,382,422.83">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2011 
Product line = Golf Equipment 
Revenue = 168,006,427.07" tabIndex=-1 href="#" shape=POLY coords="220, 310, 220, 227, 210, 227, 210, 311, 220, 311" ctx="28::9::2" type="chartElement" display="168,006,427.07">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2011 
Product line = Outdoor Protection 
Revenue = 25,008,574.08" tabIndex=-1 href="#" shape=POLY coords="210, 310, 210, 298, 201, 298, 201, 311, 210, 311" ctx="24::8::2" type="chartElement" display="25,008,574.08">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2011 
Product line = Personal Accessories 
Revenue = 456,323,355.90" tabIndex=-1 href="#" shape=POLY coords="201, 310, 201, 83, 191, 83, 191, 311, 201, 311" ctx="20::7::2" type="chartElement" display="456,323,355.90">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2011 
Product line = Mountaineering Equipment 
Revenue = 107,099,659.94" tabIndex=-1 href="#" shape=POLY coords="191, 310, 191, 257, 181, 257, 181, 311, 191, 311" ctx="16::6::2" type="chartElement" display="107,099,659.94">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2011 
Product line = Camping Equipment 
Revenue = 402,757,573.17" tabIndex=-1 href="#" shape=POLY coords="181, 310, 181, 110, 171, 110, 171, 311, 181, 311" ctx="13::5::2" type="chartElement" display="402,757,573.17">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2010 
Product line = Golf Equipment 
Revenue = 153,553,850.98" tabIndex=-1 href="#" shape=POLY coords="159, 310, 159, 234, 150, 234, 150, 311, 159, 311" ctx="27::9::1" type="chartElement" display="153,553,850.98">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2010 
Product line = Outdoor Protection 
Revenue = 36,165,521.07" tabIndex=-1 href="#" shape=POLY coords="150, 310, 150, 293, 140, 293, 140, 311, 150, 311" ctx="23::8::1" type="chartElement" display="36,165,521.07">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2010 
Product line = Personal Accessories 
Revenue = 391,647,093.61" tabIndex=-1 href="#" shape=POLY coords="140, 310, 140, 116, 130, 116, 130, 311, 140, 311" ctx="19::7::1" type="chartElement" display="391,647,093.61">
  <AREA onmouseup=window.oCVRS.pcc(event) class="dl chart_area" title="Year = 2010 
Product line = Camping Equipment 
Revenue = 332,986,338.06" tabIndex=-1 href="#" shape=POLY coords="121, 310, 121, 145, 111, 145, 111, 311, 121, 311" ctx="12::5::1" type="chartElement" display="332,986,338.06">
</MAP>

Areas can’t be selected the same way as crosstab nodes. For one, the button can’t be placed directly into the chart. Secondly, the selectNode function won’t work on charts. No, for that we’ll need something radically different: setSelectedChartArea()

First, let’s decide what we want to drill up on. For the sake of this example, I’ll say that the users are drilling down on the time dimension in the ordinal axis. So in order to drill up, we need to isolate one of those areas. It normally doesn’t matter which one as they will all drill up to the same member (this may not always be the case, especially if you change the default drill behavior). We need to loop through the areas of the chart, and find the first area that has the type “ordinalAxisLAbel”. Once we have it, we can use the drastically different function to select it.

Since the button doesn’t exist inside the chart, we also need a way to find the chart element on the page. Fortunately there is a Cognos function for that. getLayoutElementFromLid works just like getElementById. Except just for Cognos objects. And when using it, you have to remember to specify the namespace you’re working in. So not like getElementById at all. Using getLayoutElementFromLid will return the actual image of the chart, so to get the areas we have to go two nodes up.

var oCV = window['oCV'+'_THIS_'].getRV().getCV()
  , areas = oCV.getLayoutElementFromLid('ChartName'+'_THIS_').parentNode.parentNode.getElementsByTagName('AREA')  ;

for(var i = 0;i<areas.length;i++){
  if ( areas[i].getAttribute('type')=='ordinalAxisLabel') 
  {
    oCV.getSelectionController().setSelectedChartArea(areas[i]);
    oCV.goDrillManager.rvDrillUp();break;
  }

}

Stick that into the onclick event of an element, and it will drill up on the first ordinal area it finds in your chart.

This should, in theory, work in previous versions of Cognos. It works perfectly in 10.1.1 (switch _THIS_ with the correct namespace (RS for running from Report Studio or _NS_ for running from connection or in a portlet)), but unfortunately I don’t have access to any prior versions to test.

Below is the report XML. You can downgrade this to 10.1 fairly easily by changing /report/9.0/ to /report/8.0/.

<report xmlns="http://developer.cognos.com/schemas/report/9.0/" useStyleVersion="10" expressionLocale="en-us">
				<modelPath>/content/folder[@name='Samples']/folder[@name='Cubes']/package[@name='Sales and Marketing (cube)']/model[@name='2008-07-25T15:28:38.072Z']</modelPath>
				
				<layouts>
					<layout>
						<reportPages>
							<page name="Page1">
								<style>
									<defaultStyles>
										<defaultStyle refStyle="pg"/>
									</defaultStyles>
								</style>
								<pageBody>
									<style>
										<defaultStyles>
											<defaultStyle refStyle="pb"/>
										</defaultStyles>
									</style>
									<contents><v2_combinationChart maxHotspots="10000" refQuery="Query1" name="MyChart">
								<v2_combinationTypeTooltips/>
								<v2_legend>
									<v2_legendPosition>
										<v2_legendPreset/>
									</v2_legendPosition>
									<v2_legendTitle refQuery="Query1">
										<v2_chartTextContents>
											<v2_automaticText/>
										</v2_chartTextContents>
										<style>
											<defaultStyles>
												<defaultStyle refStyle="lx"/>
											</defaultStyles>
										</style>
									</v2_legendTitle>
									<style>
										<defaultStyles>
											<defaultStyle refStyle="lg"/>
										</defaultStyles>
									</style>
								</v2_legend>
								<v2_commonAxis>
									<v2_ordinalAxis>
										<v2_axisTitle refQuery="Query1">
											<v2_chartTextContents>
												<v2_automaticText/>
											</v2_chartTextContents>
											<style>
												<defaultStyles>
													<defaultStyle refStyle="at"/>
												</defaultStyles>
											</style>
										</v2_axisTitle>
										<v2_axisLine lineWeight="0"/>
										<v2_axisLabels>
											<style>
												<defaultStyles>
													<defaultStyle refStyle="al"/>
												</defaultStyles>
											</style>
										</v2_axisLabels>
									</v2_ordinalAxis>
									<chartNodes><chartNode><chartNodeMembers><chartNodeMember refDataItem="Year"><chartContents><chartTextItem><dataSource><memberCaption/></dataSource></chartTextItem></chartContents></chartNodeMember></chartNodeMembers></chartNode></chartNodes></v2_commonAxis>
								<v2_topLeftAxis>
									<v2_combinationChartTypes>
										<v2_bar borders="show">
											<v2_solidPalette>
												<v2_solidPaletteEntries>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#8599D3">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#8599D3"/>
																<v2_gradientColor colorPosition="100" gradientColor="#5876AE"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#E3AE6C">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#E3AE6C"/>
																<v2_gradientColor colorPosition="100" gradientColor="#CD854E"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#839862">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#839862"/>
																<v2_gradientColor colorPosition="100" gradientColor="#6C7F56"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#B7C873">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#B7C873"/>
																<v2_gradientColor colorPosition="100" gradientColor="#AFB885"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#8484A8">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#8484A8"/>
																<v2_gradientColor colorPosition="100" gradientColor="#525E7E"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#C0CCED">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#C0CCED"/>
																<v2_gradientColor colorPosition="100" gradientColor="#B0C2E5"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#8C5580">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#8C5580"/>
																<v2_gradientColor colorPosition="100" gradientColor="#794067"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#C789BC">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#C789BC"/>
																<v2_gradientColor colorPosition="100" gradientColor="#BB72BC"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#D5BAEF">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#D5BAEF"/>
																<v2_gradientColor colorPosition="100" gradientColor="#C29FD1"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#83683F">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#83683F"/>
																<v2_gradientColor colorPosition="100" gradientColor="#604926"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#DCB05A">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#DCB05A"/>
																<v2_gradientColor colorPosition="100" gradientColor="#C09C52"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#F4DF9E">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#F4DF9E"/>
																<v2_gradientColor colorPosition="100" gradientColor="#E4CF87"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#5F8A8C">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#5F8A8C"/>
																<v2_gradientColor colorPosition="100" gradientColor="#537579"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#96C4B2">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#96C4B2"/>
																<v2_gradientColor colorPosition="100" gradientColor="#89B0A0"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#CBE8E7">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#CBE8E7"/>
																<v2_gradientColor colorPosition="100" gradientColor="#BDD6D5"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#AE6564">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#AE6564"/>
																<v2_gradientColor colorPosition="100" gradientColor="#875352"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#D88C6F">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#D88C6F"/>
																<v2_gradientColor colorPosition="100" gradientColor="#C47D61"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#E3C9B0">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#E3C9B0"/>
																<v2_gradientColor colorPosition="100" gradientColor="#D2B2A5"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#848484">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#848484"/>
																<v2_gradientColor colorPosition="100" gradientColor="#555555"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#a4a4a4">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#a4a4a4"/>
																<v2_gradientColor colorPosition="100" gradientColor="#909090"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
													<v2_solidPaletteEntry>
														<v2_fillEffect defaultColor="#C7C7C7">
															<v2_linearGradient gradientAngle="0">
																<v2_gradientColor colorPosition="0" gradientColor="#C7C7C7"/>
																<v2_gradientColor colorPosition="100" gradientColor="#c1c1c1"/>
															</v2_linearGradient>
														</v2_fillEffect>
													</v2_solidPaletteEntry>
												</v2_solidPaletteEntries>
											</v2_solidPalette>
											<!-- v2_solidPaletteRef ref="gDefaultSolid"/ -->
										<chartNodes><chartNode><chartNodeMembers><chartNodeMember refDataItem="Product line"><chartContents><chartTextItem><dataSource><memberCaption/></dataSource></chartTextItem></chartContents></chartNodeMember></chartNodeMembers></chartNode></chartNodes></v2_bar>
									</v2_combinationChartTypes>
									<v2_axis>
										<v2_axisTitle refQuery="Query1">
											<v2_chartTextContents>
												<v2_automaticText/>
											</v2_chartTextContents>
											<style>
												<defaultStyles>
													<defaultStyle refStyle="at"/>
												</defaultStyles>
											</style>
										</v2_axisTitle>
										<v2_axisLine lineWeight="0"/>
										<v2_axisRange>
											<v2_automaticRange/>
										</v2_axisRange>
										<v2_axisLabels>
											<style>
												<defaultStyles>
													<defaultStyle refStyle="al"/>
												</defaultStyles>
											</style>
										</v2_axisLabels>
										<v2_majorGridlines lineWeight="0" lineColor="#CCCCCC"/>
										<v2_majorBackgroundColors>
											<v2_firstBackgroundColor color="#D2D2D2" transparency="50"/>
											<v2_secondBackgroundColor color="#E2E2E2" transparency="50"/>
										</v2_majorBackgroundColors>
									</v2_axis>
								</v2_topLeftAxis>
								<style>
									<defaultStyles>
										<defaultStyle refStyle="ch"/>
									</defaultStyles>
								</style>
								<noDataHandler>
									<contents>
										<block>
											<contents>
												<textItem>
													<dataSource>
														<staticValue>No Data Available</staticValue>
													</dataSource>
													<style>
														<CSS value="padding:10px 18px;"/>
													</style>
												</textItem>
											</contents>
										</block>
									</contents>
								</noDataHandler>
								<v2_defaultChartMeasure refDataItem="Revenue"/></v2_combinationChart>
							<HTMLItem>
			<dataSource>
				<staticValue>&lt;input type="button" onclick="
var oCV = window['oCV'+'_THIS_'].getRV().getCV()
  , areas = oCV.getLayoutElementFromLid('MyChart'+'_THIS_').parentNode.parentNode.getElementsByTagName('AREA')  ;

for(var i = 0;i&lt;areas.length;i++){
  if ( areas[i].getAttribute('type')=='ordinalAxisLabel') 
  {
    oCV.getSelectionController().setSelectedChartArea(areas[i]);
    oCV.goDrillManager.rvDrillUp();break;
  }

}
" value="Drill up chart"/&gt;</staticValue>
			</dataSource>
		</HTMLItem><list horizontalPagination="true" name="List1" refQuery="Query1">
			
			
			
			<noDataHandler>
				<contents>
					<block>
						<contents>
							<textItem>
								<dataSource>
									<staticValue>No Data Available</staticValue>
								</dataSource>
								<style>
									<CSS value="padding:10px 18px;"/>
								</style>
							</textItem>
						</contents>
					</block>
				</contents>
			</noDataHandler>
			<style>
				<CSS value="border-collapse:collapse"/>
				<defaultStyles>
					<defaultStyle refStyle="ls"/>
				</defaultStyles>
			</style>
		<listColumns><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Year"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lc"/></defaultStyles></style><contents><HTMLItem description="drillUp">
			<dataSource>
				<staticValue>&lt;img src="..\hal\images\btn_arrow_up.gif" onclick="var oCV = window['oCV'+'_THIS_'].getRV().getCV();oCV.getSelectionController().selectNode(this.parentNode);oCV.goDrillManager.rvDrillUp();" onmouseover="this.style.cursor='pointer'"/&gt;</staticValue>
			</dataSource>
		</HTMLItem><textItem><dataSource><dataItemValue refDataItem="Year"/></dataSource></textItem><HTMLItem description="drillDown">
			<dataSource>
				<staticValue>&lt;img src="..\hal\images\btn_arrow_down.gif" onclick="var oCV = window['oCV'+'_THIS_'].getRV().getCV();oCV.getSelectionController().selectNode(this.parentNode);oCV.goDrillManager.rvDrillDown();" onmouseover="this.style.cursor='pointer'"/&gt;</staticValue>
			</dataSource>
		</HTMLItem></contents></listColumnBody></listColumn></listColumns></list><crosstab horizontalPagination="true" name="Crosstab1" refQuery="Query1">
			<crosstabCorner>
				<contents/>
				<style>
					<defaultStyles>
						<defaultStyle refStyle="xm"/>
					</defaultStyles>
				</style>
			</crosstabCorner>
			
			
			<noDataHandler>
				<contents>
					<block>
						<contents>
							<textItem>
								<dataSource>
									<staticValue>No Data Available</staticValue>
								</dataSource>
								<style>
									<CSS value="padding:10px 18px;"/>
								</style>
							</textItem>
						</contents>
					</block>
				</contents>
			</noDataHandler>
			<style>
				<CSS value="border-collapse:collapse"/>
				<defaultStyles>
					<defaultStyle refStyle="xt"/>
				</defaultStyles>
			</style>
		<crosstabRows><crosstabNode><crosstabNestedNodes><crosstabNode><crosstabNodeMembers><crosstabNodeMember refDataItem="Product line" edgeLocation="e2"><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style><contents><HTMLItem description="drillUp">
			<dataSource>
				<staticValue>&lt;img src="..\hal\images\btn_arrow_up.gif" onclick="var oCV = window['oCV'+'_THIS_'].getRV().getCV();oCV.getSelectionController().selectNode(this.parentNode);oCV.goDrillManager.rvDrillUp();" onmouseover="this.style.cursor='pointer'"/&gt;</staticValue>
			</dataSource>
		</HTMLItem><textItem><dataSource><memberCaption/></dataSource></textItem><HTMLItem description="drillDown">
			<dataSource>
				<staticValue>&lt;img src="..\hal\images\btn_arrow_down.gif" onclick="var oCV = window['oCV'+'_THIS_'].getRV().getCV();oCV.getSelectionController().selectNode(this.parentNode);oCV.goDrillManager.rvDrillDown();" onmouseover="this.style.cursor='pointer'"/&gt;</staticValue>
			</dataSource>
		</HTMLItem></contents></crosstabNodeMember></crosstabNodeMembers></crosstabNode></crosstabNestedNodes><crosstabNodeMembers><crosstabNodeMember refDataItem="Year" edgeLocation="e1"><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style><contents><HTMLItem description="drillUp">
			<dataSource>
				<staticValue>&lt;img src="..\hal\images\btn_arrow_up.gif" onclick="var oCV = window['oCV'+'_THIS_'].getRV().getCV();oCV.getSelectionController().selectNode(this.parentNode);oCV.goDrillManager.rvDrillUp();" onmouseover="this.style.cursor='pointer'"/&gt;</staticValue>
			</dataSource>
		</HTMLItem><textItem><dataSource><memberCaption/></dataSource><reportDrills><reportDrill name="Drill-Through Definition1"><drillLabel><dataSource><staticValue/></dataSource></drillLabel><drillTarget method="execute" showInNewWindow="true"><reportPath path="CAMID(&quot;OpenDJ:u:cn=administrator&quot;)/folder[@name='My Folders']/report[@name='test drill down']"><XMLAttributes><XMLAttribute name="ReportName" value="test drill down" output="no"/><XMLAttribute name="class" value="report" output="no"/></XMLAttributes></reportPath></drillTarget></reportDrill></reportDrills><style><defaultStyles><defaultStyle refStyle="hy"/></defaultStyles></style></textItem><HTMLItem description="drillDown">
			<dataSource>
				<staticValue>&lt;img src="..\hal\images\btn_arrow_down.gif" onclick="var oCV = window['oCV'+'_THIS_'].getRV().getCV();oCV.getSelectionController().selectNode(this.parentNode);oCV.goDrillManager.rvDrillDown();" onmouseover="this.style.cursor='pointer'"/&gt;</staticValue>
			</dataSource>
		</HTMLItem></contents></crosstabNodeMember></crosstabNodeMembers></crosstabNode></crosstabRows><crosstabFactCell><contents><HTMLItem description="drillUp">
			<dataSource>
				<staticValue>&lt;img src="..\hal\images\btn_arrow_up.gif" onclick="var oCV = window['oCV'+'_THIS_'].getRV().getCV();oCV.getSelectionController().selectNode(this.parentNode);oCV.goDrillManager.rvDrillUp();" onmouseover="this.style.cursor='pointer'"/&gt;</staticValue>
			</dataSource>
		</HTMLItem><textItem><dataSource><cellValue/></dataSource></textItem><HTMLItem description="drillDown">
			<dataSource>
				<staticValue>&lt;img src="..\hal\images\btn_arrow_down.gif" onclick="var oCV = window['oCV'+'_THIS_'].getRV().getCV();oCV.getSelectionController().selectNode(this.parentNode);oCV.goDrillManager.rvDrillDown();" onmouseover="this.style.cursor='pointer'"/&gt;</staticValue>
			</dataSource>
		</HTMLItem></contents><style><defaultStyles><defaultStyle refStyle="mv"/></defaultStyles></style></crosstabFactCell><defaultMeasure refDataItem="Revenue"/><crosstabColumns><crosstabNode><crosstabNodeMembers><crosstabNodeMember refDataItem="Region" edgeLocation="e3"><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style><contents><HTMLItem description="drillUp">
			<dataSource>
				<staticValue>&lt;img src="..\hal\images\btn_arrow_up.gif" onclick="var oCV = window['oCV'+'_THIS_'].getRV().getCV();oCV.getSelectionController().selectNode(this.parentNode);oCV.goDrillManager.rvDrillUp();" onmouseover="this.style.cursor='pointer'"/&gt;</staticValue>
			</dataSource>
		</HTMLItem><textItem><dataSource><memberCaption/></dataSource></textItem><HTMLItem description="drillDown">
			<dataSource>
				<staticValue>&lt;img src="..\hal\images\btn_arrow_down.gif" onclick="var oCV = window['oCV'+'_THIS_'].getRV().getCV();oCV.getSelectionController().selectNode(this.parentNode);oCV.goDrillManager.rvDrillDown();" onmouseover="this.style.cursor='pointer'"/&gt;</staticValue>
			</dataSource>
		</HTMLItem></contents></crosstabNodeMember></crosstabNodeMembers></crosstabNode></crosstabColumns></crosstab></contents>
								</pageBody>
							</page>
						</reportPages>
					</layout>
				</layouts>
			<XMLAttributes><XMLAttribute name="RS_CreateExtendedDataItems" value="true" output="no"/><XMLAttribute name="listSeparator" value="," output="no"/><XMLAttribute name="RS_modelModificationTime" value="2008-07-25T15:28:38.133Z" output="no"/></XMLAttributes><queries><query name="Query1"><source><model/></source><selection><dataItemLevelSet name="Year"><dmLevel><LUN>[sales_and_marketing].[Time].[Time].[Year]</LUN><itemCaption>Year</itemCaption></dmLevel><dmDimension><DUN>[sales_and_marketing].[Time]</DUN><itemCaption>Time</itemCaption></dmDimension><dmHierarchy><HUN>[sales_and_marketing].[Time].[Time]</HUN><itemCaption>Time</itemCaption></dmHierarchy></dataItemLevelSet><dataItemLevelSet name="Product line"><dmLevel><LUN>[sales_and_marketing].[Products].[Products].[Product line]</LUN><itemCaption>Product line</itemCaption></dmLevel><dmDimension><DUN>[sales_and_marketing].[Products]</DUN><itemCaption>Products</itemCaption></dmDimension><dmHierarchy><HUN>[sales_and_marketing].[Products].[Products]</HUN><itemCaption>Products</itemCaption></dmHierarchy></dataItemLevelSet><dataItemMeasure name="Revenue"><dmMember><MUN>[sales_and_marketing].[Measures].[Revenue]</MUN><itemCaption>Revenue</itemCaption></dmMember><dmDimension><DUN>[sales_and_marketing].[Measures]</DUN><itemCaption>Measures</itemCaption></dmDimension><XMLAttributes><XMLAttribute name="RS_dataType" value="9" output="no"/></XMLAttributes></dataItemMeasure><dataItemLevelSet name="Region"><dmLevel><LUN>[sales_and_marketing].[Retailers].[Retailers].[Region]</LUN><itemCaption>Region</itemCaption></dmLevel><dmDimension><DUN>[sales_and_marketing].[Retailers]</DUN><itemCaption>Retailers</itemCaption></dmDimension><dmHierarchy><HUN>[sales_and_marketing].[Retailers].[Retailers]</HUN><itemCaption>Retailers</itemCaption></dmHierarchy></dataItemLevelSet></selection></query></queries><reportName>test drill down</reportName><drillBehavior drillUpDown="true" modelBasedDrillThru="true"/></report>

Manipulate drill through definitions with JavaScript

This article is based on 10.2, and uses the 10.2 Prompt API. It can be easily adapted to earlier versions however.

When defining a drillthrough you can set various settings as report target, output format, locales and more. Unfortunately there is no easy way to change those settings on the fly. On the other hand, I just did all the work so now there is an easy way.

Drillthrough definitions come in two basic parts. The second part, which won’t be delved into in this article, has the actual values being passed. These can be seen in the links themselves.
drillthrough HTML
Looking at the code itself (modified for legibility):

<SPAN 
  dtTargets='
    <drillTarget 
      drillIdx=\"0\" 
      label=\"DrillThrough\">
      <drillParameter 
        name=\"Product Line\" 
        value=\"[sales_and_marketing].[Products].[Products].[Product line]-&amp;gt;:[PC].[@MEMBER].[991]\" 
        displayValue=\"Camping Equipment\"/>
      <drillParameter 
        name=\"Year\" 
        value=\"[sales_and_marketing].[Time].[Time].[Year]-&amp;gt;:[PC].[@MEMBER].[20100101-20101231]\" 
        displayValue=\"2010\"/>
    <\/drillTarget>'>
  <SPAN class=hy tabIndex=-1>
    81,929,179.22
  </SPAN>
</SPAN>

This can be modified by looping through with JavaScript fairly easily, but I’ll leave that for another time.

The first part describes the actual settings – the metadata of the drill. This is stored in JavaScript object in the page, which makes it significantly easier to modify. Stringifying the object returns (again, modified for legibility):

[
  {"m_label":"DrillThrough"
  ,"m_outputFormat":"HTMLFragment"
  ,"m_outputLocale":"en-us"
  ,"m_showInNewWindow":"true"
  ,"m_method":"execute"
  ,"m_path":"/content/folder[@name='JavaScript Examples']/folder[@name='Modifying Drillthrough Definitions']/report[@name='Drill 1']"
  ,"m_bookmark":""
  ,"m_parameters":"<bus:parameters xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"bus:baseParameter[2]\"><item xsi:type=\"bus:parameter\"><bus:name xsi:type=\"xs:string\">Product Line</bus:name><bus:type xsi:type=\"bus:parameterDataTypeEnum\">memberUniqueName</bus:type></item><item xsi:type=\"bus:parameter\"><bus:name xsi:type=\"xs:string\">Year</bus:name><bus:type xsi:type=\"bus:parameterDataTypeEnum\">memberUniqueName</bus:type></item></bus:parameters>"
  ,"m_objectPaths":"<bus:objectPaths xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"bus:searchPathSingleObject[4]\"><item xsi:type=\"bus:searchPathSingleObject\">storeID(&quot;i326070F7595B4B5BBCD38D945E66AAEB&quot;)</item><item xsi:type=\"bus:searchPathSingleObject\">storeID(&quot;iDB36CF1A0D654E99B3117B0B6A7F8789&quot;)/model[last()]</item><item xsi:type=\"bus:searchPathSingleObject\">/content/folder[@name=&apos;Samples&apos;]/folder[@name=&apos;Cubes&apos;]/package[@name=&apos;Sales and Marketing (cube)&apos;]/model[@name=&apos;2008-07-25T15:28:38.072Z&apos;]</item><item xsi:type=\"bus:searchPathSingleObject\">/content/folder[@name=&apos;Samples&apos;]/folder[@name=&apos;Cubes&apos;]/package[@name=&apos;Sales and Marketing (cube)&apos;]/model[last()]</item></bus:objectPaths>"
  ,"m_prompt":"false"
  ,"m_dynamicDrillThrough":false
  ,"m_parameterProperties":"<PARAMETER-PROPERTIES/>"}
  ,
  {"m_label":"DrillThrough"
  ,"m_outputFormat":"HTMLFragment"
  ,"m_outputLocale":"en-us"
  ,"m_showInNewWindow":"true"
  ,"m_method":"execute"
  ,"m_path":"/content/folder[@name='JavaScript Examples']/folder[@name='Modifying Drillthrough Definitions']/report[@name='Drill 1']"
  ,"m_bookmark":""
  ,"m_parameters":"<bus:parameters xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"bus:baseParameter[2]\"><item xsi:type=\"bus:parameter\"><bus:name xsi:type=\"xs:string\">Product Line</bus:name><bus:type xsi:type=\"bus:parameterDataTypeEnum\">memberUniqueName</bus:type></item><item xsi:type=\"bus:parameter\"><bus:name xsi:type=\"xs:string\">Year</bus:name><bus:type xsi:type=\"bus:parameterDataTypeEnum\">memberUniqueName</bus:type></item></bus:parameters>"
  ,"m_objectPaths":"<bus:objectPaths xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"bus:searchPathSingleObject[4]\"><item xsi:type=\"bus:searchPathSingleObject\">storeID(&quot;i326070F7595B4B5BBCD38D945E66AAEB&quot;)</item><item xsi:type=\"bus:searchPathSingleObject\">storeID(&quot;iDB36CF1A0D654E99B3117B0B6A7F8789&quot;)/model[last()]</item><item xsi:type=\"bus:searchPathSingleObject\">/content/folder[@name=&apos;Samples&apos;]/folder[@name=&apos;Cubes&apos;]/package[@name=&apos;Sales and Marketing (cube)&apos;]/model[@name=&apos;2008-07-25T15:28:38.072Z&apos;]</item><item xsi:type=\"bus:searchPathSingleObject\">/content/folder[@name=&apos;Samples&apos;]/folder[@name=&apos;Cubes&apos;]/package[@name=&apos;Sales and Marketing (cube)&apos;]/model[last()]</item></bus:objectPaths>"
  ,"m_prompt":"false"
  ,"m_dynamicDrillThrough":false
  ,"m_parameterProperties":"<PARAMETER-PROPERTIES/>"}]

Each of these settings is easily changed (except for the the m_parameters and m_parameterProperties because that means changing the settings on the actual drills themselves). People with sharp eyes may notice that both drillthrough definitions are exactly the same. Why does it appear twice? The drillthrough appears twice in my report’s crosstab. The definition appears for the detail row and again for the totals row. If I was passing the individual month with the detail, then the first drillthrough in the object would include the month.

Because the drills can appear twice, any function written to rewrite the settings must include a loop to check the m_label in each element.

Consider the following:

<script>
var paulScripts = {},  oCR = cognos.Report.getReport( "_THIS_" );

paulScripts.getControl = function (promptName) {
  return oCR.prompt.getControlByName(promptName);
}

/*
 * function: changeDrillAttribute
 * By Paul Mendelson
 * This allows the user to change any attribute in the drill. Attributes may be:
 * m_label, m_outputFormat, m_outputLocale, m_showInNewWindow, m_method, m_path, 
 * m_bookmark, m_parameters, m_objectPaths, m_prompt, m_dynamicDrillThrough, 
 * m_parameterProperties
 * Drills may appear multiple times in the object, so the loop goes through the entire array. Each 
 * matching drill will have the attribute changed as desired.
 * Valid m_outputFormat:  CSV, HTML, layoutDataXML, MHT,  PDF, rawXML, singleXLS, spreadsheetML, XLS, 
 * XML, XLWA.
 * m_path: /content/folder[@name='folderName']/folder[@name='folderName']/report[@name='reportName']
 */

paulScripts.changeDrillAttribute = function (drillName,attribute,newValue){
  var oCV = window['oCV'+'_THIS_']
  , drillsObj = oCV.getRV().getCV().getDrillTargets();

  for(var i=0;i<drillsObj.length;i++){
   if( drillsObj[i].m_label == drillName) drillsObj[i][attribute] = newValue;
  }
}

</script>

paulScripts.changeDrillAttribute function will receive the name of the drill, the attribute to change, and the new value of that attribute. It will then loop through all of the elements in the drill targets, and if the label matches, change the attribute.

The following screenshot shows the crosstab containing the drill, and two radio button groups.
radios can change the drill

The radios have a validator set on them to invoke the changeDrillAttribute function.

<script>
paulScripts.getControl('Format').setValidator(
  function (values) {
  paulScripts.changeDrillAttribute ('DrillThrough','m_outputFormat',values[0].use);
  return true;
  }
);

paulScripts.getControl('Target').setValidator(
  function (values) {
  paulScripts.changeDrillAttribute ('DrillThrough','m_path',values[0].use);
  return true;
  }
);

</script>

Whenever the radio is changed, it will modify the drill appropriately. That setValidator function is the only use of the new Prompt API, so this can be changed very easily to previous versions by using onChange events.

Ultimately the end user can decide which report he wants to drill to, and in what format, without having to right-click. Because users don’t like right-clicking.

The following XML is the report. Remember to create two targets for the drill and to fix the value prompt. To get the path of the report, simply go to the properties of the report, click on “View the search path, ID and URL” and copy the search path.

<report xmlns="http://developer.cognos.com/schemas/report/9.0/" useStyleVersion="10" expressionLocale="en-us">
				<modelPath>/content/folder[@name='Samples']/folder[@name='Cubes']/package[@name='Sales and Marketing (cube)']/model[@name='2008-07-25T15:28:38.072Z']</modelPath>
				<drillBehavior modelBasedDrillThru="true"/>
				<queries>
					<query name="Query1">
						<source>
							<model/>
						</source>
						<selection><dataItemLevelSet name="Year"><dmLevel><LUN>[sales_and_marketing].[Time].[Time].[Year]</LUN><itemCaption>Year</itemCaption></dmLevel><dmDimension><DUN>[sales_and_marketing].[Time]</DUN><itemCaption>Time</itemCaption></dmDimension><dmHierarchy><HUN>[sales_and_marketing].[Time].[Time]</HUN><itemCaption>Time</itemCaption></dmHierarchy></dataItemLevelSet><dataItemLevelSet name="Quarter"><dmLevel><LUN>[sales_and_marketing].[Time].[Time].[Quarter]</LUN><itemCaption>Quarter</itemCaption></dmLevel><dmDimension><DUN>[sales_and_marketing].[Time]</DUN><itemCaption>Time</itemCaption></dmDimension><dmHierarchy><HUN>[sales_and_marketing].[Time].[Time]</HUN><itemCaption>Time</itemCaption></dmHierarchy></dataItemLevelSet><dataItemLevelSet name="Product line"><dmLevel><LUN>[sales_and_marketing].[Products].[Products].[Product line]</LUN><itemCaption>Product line</itemCaption></dmLevel><dmDimension><DUN>[sales_and_marketing].[Products]</DUN><itemCaption>Products</itemCaption></dmDimension><dmHierarchy><HUN>[sales_and_marketing].[Products].[Products]</HUN><itemCaption>Products</itemCaption></dmHierarchy></dataItemLevelSet><dataItemMeasure name="Revenue"><dmMember><MUN>[sales_and_marketing].[Measures].[Revenue]</MUN><itemCaption>Revenue</itemCaption></dmMember><dmDimension><DUN>[sales_and_marketing].[Measures]</DUN><itemCaption>Measures</itemCaption></dmDimension><XMLAttributes><XMLAttribute name="RS_dataType" value="9" output="no"/></XMLAttributes></dataItemMeasure></selection>
					</query>
				</queries>
				<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;script&gt;
var paulScripts = {},  oCR = cognos.Report.getReport( "_THIS_" );

paulScripts.getControl = function (promptName) {
  return oCR.prompt.getControlByName(promptName);
}

/*
 * function: changeDrillAttribute
 * Paul Mendelson
 * This allows the user to change any attribute in the drill. Attributes may be:
 *   m_label, m_outputFormat, m_outputLocale, m_showInNewWindow, m_method, m_path, 
  * m_bookmark, m_parameters, m_objectPaths, m_prompt, m_dynamicDrillThrough, 
  * m_parameterProperties
  * Drills may appear multiple times in the object, so the loop goes through the entire array. Each 
  * matching drill will have the attribute changed as desired.
  *  Valid m_outputFormat:  CSV, HTML, layoutDataXML, MHT,  PDF, rawXML, singleXLS, spreadsheetML, XLS, 
  * XML, XLWA.
  * m_path: /content/folder[@name='folderName']/folder[@name='folderName']/report[@name='reportName']
  */

paulScripts.changeDrillAttribute = function (drillName,attribute,newValue){
  var oCV = window['oCV'+'_THIS_']
  , drillsObj = oCV.getRV().getCV().getDrillTargets();

  for(var i=0;i&lt;drillsObj.length;i++){
   if( drillsObj[i].m_label == drillName) drillsObj[i][attribute] = newValue;
  }
}

  &lt;/script&gt;
	</staticValue>
			</dataSource>
		</HTMLItem>
									<table><style><defaultStyles><defaultStyle refStyle="tb"/></defaultStyles><CSS value="border-collapse:collapse"/></style><tableRows><tableRow><tableCells><tableCell><contents><crosstab refQuery="Query1" horizontalPagination="true" name="Crosstab1">
											<crosstabCorner><style><defaultStyles><defaultStyle refStyle="xm"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Revenue"/></dataSource></textItem></contents></crosstabCorner>
											
											
											<noDataHandler>
												<contents>
													<block>
														<contents>
															<textItem>
																<dataSource>
																	<staticValue>No Data Available</staticValue>
																</dataSource>
																<style>
																	<CSS value="padding:10px 18px;"/>
																</style>
															</textItem>
														</contents>
													</block>
												</contents>
											</noDataHandler>
											<style>
												<defaultStyles>
													<defaultStyle refStyle="xt"/>
												</defaultStyles>
												<CSS value="border-collapse:collapse"/>
											</style>
										<crosstabRows><crosstabNode><crosstabNestedNodes><crosstabNode><crosstabNodeMembers><crosstabNodeMember refDataItem="Quarter" edgeLocation="e2"><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style><contents><textItem><dataSource><memberCaption/></dataSource></textItem></contents></crosstabNodeMember></crosstabNodeMembers></crosstabNode><crosstabNode><crosstabNodeMembers><crosstabNodeMember refDataItem="Year" edgeLocation="e3"><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style><contents><textItem><dataSource><memberCaption/></dataSource></textItem></contents></crosstabNodeMember></crosstabNodeMembers></crosstabNode></crosstabNestedNodes><crosstabNodeMembers><crosstabNodeMember refDataItem="Year" edgeLocation="e1"><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style><contents><textItem><dataSource><memberCaption/></dataSource></textItem></contents></crosstabNodeMember></crosstabNodeMembers></crosstabNode></crosstabRows><crosstabColumns><crosstabNode><crosstabNodeMembers><crosstabNodeMember refDataItem="Product line" edgeLocation="e4"><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style><contents><textItem><dataSource><memberCaption/></dataSource></textItem></contents></crosstabNodeMember></crosstabNodeMembers></crosstabNode></crosstabColumns><defaultMeasure refDataItem="Revenue"/><crosstabFactCell><contents><textItem><dataSource><cellValue/></dataSource><reportDrills><reportDrill name="DrillThrough"><drillLabel><dataSource><staticValue/></dataSource></drillLabel><drillTarget method="execute" showInNewWindow="true"><reportPath path="/content/folder[@name='JavaScript Examples']/folder[@name='Modifying Drillthrough Definitions']/report[@name='Drill 1']"><XMLAttributes><XMLAttribute name="ReportName" value="Drill 1" output="no"/><XMLAttribute name="class" value="report" output="no"/></XMLAttributes></reportPath><drillLinks><drillLink><drillTargetContext><parameterContext parameter="Product Line"/></drillTargetContext><drillSourceContext><dataItemContext refDataItem="Product line"/></drillSourceContext></drillLink><drillLink><drillTargetContext><parameterContext parameter="Year"/></drillTargetContext><drillSourceContext><dataItemContext refDataItem="Year"/></drillSourceContext></drillLink></drillLinks></drillTarget></reportDrill></reportDrills><style><defaultStyles><defaultStyle refStyle="hy"/></defaultStyles></style></textItem></contents><style><defaultStyles><defaultStyle refStyle="mv"/></defaultStyles></style></crosstabFactCell></crosstab></contents></tableCell><tableCell><contents><table><style><defaultStyles><defaultStyle refStyle="tb"/></defaultStyles><CSS value="border-collapse:collapse"/></style><tableRows><tableRow><tableCells><tableCell><contents><selectValue parameter="Format" selectValueUI="radioGroup" name="Format"><selectOptions><selectOption useValue="PDF"/><selectOption useValue="spreadsheetML"/><selectOption useValue="HTMLFragment"/><selectOption useValue="HTML"/></selectOptions><defaultSelections><defaultSimpleSelection>HTMLFragment</defaultSimpleSelection></defaultSelections></selectValue></contents></tableCell></tableCells></tableRow><tableRow><tableCells><tableCell><contents><selectValue parameter="Target" name="Target" selectValueUI="radioGroup"><selectOptions><selectOption useValue="/content/folder[@name='JavaScript Examples']/folder[@name='Modifying Drillthrough Definitions']/report[@name='Drill 1']"><displayValue>Target 1</displayValue></selectOption><selectOption useValue="/content/folder[@name='JavaScript Examples']/folder[@name='Modifying Drillthrough Definitions']/report[@name='Drill 2']"><displayValue>Target 2</displayValue></selectOption></selectOptions><defaultSelections><defaultSimpleSelection>/content/folder[@name='JavaScript Examples']/folder[@name='Modifying Drillthrough Definitions']/report[@name='Drill 1']</defaultSimpleSelection></defaultSelections></selectValue></contents></tableCell></tableCells></tableRow></tableRows></table></contents><style><CSS value="vertical-align:top"/></style></tableCell></tableCells></tableRow></tableRows></table><HTMLItem>
			<dataSource>
				<staticValue>&lt;script&gt;
paulScripts.getControl('Format').setValidator(
  function (values) {
  paulScripts.changeDrillAttribute ('DrillThrough','m_outputFormat',values[0].use);
  return true;
  }
);

paulScripts.getControl('Target').setValidator(
  function (values) {
  paulScripts.changeDrillAttribute ('DrillThrough','m_path',values[0].use);
  return true;
  }
);

&lt;/script&gt;</staticValue>
			</dataSource>
		</HTMLItem></contents>
								</pageBody>
								
								
							</page>
						</reportPages>
					</layout>
				</layouts>
			<XMLAttributes><XMLAttribute name="RS_CreateExtendedDataItems" value="true" output="no"/><XMLAttribute name="listSeparator" value="," output="no"/><XMLAttribute name="RS_modelModificationTime" value="2008-07-25T15:28:38.133Z" output="no"/></XMLAttributes><reportName>Report</reportName></report>

Checkbox List Prompts revisited

A long while back, I published an article detailing how to use a list to interact with a checkbox prompt. Since then, several people have asked me to add features to the code, and to fix some bugs. I’ve also learned quite a bit since I wrote that, so I’ve rewritten a parts of it.

The basic core of the code is the same. Using div tags to identify the list and prompt objects, with more HTML items to build the actual checkbox in the list. This is by no means optimized JavaScript, nor is it using the 10.2 Prompt API.

Previously the code would only work with one list. The reference to the list was hardcoded in the script and the checkboxes and select all buttons would fail for the second list. Also requested, using grouped rows. For instance, a user might want to select all of the months in 2011 by checking on the checkbox in the 2011 group. Another thing I fixed was the way it would loop through value prompts to find the correct value. If the key had any special characters, it wouldn’t be able to find it. Cognos would automatically escape those special characters.

The XML below was written on 10.2, but will downgrade easily to 10.1 by changing

xmlns="http://developer.cognos.com/schemas/report/9.0/"

to

xmlns="http://developer.cognos.com/schemas/report/8.0/"

The JavaScript will work in 8.4 as well, but downgrading will be a bit more difficult – you need to use /report/6.0/ and remove all of the version 10 only XML elements. If there’s a demand for it, I’ll go through and post all of the different JavaScript objects here. (But there shouldn’t be, because 10.2 is the greatest things since 10.1.1 and you should all upgrade and IBM should be paying me push upgrades like this.)

<report xmlns="http://developer.cognos.com/schemas/report/9.0/" expressionLocale="he" interactivePageBreakByFrame="true">
    <modelPath>/content/folder[@name='Samples']/folder[@name='Cubes']/package[@name='Sales and Marketing (cube)']/model[@name='2008-07-25T15:28:38.072Z']</modelPath> 
    <layouts> 
        <layout> 
            <reportPages> 
                <page name="Page1"> 
                    <pageBody> 
                        <contents><HTMLItem description="Styles"> 
                                <dataSource> 
                                    <staticValue>&lt;style type="text/css"&gt; 
  
input.updatebutton 
{ 
   font-size:11px; 
   font-weight:bold; 
   width:140px; 
   height:27px; 
   color:#000000; 
   background-color:#cdc9c9; 
   border-style:solid; 
   border-color:#003377; 
   border-width:3px; 
} 
  
  
  
input.matchbutton 
{ 
   font-size:11px; 
   font-weight:bold; 
   width:140px; 
   height:27px; 
   color:#EEFFFF; 
   background-color:#0088DD; 
   border-style:solid; 
   border-color:#003377; 
   border-width:3px; 
} 
  
input.selectbutton 
{ 
   font-size:9px; 
   font-weight:bold; 
   width:60px; 
   height:20px; 
   color:#000000; 
   background-color:#FFFFFF; 
   border-style:solid; 
   border-color:#FFFFFF; 
   border-width:3px; 
} 
  
&lt;/style&gt; 
  
&lt;script language="javascript"&gt; 
  
function goLite(FRM,BTN) 
{ 
   window.document.forms[FRM].elements[BTN].style.color = "#FFFF99"; 
   window.document.forms[FRM].elements[BTN].style.backgroundColor = "#11AAEE"; 
} 
  
function goDim(FRM,BTN) 
{ 
   window.document.forms[FRM].elements[BTN].style.color = "#EEFFFF"; 
   window.document.forms[FRM].elements[BTN].style.backgroundColor = "#0088DD"; 
} 
  
&lt;/script&gt; 
</staticValue> 
                                </dataSource> 
                            </HTMLItem> 
                            <HTMLItem description="Scripts"> 
                                <dataSource> 
                                    <staticValue>&lt;script&gt; 
function selectInCheckbox(cbGroup,id) 
{ 
   var inputs= document.getElementById(cbGroup).getElementsByTagName('input'); 
   for (var i=0;i&lt;inputs.length;i++) 
   { 
        if (inputs[i].value == id)  
        { 
            inputs[i].click(); 
        } 
   } 
} 
  
function selectInCheckboxRow(cbGroup,id) 
{ 
    var inputs= document.getElementById(cbGroup).getElementsByTagName('input'); 
    inputs[id].click(); 
} 

function checkAll(list){ 
var inputs=document.getElementById(list).getElementsByTagName('input') 
for (var i=0;i&lt;inputs.length;i++){ 
        if (inputs[i].type == 'checkbox') { 
            if (inputs[i].checked == true)  
        {} 
        else {inputs[i].click();} 
        } 
} 
}  
  
function unCheckAll(list){ 
var inputs=document.getElementById(list).getElementsByTagName('input') 
for (var i=0;i&lt;inputs.length;i++){ 
        if (inputs[i].type == 'checkbox') { 
            if (inputs[i].checked == true)  
        {inputs[i].click();} 
        else {} 
        } 
} 
}  

function getSource (){
    var targ; 
    if (!e) var e = window.event; 
    if(!e) return false; 
    if (e.target) targ = e.target; 
    else if (e.srcElement) targ = e.srcElement; 
    if (targ.nodeType == 3) // defeat Safari bug 
      targ = targ.parentNode; 
    return targ; 
} 
  

function checkNested(){

var 
    elm = getSource().parentNode
  , tbody = elm.parentNode.parentNode.parentNode
  , rowsLength = tbody.rows.length
  , rowSpanLength = elm.rowSpan
  , rowIndex = elm.parentNode.rowIndex
  , isChecked = getSource().checked;

  for(var i=rowIndex;i&lt;rowIndex+rowSpanLength;i++)
  {
     var e = i == rowIndex?elm.cellIndex + 1 : 0;
      if(tbody.rows[i].cells[e].getElementsByTagName('INPUT')[0].checked == isChecked) {continue;}
     else{  tbody.rows[i].cells[e].getElementsByTagName('INPUT')[0].click()}
      i = i+elm.nextSibling.rowSpan - 1;

  }
}
&lt;/script&gt; 
  
</staticValue> 
                                </dataSource> 
                            </HTMLItem> 
                              
                              
                            <promptButton type="reprompt"> 
            <contents/> 
            <style> 
                <defaultStyles> 
                    <defaultStyle refStyle="bp"/> 
                </defaultStyles> 
            </style> 
        </promptButton><table><style><defaultStyles><defaultStyle refStyle="tb"/></defaultStyles><CSS value="border-collapse:collapse"/></style><tableRows><tableRow><tableCells><tableCell><contents><HTMLItem description="div"> 
            <dataSource> 
                <staticValue>&lt;div id="checkbox1" &gt;</staticValue> 
            </dataSource> 
        </HTMLItem><selectValue multiSelect="true" parameter="code" range="false" refQuery="Prompt" required="false" selectValueUI="checkboxGroup"><useItem refDataItem="Product line code"/><sortList><sortItem refDataItem="Product line code"/></sortList></selectValue><HTMLItem description="/div"> 
            <dataSource> 
                <staticValue>&lt;/div&gt;</staticValue> 
            </dataSource> 
        </HTMLItem><HTMLItem description="div"> 
            <dataSource> 
                <staticValue>&lt;div id="checkbox2" &gt;</staticValue> 
            </dataSource> 
        </HTMLItem><selectValue multiSelect="true" parameter="Quarter" refQuery="Quarters" required="false" selectValueUI="checkboxGroup"><useItem refDataItem="Quarter - Category Code"><displayItem refDataItem="Quarter"/></useItem></selectValue><HTMLItem description="/div"> 
            <dataSource> 
                <staticValue>&lt;/div&gt;</staticValue> 
            </dataSource> 
        </HTMLItem></contents><style><CSS value="vertical-align:top"/></style></tableCell><tableCell><contents><HTMLItem description="div id=&quot;list1&quot;"> 
                                                                <dataSource> 
                                                                    <staticValue>&lt;div id="list1"&gt;</staticValue> 
                                                                </dataSource> 
                                                            </HTMLItem><list name="List2" pageBreakText="false" refQuery="Prompt" repeatEveryPage="true"> 
              
              
              
            <style> 
                <CSS value="border-collapse:collapse"/> 
                <defaultStyles> 
                    <defaultStyle refStyle="ls"/> 
                </defaultStyles> 
            </style> 
        <listColumns><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><staticValue>HTML Item</staticValue></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lc"/></defaultStyles></style><contents><HTMLItem description="Checkbox Start"> 
                                                                                    <dataSource> 
                                                                                        <staticValue>&lt;input title="Faster but if the sorting is off then this won't work" type="checkbox"  
</staticValue></dataSource> 
                                                                                </HTMLItem><HTMLItem description="checked"> 
            <dataSource> 
                  
            <reportExpression>case when (ParamValue('code') +', ') contains ([Product line code] +', ') then (' checked ') else ('') end</reportExpression></dataSource> 
        </HTMLItem><HTMLItem description="onClick"> 
            <dataSource> 
                <staticValue>onClick="selectInCheckboxRow('checkbox1','</staticValue> 
            </dataSource> 
        </HTMLItem><HTMLItem description="Row"> 
            <dataSource> 
                  
            <reportExpression>RowNumber ()</reportExpression></dataSource> 
        </HTMLItem><HTMLItem description="CheckboxEnd"> 
                                                                                    <dataSource> 
                                                                                        <staticValue>'); 
"&gt; 
</staticValue> 
                                                                                    </dataSource> 
                                                                                </HTMLItem></contents></listColumnBody></listColumn><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><staticValue>By Code</staticValue></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lc"/></defaultStyles></style><contents><HTMLItem description="Checkbox Start"> 
                                                                                    <dataSource> 
                                                                                        <staticValue>&lt;input title="Slower but less prone to error" type="checkbox"  
</staticValue></dataSource> 
                                                                                </HTMLItem><HTMLItem description="checked"> 
            <dataSource> 
                  
            <reportExpression>case when (ParamValue('code') +', ') contains ([Product line code] +', ') then (' checked ') else ('') end</reportExpression></dataSource> 
        </HTMLItem><HTMLItem description="onClick"> 
            <dataSource> 
                <staticValue>onClick="selectInCheckbox('checkbox1','</staticValue> 
            </dataSource> 
        </HTMLItem><HTMLItem description="Code"> 
            <dataSource> 
                  
            <dataItemValue refDataItem="Product line code"/></dataSource> 
        </HTMLItem><HTMLItem description="CheckboxEnd"> 
                                                                                    <dataSource> 
                                                                                        <staticValue>'); 
"&gt; 
</staticValue> 
                                                                                    </dataSource> 
                                                                                </HTMLItem></contents></listColumnBody></listColumn><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Product line"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lc"/></defaultStyles></style><contents><textItem><dataSource><dataItemValue refDataItem="Product line"/></dataSource></textItem></contents></listColumnBody></listColumn><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Quantity"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lm"/></defaultStyles></style><contents><textItem><dataSource><dataItemValue refDataItem="Quantity"/></dataSource></textItem></contents></listColumnBody></listColumn><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Revenue"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lm"/></defaultStyles></style><contents><textItem><dataSource><dataItemValue refDataItem="Revenue"/></dataSource></textItem></contents></listColumnBody></listColumn><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Gross profit"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lm"/></defaultStyles></style><contents><textItem><dataSource><dataItemValue refDataItem="Gross profit"/></dataSource></textItem></contents></listColumnBody></listColumn></listColumns><propertyList><propertyItem refDataItem="Product line code"/></propertyList><sortList><sortItem refDataItem="Product line code"/></sortList></list><HTMLItem description="/div"> 
                                                                <dataSource> 
                                                                    <staticValue>&lt;/div&gt;</staticValue> 
                                                                </dataSource> 
                                                            </HTMLItem><HTMLItem description="doAll"> 
                                                        <dataSource> 
                                                            <staticValue> &lt;input type="button" value="Select All" class="selectbutton" onmouseover = "this.style.cursor='hand'" onclick="checkAll('list1');"&gt; 
&lt;input type="button" value="Clear All" class="selectbutton" onmouseover = "this.style.cursor='hand'" onclick="unCheckAll('list1');"&gt;</staticValue> 
                                                        </dataSource> 
                                                    </HTMLItem><HTMLItem description="div id=&quot;list2&quot;"> 
                                                                <dataSource> 
                                                                    <staticValue>&lt;div id="list2"&gt;</staticValue> 
                                                                </dataSource> 
                                                            </HTMLItem><list horizontalPagination="true" name="List1" refQuery="Prompt">
			
			
			
			<noDataHandler>
				<contents>
					<block>
						<contents>
							<textItem>
								<dataSource>
									<staticValue>No Data Available</staticValue>
								</dataSource>
								<style>
									<CSS value="padding:10px 18px;"/>
								</style>
							</textItem>
						</contents>
					</block>
				</contents>
			</noDataHandler>
			<style>
				<CSS value="border-collapse:collapse"/>
				<defaultStyles>
					<defaultStyle refStyle="ls"/>
				</defaultStyles>
			</style>
		<listColumns><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Time"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lc"/></defaultStyles></style><contents><HTMLItem>
			<dataSource>
				<staticValue>&lt;input type="checkbox" onclick="
checkNested()"&gt;</staticValue>
			</dataSource>
		</HTMLItem><textItem><dataSource><dataItemValue refDataItem="Time"/></dataSource></textItem></contents><listColumnRowSpan refDataItem="Time"/></listColumnBody></listColumn><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Year"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lc"/></defaultStyles></style><contents><HTMLItem>
			<dataSource>
				<staticValue>&lt;input type="checkbox" onclick="
checkNested()"&gt;</staticValue>
			</dataSource>
		</HTMLItem><textItem><dataSource><dataItemValue refDataItem="Year"/></dataSource></textItem></contents><listColumnRowSpan refDataItem="Year"/></listColumnBody></listColumn><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Quarter"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lc"/></defaultStyles></style><contents><HTMLItem description="Checkbox Start"> 
                                                                                    <dataSource> 
                                                                                        <staticValue>&lt;input title="Slower but less prone to error" type="checkbox"  
</staticValue></dataSource> 
                                                                                </HTMLItem><HTMLItem description="checked"> 
            <dataSource> 
                  
            <reportExpression>case when (ParamValue('Quarter') +', ') contains ([Quarter - Category Code] +', ') then (' checked ') else ('') end</reportExpression></dataSource> 
        </HTMLItem><HTMLItem description="onClick"> 
            <dataSource> 
                <staticValue>onClick="selectInCheckbox('checkbox2',unescape('</staticValue> 
            </dataSource> 
        </HTMLItem><HTMLItem description="Code"> 
            <dataSource> 
                  
            <reportExpression>URLEncode ([Prompt].[Quarter - Category Code])</reportExpression></dataSource> 
        </HTMLItem><HTMLItem description="CheckboxEnd"> 
                                                                                    <dataSource> 
                                                                                        <staticValue>')); 
"&gt; 
</staticValue> 
                                                                                    </dataSource> 
                                                                                </HTMLItem><textItem><dataSource><dataItemValue refDataItem="Quarter"/></dataSource></textItem></contents></listColumnBody></listColumn><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Quantity"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lm"/></defaultStyles></style><contents><textItem><dataSource><dataItemValue refDataItem="Quantity"/></dataSource></textItem></contents></listColumnBody></listColumn><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Revenue"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lm"/></defaultStyles></style><contents><textItem><dataSource><dataItemValue refDataItem="Revenue"/></dataSource></textItem></contents></listColumnBody></listColumn><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle="lt"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem="Gross profit"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle="lm"/></defaultStyles></style><contents><textItem><dataSource><dataItemValue refDataItem="Gross profit"/></dataSource></textItem></contents></listColumnBody></listColumn></listColumns><propertyList><propertyItem refDataItem="Year - Category Code"/><propertyItem refDataItem="Quarter - Category Code"/></propertyList><listGroups><listGroup refDataItem="Time"/><listGroup refDataItem="Year"/></listGroups></list><HTMLItem description="/div"> 
                                                                <dataSource> 
                                                                    <staticValue>&lt;/div&gt;</staticValue> 
                                                                </dataSource> 
                                                            </HTMLItem><HTMLItem description="doAll"> 
                                                        <dataSource> 
                                                            <staticValue> &lt;input type="button" value="Select All" class="selectbutton" onmouseover = "this.style.cursor='hand'" onclick="checkAll('list2');"&gt; 
&lt;input type="button" value="Clear All" class="selectbutton" onmouseover = "this.style.cursor='hand'" onclick="unCheckAll('list2');"&gt;</staticValue> 
                                                        </dataSource> 
                                                    </HTMLItem><HTMLItem description="div id=&quot;list3&quot;"> 
                                                                <dataSource> 
                                                                    <staticValue>&lt;div id="list3"&gt;</staticValue> 
                                                                </dataSource> 
                                                            </HTMLItem><crosstab name="Crosstab1" pageBreakText="false" refQuery="Prompt" repeatEveryPage="true">
			<crosstabCorner>
				<contents/>
				<style>
					<defaultStyles>
						<defaultStyle refStyle="xm"/>
					</defaultStyles>
				</style>
			</crosstabCorner>
			
			
			
			<style>
				<CSS value="border-collapse:collapse"/>
				<defaultStyles>
					<defaultStyle refStyle="xt"/>
				</defaultStyles>
			</style>
		<crosstabFactCell><contents><textItem><dataSource><cellValue/></dataSource></textItem></contents><style><defaultStyles><defaultStyle refStyle="mv"/></defaultStyles></style></crosstabFactCell><crosstabColumns><crosstabNode><crosstabNodeMembers><crosstabNodeMember edgeLocation="e5" refDataItem="Product line"><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style><contents><HTMLItem description="Checkbox Start"> 
                                                                                    <dataSource> 
                                                                                        <staticValue>&lt;input title="Slower but less prone to error" type="checkbox"  
</staticValue></dataSource> 
                                                                                </HTMLItem><HTMLItem description="checked"> 
            <dataSource> 
                  
            <reportExpression>case when (ParamValue('code') +', ') contains ([Product line code] +', ') then (' checked ') else ('') end</reportExpression></dataSource> 
        </HTMLItem><HTMLItem description="onClick"> 
            <dataSource> 
                <staticValue>onClick="selectInCheckbox('checkbox1','</staticValue> 
            </dataSource> 
        </HTMLItem><HTMLItem description="Code"> 
            <dataSource> 
                  
            <dataItemValue refDataItem="Product line code"/></dataSource> 
        </HTMLItem><HTMLItem description="CheckboxEnd"> 
                                                                                    <dataSource> 
                                                                                        <staticValue>'); 
"&gt; 
</staticValue> 
                                                                                    </dataSource> 
                                                                                </HTMLItem><textItem><dataSource><memberCaption/></dataSource></textItem></contents><propertyList><propertyItem refDataItem="Product line code"/></propertyList></crosstabNodeMember></crosstabNodeMembers><crosstabNestedNodes><crosstabNode><crosstabNodeMembers><crosstabNodeMember edgeLocation="e1" refDataItem="Quantity"><contents><textItem><dataSource><memberCaption/></dataSource></textItem></contents><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style></crosstabNodeMember></crosstabNodeMembers></crosstabNode><crosstabNode><crosstabNodeMembers><crosstabNodeMember edgeLocation="e2" refDataItem="Revenue"><contents><textItem><dataSource><memberCaption/></dataSource></textItem></contents><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style></crosstabNodeMember></crosstabNodeMembers></crosstabNode><crosstabNode><crosstabNodeMembers><crosstabNodeMember edgeLocation="e3" refDataItem="Gross profit"><contents><textItem><dataSource><memberCaption/></dataSource></textItem></contents><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style></crosstabNodeMember></crosstabNodeMembers></crosstabNode></crosstabNestedNodes></crosstabNode></crosstabColumns><crosstabRows><crosstabNode><crosstabNodeMembers><crosstabNodeMember edgeLocation="e4" refDataItem="Quarter"><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style><contents><HTMLItem description="Checkbox Start"> 
                                                                                    <dataSource> 
                                                                                        <staticValue>&lt;input title="Slower but less prone to error" type="checkbox"  
</staticValue></dataSource> 
                                                                                </HTMLItem><HTMLItem description="checked"> 
            <dataSource> 
                  
            <reportExpression>case when (ParamValue('Quarter') +', ') contains ([Quarter - Category Code] +', ') then (' checked ') else ('') end</reportExpression></dataSource> 
        </HTMLItem><HTMLItem description="onClick"> 
            <dataSource> 
                <staticValue>onClick="selectInCheckbox('checkbox2',unescape('</staticValue> 
            </dataSource> 
        </HTMLItem><HTMLItem description="Code"> 
            <dataSource> 
                  
            <reportExpression>URLEncode ([Prompt].[Quarter - Category Code])</reportExpression></dataSource> 
        </HTMLItem><HTMLItem description="CheckboxEnd"> 
                                                                                    <dataSource> 
                                                                                        <staticValue>')); 
"&gt; 
</staticValue> 
                                                                                    </dataSource> 
                                                                                </HTMLItem><textItem><dataSource><memberCaption/></dataSource></textItem></contents><propertyList><propertyItem refDataItem="Quarter - Category Code"/></propertyList></crosstabNodeMember></crosstabNodeMembers></crosstabNode></crosstabRows></crosstab><HTMLItem description="/div"> 
                                                                <dataSource> 
                                                                    <staticValue>&lt;/div&gt;</staticValue> 
                                                                </dataSource> 
                                                            </HTMLItem><HTMLItem description="doAll"> 
                                                        <dataSource> 
                                                            <staticValue> &lt;input type="button" value="Select All" class="selectbutton" onmouseover = "this.style.cursor='hand'" onclick="checkAll('list3');"&gt; 
&lt;input type="button" value="Clear All" class="selectbutton" onmouseover = "this.style.cursor='hand'" onclick="unCheckAll('list3');"&gt;</staticValue> 
                                                        </dataSource> 
                                                    </HTMLItem></contents><style><CSS value="vertical-align:top"/></style></tableCell></tableCells></tableRow></tableRows></table><block> 
                                <contents/> 
                            </block> 
                        <combinationChart maxHotspots="10000" name="Combination Chart1" refQuery="Report" showTooltips="true"> 
                                <legend> 
                                    <legendPosition> 
                                        <relativePosition/> 
                                    </legendPosition> 
                                    <legendTitle refQuery="Report"> 
                                        <style> 
                                            <defaultStyles> 
                                                <defaultStyle refStyle="lx"/> 
                                            </defaultStyles> 
                                        </style> 
                                    </legendTitle> 
                                    <style> 
                                        <defaultStyles> 
                                            <defaultStyle refStyle="lg"/> 
                                        </defaultStyles> 
                                    </style> 
                                </legend> 
                                <ordinalAxis> 
                                    <axisTitle refQuery="Report"> 
                                        <style> 
                                            <defaultStyles> 
                                                <defaultStyle refStyle="at"/> 
                                            </defaultStyles> 
                                        </style> 
                                    </axisTitle> 
                                    <axisLine color="black"/> 
                                    <style> 
                                        <defaultStyles> 
                                            <defaultStyle refStyle="al"/> 
                                        </defaultStyles> 
                                    </style> 
                                </ordinalAxis> 
                                <numericalAxisY1> 
                                    <axisTitle refQuery="Report"> 
                                        <style> 
                                            <defaultStyles> 
                                                <defaultStyle refStyle="at"/> 
                                            </defaultStyles> 
                                        </style> 
                                    </axisTitle> 
                                    <gridlines color="#cccccc"/> 
                                    <axisLine color="black"/> 
                                    <style> 
                                        <defaultStyles> 
                                            <defaultStyle refStyle="al"/> 
                                        </defaultStyles> 
                                    </style> 
                                </numericalAxisY1> 
                                <combinationChartTypes> 
                                    <bar><chartNodes><chartNode><chartNodeMembers><chartNodeMember refDataItem="Revenue"><chartContents><chartTextItem><dataSource><memberCaption/></dataSource></chartTextItem></chartContents></chartNodeMember></chartNodeMembers></chartNode></chartNodes></bar> 
                                </combinationChartTypes> 
                                <style> 
                                    <defaultStyles> 
                                        <defaultStyle refStyle="ch"/> 
                                    </defaultStyles> 
                                </style> 
                                <commonClusters><chartNodes><chartNode><chartNodeMembers><chartNodeMember refDataItem="Product type"><chartContents><chartTextItem><dataSource><memberCaption/></dataSource></chartTextItem></chartContents></chartNodeMember></chartNodeMembers></chartNode></chartNodes></commonClusters><conditionalRender refVariable="renderGraph"><renderFor refVariableValue="1"/></conditionalRender></combinationChart> 
                        </contents> 
                    <style><defaultStyles><defaultStyle refStyle="pb"/></defaultStyles></style></pageBody> 
                <style><defaultStyles><defaultStyle refStyle="pg"/></defaultStyles></style></page> 
            <page name="Page2"> 
                    <pageBody> 
                        <contents><HTMLItem description="Styles"> 
                                <dataSource> 
                                    <staticValue>&lt;style type="text/css"&gt; 
  
input.updatebutton 
{ 
   font-size:11px; 
   font-weight:bold; 
   width:140px; 
   height:27px; 
   color:#000000; 
   background-color:#cdc9c9; 
   border-style:solid; 
   border-color:#003377; 
   border-width:3px; 
} 
  
  
  
input.matchbutton 
{ 
   font-size:11px; 
   font-weight:bold; 
   width:140px; 
   height:27px; 
   color:#EEFFFF; 
   background-color:#0088DD; 
   border-style:solid; 
   border-color:#003377; 
   border-width:3px; 
} 
  
input.selectbutton 
{ 
   font-size:9px; 
   font-weight:bold; 
   width:60px; 
   height:20px; 
   color:#000000; 
   background-color:#FFFFFF; 
   border-style:solid; 
   border-color:#FFFFFF; 
   border-width:3px; 
} 
  
&lt;/style&gt; 
  
&lt;script language="javascript"&gt; 
  
function goLite(FRM,BTN) 
{ 
   window.document.forms[FRM].elements[BTN].style.color = "#FFFF99"; 
   window.document.forms[FRM].elements[BTN].style.backgroundColor = "#11AAEE"; 
} 
  
function goDim(FRM,BTN) 
{ 
   window.document.forms[FRM].elements[BTN].style.color = "#EEFFFF"; 
   window.document.forms[FRM].elements[BTN].style.backgroundColor = "#0088DD"; 
} 
  
&lt;/script&gt; 
</staticValue> 
                                </dataSource> 
                            </HTMLItem> 
                            <HTMLItem description="Scripts"> 
                                <dataSource> 
                                    <staticValue>&lt;script&gt; 
function selectInCheckbox(cbGroup,id) 
{ 
   var inputs= document.getElementById(cbGroup).getElementsByTagName('input'); 
   for (var i=0;i&lt;inputs.length;i++) 
   { 
        if (inputs[i].value == id)  
        { 
            inputs[i].click(); 
        } 
   } 
} 
  
function selectInCheckboxRow(cbGroup,id) 
{ 
    var inputs= document.getElementById(cbGroup).getElementsByTagName('input'); 
    inputs[id].click(); 
} 

function checkAll(list){ 
var inputs=document.getElementById(list).getElementsByTagName('input') 
for (var i=0;i&lt;inputs.length;i++){ 
        if (inputs[i].type == 'checkbox') { 
            if (inputs[i].checked == true)  
        {} 
        else {inputs[i].click();} 
        } 
} 
}  
  
function unCheckAll(list){ 
var inputs=document.getElementById(list).getElementsByTagName('input') 
for (var i=0;i&lt;inputs.length;i++){ 
        if (inputs[i].type == 'checkbox') { 
            if (inputs[i].checked == true)  
        {inputs[i].click();} 
        else {} 
        } 
} 
}  
&lt;/script&gt; 
  
</staticValue> 
                                </dataSource> 
                            </HTMLItem> 
                              
                              
                            <promptButton type="reprompt"> 
            <contents/> 
            <style> 
                <defaultStyles> 
                    <defaultStyle refStyle="bp"/> 
                </defaultStyles> 
            </style> 
        </promptButton><table><style><defaultStyles><defaultStyle refStyle="tb"/></defaultStyles><CSS value="border-collapse:collapse"/></style><tableRows><tableRow><tableCells><tableCell><contents><HTMLItem description="div"> 
            <dataSource> 
                <staticValue>&lt;div id="checkbox1" &gt;</staticValue> 
            </dataSource> 
        </HTMLItem><selectValue multiSelect="true" parameter="code" range="false" refQuery="Prompt" required="false" selectValueUI="checkboxGroup"><useItem refDataItem="Product line code"/><sortList><sortItem refDataItem="Product line code"/></sortList></selectValue><HTMLItem description="/div"> 
            <dataSource> 
                <staticValue>&lt;/div&gt;</staticValue> 
            </dataSource> 
        </HTMLItem><HTMLItem description="div"> 
            <dataSource> 
                <staticValue>&lt;div id="checkbox2" &gt;</staticValue> 
            </dataSource> 
        </HTMLItem><selectValue multiSelect="true" parameter="Year" refQuery="Quarters" required="false" selectValueUI="checkboxGroup"><useItem refDataItem="Quarter - Category Code"><displayItem refDataItem="Quarter"/></useItem></selectValue><HTMLItem description="/div"> 
            <dataSource> 
                <staticValue>&lt;/div&gt;</staticValue> 
            </dataSource> 
        </HTMLItem></contents><style><CSS value="vertical-align:top"/></style></tableCell><tableCell><contents/><style><CSS value="vertical-align:top"/></style></tableCell></tableCells></tableRow></tableRows></table><block> 
                                <contents/> 
                            </block> 
                        <combinationChart maxHotspots="10000" name="Combination Chart2" refQuery="Report" showTooltips="true"> 
                                <legend> 
                                    <legendPosition> 
                                        <relativePosition/> 
                                    </legendPosition> 
                                    <legendTitle refQuery="Report"> 
                                        <style> 
                                            <defaultStyles> 
                                                <defaultStyle refStyle="lx"/> 
                                            </defaultStyles> 
                                        </style> 
                                    </legendTitle> 
                                    <style> 
                                        <defaultStyles> 
                                            <defaultStyle refStyle="lg"/> 
                                        </defaultStyles> 
                                    </style> 
                                </legend> 
                                <ordinalAxis> 
                                    <axisTitle refQuery="Report"> 
                                        <style> 
                                            <defaultStyles> 
                                                <defaultStyle refStyle="at"/> 
                                            </defaultStyles> 
                                        </style> 
                                    </axisTitle> 
                                    <axisLine color="black"/> 
                                    <style> 
                                        <defaultStyles> 
                                            <defaultStyle refStyle="al"/> 
                                        </defaultStyles> 
                                    </style> 
                                </ordinalAxis> 
                                <numericalAxisY1> 
                                    <axisTitle refQuery="Report"> 
                                        <style> 
                                            <defaultStyles> 
                                                <defaultStyle refStyle="at"/> 
                                            </defaultStyles> 
                                        </style> 
                                    </axisTitle> 
                                    <gridlines color="#cccccc"/> 
                                    <axisLine color="black"/> 
                                    <style> 
                                        <defaultStyles> 
                                            <defaultStyle refStyle="al"/> 
                                        </defaultStyles> 
                                    </style> 
                                </numericalAxisY1> 
                                <combinationChartTypes> 
                                    <bar><chartNodes><chartNode><chartNodeMembers><chartNodeMember refDataItem="Revenue"><chartContents><chartTextItem><dataSource><memberCaption/></dataSource></chartTextItem></chartContents></chartNodeMember></chartNodeMembers></chartNode></chartNodes></bar> 
                                </combinationChartTypes> 
                                <style> 
                                    <defaultStyles> 
                                        <defaultStyle refStyle="ch"/> 
                                    </defaultStyles> 
                                </style> 
                                <commonClusters><chartNodes><chartNode><chartNodeMembers><chartNodeMember refDataItem="Product type"><chartContents><chartTextItem><dataSource><memberCaption/></dataSource></chartTextItem></chartContents></chartNodeMember></chartNodeMembers></chartNode></chartNodes></commonClusters><conditionalRender refVariable="renderGraph"><renderFor refVariableValue="1"/></conditionalRender></combinationChart> 
                        </contents> 
                    <style><defaultStyles><defaultStyle refStyle="pb"/></defaultStyles></style></pageBody> 
                <style><defaultStyles><defaultStyle refStyle="pg"/></defaultStyles></style></page></reportPages> 
        </layout> 
    </layouts> 
<queries> 
      
      
      
          
    <query name="Prompt"> 
            <source> 
                <model/> 
            </source> 
            <selection><dataItem aggregate="none" name="Product line code" rollupAggregate="none"><expression>[sales_and_marketing].[Products].[Products].[Product line].[Product line - Category Code]</expression></dataItem><dataItem aggregate="none" name="Product line" rollupAggregate="none"><expression>[sales_and_marketing].[Products].[Products].[Product line]</expression></dataItem><dataItem aggregate="total" name="Quantity"><expression>[sales_and_marketing].[Measures].[Quantity]</expression></dataItem><dataItem aggregate="total" name="Revenue"><expression>[sales_and_marketing].[Measures].[Revenue]</expression></dataItem><dataItem aggregate="total" name="Gross profit"><expression>[sales_and_marketing].[Measures].[Gross profit]</expression></dataItem><dataItem aggregate="none" name="Year - Category Code"><expression>[sales_and_marketing].[Time].[Time].[Year].[Year - Category Code]</expression></dataItem><dataItem aggregate="none" name="Year" rollupAggregate="none" sort="ascending"><expression>[sales_and_marketing].[Time].[Time].[Year]</expression></dataItem><dataItem aggregate="none" name="Quarter" rollupAggregate="none"><expression>[sales_and_marketing].[Time].[Time].[Quarter]</expression></dataItem><dataItem aggregate="none" name="Quarter - Category Code" rollupAggregate="none"><expression>[sales_and_marketing].[Time].[Time].[Quarter].[Quarter - Category Code]</expression></dataItem><dataItem name="Time" aggregate="none" rollupAggregate="none"><expression>[sales_and_marketing].[Time].[Time].[Time]-&gt;:[PC].[@MEMBER].[Time]</expression></dataItem></selection> 
        </query><query name="Report"><source><model/></source><selection><dataItem aggregate="total" name="Revenue"><expression>[sales_and_marketing].[Measures].[Revenue]</expression></dataItem><dataItem aggregate="none" name="Product type" rollupAggregate="none"><expression>[sales_and_marketing].[Products].[Products].[Product type]</expression></dataItem></selection><detailFilters><detailFilter><filterExpression>[sales_and_marketing].[Products].[Products].[Product line].[Product line - Category Code] in (?code?)</filterExpression></detailFilter><detailFilter use="optional"><filterExpression>[sales_and_marketing].[Time].[Time].[Quarter].[Quarter - Category Code] in (?Quarter?)</filterExpression></detailFilter></detailFilters></query><query name="Quarters"><source><model/></source><selection><dataItem aggregate="none" name="Quarter - Category Code"><expression>[sales_and_marketing].[Time].[Time].[Quarter].[Quarter - Category Code]</expression></dataItem><dataItem aggregate="none" name="Quarter" sort="ascending"><expression>[sales_and_marketing].[Time].[Time].[Quarter]</expression></dataItem></selection></query></queries><XMLAttributes><XMLAttribute name="RS_CreateExtendedDataItems" output="no" value="false"/><XMLAttribute name="listSeparator" output="no" value=","/><XMLAttribute name="RS_modelModificationTime" output="no" value="2008-07-25T15:28:38.133Z"/></XMLAttributes><reportVariables><reportVariable name="renderGraph" type="boolean"> 
            <reportExpression>ParamValue('code') is not null</reportExpression> 
            <variableValues> 
                <variableValue value="1"/> 
            </variableValues> 
        </reportVariable></reportVariables><reportName>checkbox 2</reportName></report>

Button Prompts in Cognos 10

One of the features I’ve always wanted is buttons that set parameters. The existing prompt buttons just serve to provide navigation features to Cognos reports. You can’t, for instance, press the “Mountaineering Equipment” button and see a report which is filtered by mountaineering. Yes, you can use regular checkbox or radio prompts to do this, but that is hardly the point, is it? I want good, old fashioned buttons!

Consider the following screenshot:
report with buttons

There are buttons going across the top, to let the user select which product line, and buttons going down the left to let the user select how he wants to view the report (xtab, bar, or column).

It would be possible to use standard checkbox or radio prompts with this, but it wouldn’t look nearly as good. Some developers may be tempted to manually create the buttons with extensive use of HTML items. It would work, a certain developer (who will remain anonymous here) used that method for a series of reports and I still get calls asking how to add or remove buttons.

Instead, it is infinitely easier to write JS function that creates the button elements on the fly based on an existing prompt.

Read the following JS (10.2 only):

<script>

/* 
  * Function: addEvent
  * Author: Dan Fruendel
  * Attachs an event or adds an event listener depending on the browser.
  */
var
  addEvent = function(element, event, func)
  {
    if(element.addEventListener)
    {
      addEvent = function(element, event, func)
      {
        element.addEventListener(event, func, false);
        return true;
      };
    }
    else if(element.attachEvent)
    {
      addEvent = function(element, event, func)
      {
        return element.attachEvent("on" + event, func);
      };
    }
    else
    {
      addEvent = function(element, event, func)
      {
        var oldEventHandler = element['on' + event];
        element['on' + event] = function()
        {
          //using .apply to pass on anything this function gets.
          if(typeof(oldEventHandler) === "function")
          {
            oldEventHandler.apply(element, arguments);
          }
          func.apply(element, arguments);
        }
        return true;
      };
    }
    return addEvent(element, event, func);
  }
/*
 * Fake Namespace and prompt getters.
 */ 	
var paulScripts = {}
  , oCR = cognos.Report.getReport("_THIS_");

paulScripts.getSource = function()
{
    var targ;
    if (!e) var e = window.event;
    if(!e) return false;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ.nodeType == 3) // defeat Safari bug
      targ = targ.parentNode;
    return targ;
}

paulScripts.getControl = function(promptName) {
  return oCR.prompt.getControlByName(promptName);
}

paulScripts.reprompt = function(){
if(!paulScripts.getSource() ) return true;
  oCR.sendRequest(cognos.Report.Action.REPROMPT);
  return true;
}


paulScripts.addButtons = function ( promptName, myClass,reprompt) {
var 
    newOption = ''
  , reprompt = reprompt?reprompt:false
  , id = paulScripts.getControl ( promptName )._id_
  , selElm = document.getElementById('PRMT_SV_'+ id)
  , selElmSelect = document.getElementById('PRMT_SV_LINK_SELECT_'+ id)
  , selElmDeselect = document.getElementById('PRMT_SV_LINK_DESELECT_'+ id)
  , rads = selElm.getElementsByTagName('input')
  , len = rads.length
  , type = len==0?'none':rads[0].type
  , radioClick = function(){for(var radios=paulScripts.getSource().parentNode.getElementsByTagName('input').length/2;radios<paulScripts.getSource().parentNode.getElementsByTagName('input').length;radios++){paulScripts.getSource().parentNode.getElementsByTagName('input')[radios].className=myClass + 'Unselected'};paulScripts.getSource().parentNode.getElementsByTagName('input')[paulScripts.getSource().index].click(); paulScripts.getSource().className=myClass + 'Selected'}
  , checkClick= function(){paulScripts.getSource().parentNode.getElementsByTagName('input')[paulScripts.getSource().index].click(); paulScripts.getSource().className=paulScripts.getSource().className==myClass + 'Selected'?myClass + 'Unselected':myClass + 'Selected';}
  , selectAll= function(){ for(var elms=rads.length;elms>rads.length/2;elms--){rads[elms-1].className=myClass + 'Selected'}}
  , deselectAll= function(){ ; for(var elms=rads.length;elms>rads.length/2;elms--){rads[elms-1].className=myClass + 'Unselected'}}
;
  selElm.className = myClass;

  if(type == 'none') return false;

  for(i=0;i<len;i++)
  {
    newOption = document.createElement( 'input');
    newOption.type='button';
    newOption.value=rads[i].getAttribute('dv');
    newOption.className=rads[i].selected?myClass + 'Selected': myClass + 'Unselected';
    newOption.index=i;
    if(type=='checkbox') {addEvent(newOption,'click',checkClick)};
    if(type=='radio') {addEvent(newOption,'click',radioClick)};
    rads[i].parentNode.parentNode.style.display='none';
    selElm.appendChild(newOption );
  }

  if(reprompt) paulScripts.getControl ( promptName ).setValidator(paulScripts.reprompt);

  if(selElmSelect) addEvent(selElmSelect,'click',selectAll);
  if(selElmDeselect) addEvent(selElmDeselect,'click',deselectAll);
}

paulScripts.addButtons('Products','Horizontal',1);
paulScripts.addButtons('Reports','Vertical');

</script>

Look complicated? It’s actually not complicated at all. The first function there was written by a friend (and if you think I’m good at JS… he’s the kind of person to look at some code, think for 5 minutes and rewrite it using half the lines and make it run several times faster), it allows you to attach events in different browsers. The getSource function is there because some browsers have issues with THIS. getControl is the 10.2 method of identifying the referenced prompt object. The reprompt function is simply the way I force the report to refresh (on checkbox prompts, for instance).

The meat of the function is in the addButton function. First it finds the prompt object you’re referencing (using 10.2 methods, needs a rewrite if using in earlier versions). Next it determines if the prompt is a checkbox or radio. If it’s neither, the function exits. Then it starts creating the actual button elements. It generates an array of all of the elements in the prompt, then for each one creates a button using the display value and hides the original element. Each generated button has a click function that will, in turn, click on the correct checkbox or radio in the original prompt.

The buttons each have a class based on if it’s selected or not. Clicking on the button will alternate between selected/unselected. The style will have to be included in an HTML item as well. Each style must have three entries, styleName for the top box, styleNameSelected for selected buttons, and styleNameUnselected for unselected buttons.

If the reprompt option is set to true, then it will add the reprompt function to the validator, essentially making it an autosubmit prompt.

Finally, if this is a checkbox group, it will add functions to the select and deselect all links under the prompt.

To use the prompt, it’s then a simple matter of creating your prompt object on the page, naming it, and calling the function. So in the above screenshot there are two prompts on the page. A multiselect checkbox (based on the product line dimension) above the crosstab, and a radio button (with static choices) to the left. The function is called twice, once for each prompt. The reprompt flag is set for the checkbox prompt, while the radio is set to autosubmit in the report.

I wrote some simple CSS to highlight the buttons when selected:

<style>
.Vertical{
  width:'';
  height:'';
}

.VerticalUnselected{
  padding:2px 10px 3px 10px;
  margin-right:7px;
  background-image:url(../reportstyles/images/button_bg.png);
  background-position:left top;
  background-repeat:repeat-x;
  background-color:#EFEFEF;
  color:#000000;
  font-size:10pt;
  font-weight:normal;
  text-align:center;
  border:1px solid #92afc2;
  width: 75px;
  display:block;
}

.VerticalSelected{
  padding:2px 10px 3px 10px;
  margin-right:7px;
  background-image:url(../reportstyles/images/button_bg.png);
  background-position:left top;
  background-repeat:repeat-x;
  background-color:#A0AFEB;
  color:#000000;
  font-size:10pt;
  font-weight:normal;
  text-align:center;
  border:1px solid #92afc2;
  width: 75px;
  display:block;
}

.Horizontal{
  width:0;
  height:0;
  white-space:nowrap;
}

.HorizontalUnselected{
  padding:2px 10px 3px 10px;
  margin-right:7px;
  background-image:url(../reportstyles/images/button_bg.png);
  background-position:left top;
  background-repeat:repeat-x;
  background-color:#EFEFEF;
  color:#000000;
  font-size:10pt;
  font-weight:normal;
  text-align:center;
  border:1px solid #92afc2;
}

.HorizontalSelected{
  padding:2px 10px 3px 10px;
  margin-right:7px;
  background-image:url(../reportstyles/images/button_bg.png);
  background-position:left top;
  background-repeat:repeat-x;
  background-color:#A0AFEB;
  color:#000000;
  font-size:10pt;
  font-weight:normal;
  text-align:center;
  border:1px solid #92afc2;
}

</style>

Each button group can have it’s own unique style, if so desired. Just remember to write the CSS for each one.

Ultimately the report consists of 2 prompts, 2 graphs, a crosstab, a conditional block and a single HTML item.

The report XML (10.2, sales and marketing) below:

<report xmlns="http://developer.cognos.com/schemas/report/9.0/" useStyleVersion="10" expressionLocale="en-us">
				<modelPath>/content/folder[@name='Samples']/folder[@name='Cubes']/package[@name='Sales and Marketing (cube)']/model[@name='2008-07-25T15:28:38.072Z']</modelPath>
				<drillBehavior/>
				<layouts>
					<layout>
						<reportPages>
							<page name="Page1">
								<style>
									<defaultStyles>
										<defaultStyle refStyle="pg"/>
									</defaultStyles>
								</style>
								<pageBody>
									<style>
										<defaultStyles>
											<defaultStyle refStyle="pb"/>
										</defaultStyles>
									</style>
									<contents><table><style><defaultStyles><defaultStyle refStyle="tb"/></defaultStyles><CSS value="border-collapse:collapse;width:100%"/></style><tableRows><tableRow><tableCells><tableCell><contents/></tableCell><tableCell><contents><selectValue parameter="Products" refQuery="Products" multiSelect="true" required="false" name="Products" selectValueUI="checkboxGroup"><useItem refDataItem="Product line"/><style><CSS value="height:0px;width:0px"/></style></selectValue></contents></tableCell></tableCells></tableRow><tableRow><tableCells><tableCell><contents><selectValue selectValueUI="radioGroup" name="Reports" autoSubmit="true" parameter="ReportType" hideAdornments="true"><selectOptions><selectOption useValue="1"><displayValue>Columns</displayValue></selectOption><selectOption useValue="2"><displayValue>Bar</displayValue></selectOption><selectOption useValue="3"><displayValue>Crosstab</displayValue></selectOption></selectOptions><style><CSS value="width:0px;height:0px"/></style><defaultSelections><defaultSimpleSelection>1</defaultSimpleSelection></defaultSelections></selectValue></contents><style><CSS value="vertical-align:top"/></style></tableCell><tableCell><contents>
												<conditionalBlocks>
			<conditionalBlockDefault>
				<contents/>
			</conditionalBlockDefault>
		<conditionalBlockCases refVariable="ReportType"><conditionalBlock refVariableValue="1"><contents><v2_combinationChart maxHotspots="10000" refQuery="Query2" name="Combination Chart2">
														<v2_combinationTypeTooltips/>
														<v2_legend>
															<v2_legendPosition>
																<v2_legendPreset/>
															</v2_legendPosition>
															<v2_legendTitle refQuery="Query2">
																<v2_chartTextContents>
																	<v2_automaticText/>
																</v2_chartTextContents>
																<style>
																	<defaultStyles>
																		<defaultStyle refStyle="lx"/>
																	</defaultStyles>
																</style>
															</v2_legendTitle>
															<style>
																<defaultStyles>
																	<defaultStyle refStyle="lg"/>
																</defaultStyles>
															</style>
														</v2_legend>
														<v2_commonAxis>
															<v2_ordinalAxis>
																<v2_axisTitle refQuery="Query2">
																	<v2_chartTextContents>
																		<v2_automaticText/>
																	</v2_chartTextContents>
																	<style>
																		<defaultStyles>
																			<defaultStyle refStyle="at"/>
																		</defaultStyles>
																	</style>
																</v2_axisTitle>
																<v2_axisLine lineWeight="0"/>
																<v2_axisLabels>
																	<style>
																		<defaultStyles>
																			<defaultStyle refStyle="al"/>
																		</defaultStyles>
																	</style>
																</v2_axisLabels>
															</v2_ordinalAxis>
															<chartNodes><chartNode><chartNodeMembers><chartNodeMember refDataItem="Product Types"><chartContents><chartTextItem><dataSource><memberCaption/></dataSource></chartTextItem></chartContents></chartNodeMember></chartNodeMembers></chartNode></chartNodes></v2_commonAxis>
														<v2_topLeftAxis>
															<v2_combinationChartTypes>
																<v2_bar borders="show">
																	<v2_solidPalette>
																		<v2_solidPaletteEntries>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#8599D3">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#8599D3"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#5876AE"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#E3AE6C">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#E3AE6C"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#CD854E"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#839862">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#839862"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#6C7F56"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#B7C873">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#B7C873"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#AFB885"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#8484A8">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#8484A8"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#525E7E"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#C0CCED">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#C0CCED"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#B0C2E5"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#8C5580">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#8C5580"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#794067"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#C789BC">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#C789BC"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#BB72BC"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#D5BAEF">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#D5BAEF"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#C29FD1"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#83683F">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#83683F"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#604926"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#DCB05A">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#DCB05A"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#C09C52"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#F4DF9E">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#F4DF9E"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#E4CF87"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#5F8A8C">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#5F8A8C"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#537579"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#96C4B2">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#96C4B2"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#89B0A0"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#CBE8E7">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#CBE8E7"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#BDD6D5"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#AE6564">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#AE6564"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#875352"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#D88C6F">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#D88C6F"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#C47D61"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#E3C9B0">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#E3C9B0"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#D2B2A5"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#848484">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#848484"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#555555"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#a4a4a4">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#a4a4a4"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#909090"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																			<v2_solidPaletteEntry>
																				<v2_fillEffect defaultColor="#C7C7C7">
																					<v2_linearGradient>
																						<v2_gradientColor gradientColor="#C7C7C7"/>
																						<v2_gradientColor colorPosition="100" gradientColor="#c1c1c1"/>
																					</v2_linearGradient>
																				</v2_fillEffect>
																			</v2_solidPaletteEntry>
																		</v2_solidPaletteEntries>
																	</v2_solidPalette>
																	<!-- v2_solidPaletteRef ref=&amp;amp;quot;gDefaultSolid&amp;amp;quot;/ -->
																	<chartNodes><chartNode><chartNodeMembers><chartNodeMember refDataItem="Revenue"><chartContents><chartTextItem><dataSource><memberCaption/></dataSource></chartTextItem></chartContents></chartNodeMember></chartNodeMembers></chartNode></chartNodes></v2_bar>
															</v2_combinationChartTypes>
															<v2_axis>
																<v2_axisTitle refQuery="Query2">
																	<v2_chartTextContents>
																		<v2_automaticText/>
																	</v2_chartTextContents>
																	<style>
																		<defaultStyles>
																			<defaultStyle refStyle="at"/>
																		</defaultStyles>
																	</style>
																</v2_axisTitle>
																<v2_axisLine lineWeight="0"/>
																<v2_axisRange>
																	<v2_automaticRange/>
																</v2_axisRange>
																<v2_axisLabels>
																	<style>
																		<defaultStyles>
																			<defaultStyle refStyle="al"/>
																		</defaultStyles>
																	</style>
																</v2_axisLabels>
																<v2_majorGridlines lineWeight="0" lineColor="#CCCCCC"/>
																<v2_majorBackgroundColors>
																	<v2_firstBackgroundColor color="#D2D2D2" transparency="50"/>
																	<v2_secondBackgroundColor color="#E2E2E2" transparency="50"/>
																</v2_majorBackgroundColors>
															</v2_axis>
														</v2_topLeftAxis>
														<style>
															<defaultStyles>
																<defaultStyle refStyle="ch"/>
															</defaultStyles>
														</style>
														<noDataHandler>
															<contents>
																<block>
																	<contents>
																		<textItem>
																			<dataSource>
																				<staticValue>No Data Available</staticValue>
																			</dataSource>
																			<style>
																				<CSS value="padding:10px 18px;"/>
																			</style>
																		</textItem>
																	</contents>
																</block>
															</contents>
														</noDataHandler>
														</v2_combinationChart></contents></conditionalBlock><conditionalBlock refVariableValue="2"><contents><v2_combinationChart maxHotspots="10000" orientation="horizontal" refQuery="Query2" name="Combination Chart1">
																		<v2_combinationTypeTooltips/>
																		<v2_legend>
																			<v2_legendPosition>
																				<v2_legendPreset/>
																			</v2_legendPosition>
																			<v2_legendTitle refQuery="Query2">
																				<v2_chartTextContents>
																					<v2_automaticText/>
																				</v2_chartTextContents>
																				<style>
																					<defaultStyles>
																						<defaultStyle refStyle="lx"/>
																					</defaultStyles>
																				</style>
																			</v2_legendTitle>
																			<style>
																				<defaultStyles>
																					<defaultStyle refStyle="lg"/>
																				</defaultStyles>
																			</style>
																		</v2_legend>
																		<v2_commonAxis>
																			<v2_ordinalAxis>
																				<v2_axisTitle refQuery="Query2">
																					<v2_chartTextContents>
																						<v2_automaticText/>
																					</v2_chartTextContents>
																					<style>
																						<defaultStyles>
																							<defaultStyle refStyle="at"/>
																						</defaultStyles>
																					</style>
																				</v2_axisTitle>
																				<v2_axisLine lineWeight="0"/>
																				<v2_axisLabels>
																					<style>
																						<defaultStyles>
																							<defaultStyle refStyle="al"/>
																						</defaultStyles>
																					</style>
																				</v2_axisLabels>
																			</v2_ordinalAxis>
																			<chartNodes><chartNode><chartNodeMembers><chartNodeMember refDataItem="Product Types"><chartContents><chartTextItem><dataSource><memberCaption/></dataSource></chartTextItem></chartContents></chartNodeMember></chartNodeMembers></chartNode></chartNodes></v2_commonAxis>
																		<v2_topLeftAxis>
																			<v2_combinationChartTypes>
																				<v2_bar borders="show">
																					<v2_solidPalette>
																						<v2_solidPaletteEntries>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#8599D3">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#8599D3"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#5876AE"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#E3AE6C">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#E3AE6C"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#CD854E"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#839862">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#839862"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#6C7F56"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#B7C873">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#B7C873"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#AFB885"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#8484A8">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#8484A8"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#525E7E"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#C0CCED">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#C0CCED"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#B0C2E5"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#8C5580">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#8C5580"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#794067"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#C789BC">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#C789BC"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#BB72BC"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#D5BAEF">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#D5BAEF"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#C29FD1"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#83683F">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#83683F"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#604926"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#DCB05A">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#DCB05A"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#C09C52"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#F4DF9E">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#F4DF9E"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#E4CF87"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#5F8A8C">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#5F8A8C"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#537579"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#96C4B2">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#96C4B2"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#89B0A0"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#CBE8E7">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#CBE8E7"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#BDD6D5"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#AE6564">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#AE6564"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#875352"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#D88C6F">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#D88C6F"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#C47D61"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#E3C9B0">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#E3C9B0"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#D2B2A5"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#848484">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#848484"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#555555"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#a4a4a4">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#a4a4a4"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#909090"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																							<v2_solidPaletteEntry>
																								<v2_fillEffect defaultColor="#C7C7C7">
																									<v2_linearGradient>
																										<v2_gradientColor gradientColor="#C7C7C7"/>
																										<v2_gradientColor colorPosition="100" gradientColor="#c1c1c1"/>
																									</v2_linearGradient>
																								</v2_fillEffect>
																							</v2_solidPaletteEntry>
																						</v2_solidPaletteEntries>
																					</v2_solidPalette>
																					<!-- v2_solidPaletteRef ref=&amp;amp;quot;gDefaultSolid&amp;amp;quot;/ -->
																					<chartNodes><chartNode><chartNodeMembers><chartNodeMember refDataItem="Revenue"><chartContents><chartTextItem><dataSource><memberCaption/></dataSource></chartTextItem></chartContents></chartNodeMember></chartNodeMembers></chartNode></chartNodes></v2_bar>
																			</v2_combinationChartTypes>
																			<v2_axis>
																				<v2_axisTitle refQuery="Query2">
																					<v2_chartTextContents>
																						<v2_automaticText/>
																					</v2_chartTextContents>
																					<style>
																						<defaultStyles>
																							<defaultStyle refStyle="at"/>
																						</defaultStyles>
																					</style>
																				</v2_axisTitle>
																				<v2_axisLine lineWeight="0"/>
																				<v2_axisRange>
																					<v2_automaticRange/>
																				</v2_axisRange>
																				<v2_axisLabels>
																					<style>
																						<defaultStyles>
																							<defaultStyle refStyle="al"/>
																						</defaultStyles>
																					</style>
																				</v2_axisLabels>
																				<v2_majorGridlines lineWeight="0" lineColor="#CCCCCC"/>
																				<v2_majorBackgroundColors>
																					<v2_firstBackgroundColor color="#D2D2D2" transparency="50"/>
																					<v2_secondBackgroundColor color="#E2E2E2" transparency="50"/>
																				</v2_majorBackgroundColors>
																			</v2_axis>
																		</v2_topLeftAxis>
																		<style>
																			<CSS value=""/><defaultStyles><defaultStyle refStyle="ch"/></defaultStyles></style>
																		<noDataHandler>
																			<contents>
																				<block>
																					<contents>
																						<textItem>
																							<dataSource>
																								<staticValue>No Data Available</staticValue>
																							</dataSource>
																							<style>
																								<CSS value="padding:10px 18px;"/>
																							</style>
																						</textItem>
																					</contents>
																				</block>
																			</contents>
																		</noDataHandler>
																		</v2_combinationChart>
																</contents></conditionalBlock><conditionalBlock refVariableValue="3"><contents><crosstab name="Crosstab1" refQuery="Query2" pageBreakText="false" repeatEveryPage="true">
			<crosstabCorner>
				<contents/>
				<style>
					<defaultStyles>
						<defaultStyle refStyle="xm"/>
					</defaultStyles>
				</style>
			</crosstabCorner>
			
			
			<noDataHandler>
				<contents>
					<block>
						<contents>
							<textItem>
								<dataSource>
									<staticValue>No Data Available</staticValue>
								</dataSource>
								<style>
									<CSS value="padding:10px 18px;"/>
								</style>
							</textItem>
						</contents>
					</block>
				</contents>
			</noDataHandler>
			<style>
				<CSS value="border-collapse:collapse"/>
				<defaultStyles>
					<defaultStyle refStyle="xt"/>
				</defaultStyles>
			</style>
		<crosstabFactCell><contents><textItem><dataSource><cellValue/></dataSource></textItem></contents><style><defaultStyles><defaultStyle refStyle="mv"/></defaultStyles></style></crosstabFactCell><crosstabRows><crosstabNode><crosstabNodeMembers><crosstabNodeMember refDataItem="Product Types" edgeLocation="e1"><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style><contents><textItem><dataSource><memberCaption/></dataSource></textItem></contents></crosstabNodeMember></crosstabNodeMembers></crosstabNode></crosstabRows><crosstabColumns><crosstabNode><crosstabNodeMembers><crosstabNodeMember refDataItem="Revenue" edgeLocation="e2"><style><defaultStyles><defaultStyle refStyle="ml"/></defaultStyles></style><contents><textItem><dataSource><memberCaption/></dataSource></textItem></contents></crosstabNodeMember></crosstabNodeMembers></crosstabNode></crosstabColumns></crosstab></contents></conditionalBlock></conditionalBlockCases></conditionalBlocks></contents><style><CSS value="width:100%;vertical-align:top;text-align:left"/></style></tableCell></tableCells></tableRow></tableRows></table><HTMLItem>
			<dataSource>
				<staticValue>&lt;style&gt;
.Vertical{
  width:'';
  height:'';
}

.VerticalUnselected{
  padding:2px 10px 3px 10px;
  margin-right:7px;
  background-image:url(../reportstyles/images/button_bg.png);
  background-position:left top;
  background-repeat:repeat-x;
  background-color:#EFEFEF;
  color:#000000;
  font-size:10pt;
  font-weight:normal;
  text-align:center;
  border:1px solid #92afc2;
  width: 75px;
  display:block;
}

.VerticalSelected{
  padding:2px 10px 3px 10px;
  margin-right:7px;
  background-image:url(../reportstyles/images/button_bg.png);
  background-position:left top;
  background-repeat:repeat-x;
  background-color:#A0AFEB;
  color:#000000;
  font-size:10pt;
  font-weight:normal;
  text-align:center;
  border:1px solid #92afc2;
  width: 75px;
  display:block;
}

.Horizontal{
  width:0;
  height:0;
  white-space:nowrap;
}

.HorizontalUnselected{
  padding:2px 10px 3px 10px;
  margin-right:7px;
  background-image:url(../reportstyles/images/button_bg.png);
  background-position:left top;
  background-repeat:repeat-x;
  background-color:#EFEFEF;
  color:#000000;
  font-size:10pt;
  font-weight:normal;
  text-align:center;
  border:1px solid #92afc2;
}

.HorizontalSelected{
  padding:2px 10px 3px 10px;
  margin-right:7px;
  background-image:url(../reportstyles/images/button_bg.png);
  background-position:left top;
  background-repeat:repeat-x;
  background-color:#A0AFEB;
  color:#000000;
  font-size:10pt;
  font-weight:normal;
  text-align:center;
  border:1px solid #92afc2;
}

&lt;/style&gt;
&lt;script&gt;

/* 
  * Function: addEvent
  * Author: Dan Fruendel
  * Attachs an event or adds an event listener depending on the browser.
  */
var
  addEvent = function(element, event, func)
  {
    if(element.addEventListener)
    {
      addEvent = function(element, event, func)
      {
        element.addEventListener(event, func, false);
        return true;
      };
    }
    else if(element.attachEvent)
    {
      addEvent = function(element, event, func)
      {
        return element.attachEvent("on" + event, func);
      };
    }
    else
    {
      addEvent = function(element, event, func)
      {
        var oldEventHandler = element['on' + event];
        element['on' + event] = function()
        {
          //using .apply to pass on anything this function gets.
          if(typeof(oldEventHandler) === "function")
          {
            oldEventHandler.apply(element, arguments);
          }
          func.apply(element, arguments);
        }
        return true;
      };
    }
    return addEvent(element, event, func);
  }
/*
 * Fake Namespace and prompt getters.
 */ 	
var paulScripts = {}
  , oCR = cognos.Report.getReport("_THIS_");

paulScripts.getSource = function()
{
    var targ;
    if (!e) var e = window.event;
    if(!e) return false;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ.nodeType == 3) // defeat Safari bug
      targ = targ.parentNode;
    return targ;
}

paulScripts.getControl = function(promptName) {
  return oCR.prompt.getControlByName(promptName);
}

paulScripts.reprompt = function(){
if(!paulScripts.getSource() ) return true;
  oCR.sendRequest(cognos.Report.Action.REPROMPT);
  return true;
}


paulScripts.addButtons = function ( promptName, myClass,reprompt) {
var 
    newOption = ''
  , reprompt = reprompt?reprompt:false
  , id = paulScripts.getControl ( promptName )._id_
  , selElm = document.getElementById('PRMT_SV_'+ id)
  , selElmSelect = document.getElementById('PRMT_SV_LINK_SELECT_'+ id)
  , selElmDeselect = document.getElementById('PRMT_SV_LINK_DESELECT_'+ id)
  , rads = selElm.getElementsByTagName('input')
  , len = rads.length
  , type = len==0?'none':rads[0].type
  , radioClick = function(){for(var radios=paulScripts.getSource().parentNode.getElementsByTagName('input').length/2;radios&lt;paulScripts.getSource().parentNode.getElementsByTagName('input').length;radios++){paulScripts.getSource().parentNode.getElementsByTagName('input')[radios].className=myClass + 'Unselected'};paulScripts.getSource().parentNode.getElementsByTagName('input')[paulScripts.getSource().index].click(); paulScripts.getSource().className=myClass + 'Selected'}
  , checkClick= function(){paulScripts.getSource().parentNode.getElementsByTagName('input')[paulScripts.getSource().index].click(); paulScripts.getSource().className=paulScripts.getSource().className==myClass + 'Selected'?myClass + 'Unselected':myClass + 'Selected';}
  , selectAll= function(){ for(var elms=rads.length;elms&gt;rads.length/2;elms--){rads[elms-1].className=myClass + 'Selected'}}
  , deselectAll= function(){ ; for(var elms=rads.length;elms&gt;rads.length/2;elms--){rads[elms-1].className=myClass + 'Unselected'}}
;
  selElm.className = myClass;

  if(type == 'none') return false;

  for(i=0;i&lt;len;i++)
  {
    newOption = document.createElement( 'input');
    newOption.type='button';
    newOption.value=rads[i].getAttribute('dv');
    newOption.className=rads[i].selected?myClass + 'Selected': myClass + 'Unselected';
    newOption.index=i;
    if(type=='checkbox') {addEvent(newOption,'click',checkClick)};
    if(type=='radio') {addEvent(newOption,'click',radioClick)};
    rads[i].parentNode.parentNode.style.display='none';
    selElm.appendChild(newOption );
  }

  if(reprompt) paulScripts.getControl ( promptName ).setValidator(paulScripts.reprompt);

  if(selElmSelect) addEvent(selElmSelect,'click',selectAll);
  if(selElmDeselect) addEvent(selElmDeselect,'click',deselectAll);
}

paulScripts.addButtons('Products','Horizontal',1);

paulScripts.addButtons('Reports','Vertical');
&lt;/script&gt;</staticValue>
			</dataSource>
		</HTMLItem></contents>
								</pageBody>
							</page>
						</reportPages>
					</layout>
				</layouts>
			<XMLAttributes><XMLAttribute name="RS_CreateExtendedDataItems" value="true" output="no"/><XMLAttribute name="listSeparator" value="," output="no"/><XMLAttribute name="RS_modelModificationTime" value="2008-07-25T15:28:38.133Z" output="no"/></XMLAttributes><classStyles><classStyle name="cls1" label="Button1"><CSS value="padding:2px 10px 3px 10px;margin-right:7px;background-image:url(../reportstyles/images/button_bg.png);background-position:left top;background-repeat:repeat-x;background-color:#CCFFCC;color:#000000;font-size:10pt;font-weight:normal;text-align:center;border:1px solid #92afc2"/></classStyle></classStyles><reportName>radios to buttons</reportName><queries><query name="Query2"><source><model/></source><selection><dataItem name="Product Types"><expression>descendants(
#promptmany('Products','mun','[sales_and_marketing].[Products].[Products].[Products]-&gt;:[PC].[@MEMBER].[Products]','set(','',')')#
,[sales_and_marketing].[Products].[Products].[Product type]
)</expression></dataItem><dataItemMeasure name="Revenue"><dmMember><MUN>[sales_and_marketing].[Measures].[Revenue]</MUN><itemCaption>Revenue</itemCaption></dmMember><dmDimension><DUN>[sales_and_marketing].[Measures]</DUN><itemCaption>Measures</itemCaption></dmDimension><XMLAttributes><XMLAttribute name="RS_dataType" value="9" output="no"/></XMLAttributes></dataItemMeasure></selection></query><query name="Products"><source><model/></source><selection><dataItem name="Product line" aggregate="none"><expression>[sales_and_marketing].[Products].[Products].[Product line]</expression></dataItem></selection></query></queries><reportVariables><reportVariable type="string" name="ReportType">
			<reportExpression>ParamValue('ReportType')</reportExpression>
		<variableValues><variableValue value="1"/><variableValue value="2"/><variableValue value="3"/></variableValues></reportVariable></reportVariables></report>

Quickie: Referencing the prompt DOM element with the Cognos 10.2 Prompt API

With all of the nice things in the new API, there are still a few annoyances. For instance, the functions for adding values only work on textboxes, meaning you can’t programmatically add and remove elements. You also can’t easily move things around, or flip switches, or do any of the normal things you would do with Javascript.

Poking through the JS files, I did find a few things that should make life easier. Today I had an issue where I had to make a value prompt to allowing users the choice of viewing the report YTD or for the entire year. The cube has a nice hierarchy for that, with the captions yes/no or the all level for everything (yes, I know the cube could have been designed so that the No choice shows the entire year, this is a post about JS not OLAP so shush). The issue is that the users want to select “Everything” or “Until December 11”. The everything choice is fairly easy, it’s a static choice with the display set to “Everything”. The “Until December 11” is more difficult, the caption should change every day. Instead of altering the cube to put in a dynamic caption, I opted to use another static choice (this way I don’t need to go to the cube at all), and change the option text with JS.

In order to do this, I need to find the prompt on the page. The ID for the prompt itself is “PRMT_N19F64920x0B67C9E4RS” but that looks like it will change every time the report is run, how can I guarantee that I will always be able to access that. Keep in mind that I’m incredibly lazy, and don’t want to spend the time wrapping the prompt with my own uniquely identified div (because then I’d have to keep track of all of the div IDs, and make sure to move the HTML items when I move the prompt and it’s just too much of a hassle). Surely there must be an easier way.

It turns out that you can get the ID of the prompt with the Prompt API:

var acme = {};
acme.getControl = function(promptName)
{
  var ocr = cognos.Report.getReport("_THIS_");
  return ocr.prompt.getControlByName(promptName);
};
alert(acme.getControl('FilterType')._id_);

That would return N19F64920x0B67C9E4RS.

So that means that we can very easily modify the text of the prompt:

<script>
var acme = {};
acme.getControl = function(promptName)
{
  var ocr = cognos.Report.getReport("_THIS_");
  return ocr.prompt.getControlByName(promptName);
};

Date.prototype.getMonthName = function() {
  var monthNames = [ 'January','February','March','April','May','June','July','August','September','October','November','December'];
  return monthNames[this.getMonth()];
}

var dt = new Date(), 
    dtCaption = 'Until ' + dt.getMonthName() + ' ' + dt.getDate();

document.getElementById('PRMT_' + acme.getControl('FilterType')._id_).getElementsByTagName('OPTION')[1].dv = dtCaption;
document.getElementById('PRMT_' + acme.getControl('FilterType')._id_).getElementsByTagName('OPTION')[1].innerHTML = dtCaption;
</script>

This will change the display value (dv) and the label (innerHTML) with Until December 11 (or whatever the current date is).

Cognos Prompt API

Well, it’s been a week since I’ve returned from the IOD, and I’m almost fully recovered from the jet-lag. I had an absolute blast, and am looking forward to going back next year.

I promised more details on the various booths that I went to, and I do have the various papers that they gave me. I will eventually get to them! But before I do, this is what I started writing while I was at the IOD, but only now am I getting around to actually publishing it.

One of the most exciting new features in Cognos 10.2 is the introduction of a standardized prompt api. No longer will developers have to scramble to try to figure out how to get validate prompts at run time. Or how to repopulate them as needed through other interactions.

IBM has released a standard set of functions, and has even released a few samples containing them. The goal in this post is to learn how to use the new API and maybe to redo a few challenges I’ve had previously.

Just as previous version required a bit of JavaScript to prepare your page for playing with the prompt objects, this version is no different. What is different, is that instead of having to memorize the entire fW formWarpRequest nonsense, now it’s a much simpler:

var acme = {};
acme.getControl = function(promptName) 
{
  var ocr = cognos.Report.getReport("_THIS_");
  return ocr.prompt.getControlByName(promptName);
};

The acme namespace is to prevent function conflicts with existing Cognos functions, just preface all functions with that and you’ll be good. The “_THIS_” will automatically be replaced with the correct Cognos Namespace, so your JavaScript should still work if you’re running the report from Report Studio or the Cognos Connection. This never ever needs to change, so just copy and paste the above (although employees of Acme Inc may want to change the fictious namespace). This solution was shamelessly ripped from Rick Blackwell’s wonderful session at the IOD. All credit for anything and everything related to Cognos and JavaScript should obviously go to him now.

To begin with, let’s use Rick’s standard example for Postal Code validation.

 	/*
	 *
	 * This function will associate a validation function with the prompt control called promptPostalCode
	 *
	 */
	asdf.assignValidator = function ( ) {
		// Create the report object
		oCR = cognos.Report.getReport( "_THIS_" );

		// Create an array of prompt controls
		// This object is used in both functions in this script.
		asdf.promptControlPostalCode = oCR.prompt.getControlByName("promptPostalCode");

		// Make sure we have a valid Postal Code in the format "ana nan" such as K3F 5F4
		asdf.promptControlPostalCode.setValidator(asdf.postalCodeValidator);

	};


	/*
	 *
	 * This function is called for each character entered by the user.
	 * Ensure the value is a valid Postal Code (ie. A1A 1A1 with spaces) using RegEx.
	 *
	 */
	asdf.postalCodeValidator = function(promptValue) {
		//promptValue is an array of 1 value

		// If a value has been entered by the user ensure it matches the pattern
		if (promptValue.length > 0) {
			var rePostalCodeFormat = new RegExp("[a-z][0-9][a-z] [0-9][a-z][0-9]", "gi" );
			if ( rePostalCodeFormat.test(promptValue[0].use) ) {
				return true;
			} else {
			    return false;
			}
		} else {
		 	// If the prompt contains no value it is valid.
			// This is important as the prompt and filter are optional
			return true;
		}
	};

His example is a bit complicated, but it’s good to demonstrate the capabilities.

The first function finds the promptPostalCode prompt, and assigns the validator. Now when a user enters a value, it will trigger the validator function, passing the entered value.
The second function will take the entered value compare it against the regex, and return a true/false, telling Cognos whether the finish button should be active, and if there should be a red underline in the prompt object.

Of course, this is not the only thing that can be done with the validator function. The validator gives us an easy to use onchange function for the prompts.

A few of my clients want tree prompts which automatically hides after a user has selects a member. Previously, there were a few was this could be accomplished, each of them more difficult than the last. But now, instead of using the JS to validate, I can use the validate function to hide the prompt after a few seconds.

First I create an HTML item containing span with an ID:

<span id="treeLabel" onclick="acme.toggleTree()">Tree Prompt</span>

Next, I wrap the tree prompt inside a span with boxtype set to none:

<span id="treePrompt" style="display:none">

</span>

First a function to directly toggle the display of the tree prompt:

acme.toggleTree = function()
{
document.getElementById('treeprompt').style.display=document.getElementById('treeprompt').style.display=='none'?'block':'none';
}

Next, the actual validation function:

/*
 * function hideTree. Paul Mendelson - 2012-10-22
 * Whenever a tree node is clicked, it will wait {acme.hideTimer} seconds before hiding
 * the tree. If another selection is made, it will restart the counter.
 */
acme.hideTree= (function () {
  var timer;
  var elm;
  return function (){
    clearTimeout(timer);
  var promptName = this.getName();

    //standard way of determing source of click.
    var targ;
    if (!e) var e = window.event;
    if(!e) return false;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ.nodeType == 3) // defeat Safari bug
      targ = targ.parentNode;

    timer = window.setTimeout(function() {  
      document.getElementById('treePrompt').style.display='none';
      document.getElementById('treeLabel').innerHTML = acme.getControl('Time').getValues()[0].display;
    },acme.hideTimer);
    return true;
    };
})();

Notice that it’s not actually doing any validation; it’s simply returning true. Notice that it’s also sending the label of the selected node to the tree label. Ultimately the new Prompt API makes it significantly easier to build complex reports.

Example XML:

<report xmlns="http://developer.cognos.com/schemas/report/9.0/" useStyleVersion="10" expressionLocale="en-us">
				<modelPath>/content/folder[@name='Samples']/folder[@name='Cubes']/package[@name='Sales and Marketing (cube)']/model[@name='2008-07-25T15:28:38.072Z']</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><textBox parameter="Parameter1" name="textBox" multiSelect="true"/><HTMLItem description="Label">
			<dataSource>
				<staticValue>&lt;span id="treeLabel" onclick="acme.toggleTree()"&gt;Tree Prompt&lt;/span&gt;
&lt;span id="treePrompt" style="display:none"&gt;</staticValue>
			</dataSource>
		</HTMLItem><selectWithTree parameter="Time" refQuery="Time" name="Time"><selectWithTreeItem refDataItem="Time"/></selectWithTree><HTMLItem description="scripts">
			<dataSource>
				<staticValue>&lt;/span&gt;
	
&lt;script&gt;



/*
 * Fictious Namespace and getter. Don't change these unless IBM says so or you know what you're doing.
 * acme is now the official standard fictious namespace (thanks Rick), so make sure all functions sit there.
 * This is based on the samples, so I'm giving all credit to Rick Blackwell of IBM.
 */
var acme = {};
acme.getControl = function(promptName) 
{
  var ocr = cognos.Report.getReport("_THIS_");
  return ocr.prompt.getControlByName(promptName);
};

/*
 * Global Params
 * Paul Mendelson 2012-28-10
 * These control the behaviour of the functions below. 
 */

//Time in miliseconds to wait before prompt disappears.
acme.hideTimer = 1000;


/*
 *  This will return any available methods or functions or whatever available on the referenced object.
 */ 
function getMethods(myObject)
{
  var funcs=[]
  for(var name in myObject)
  {
    funcs.push(name)
  }
  return  funcs.join(', ');
}

/*
 * Hide the prompt when validating
 */

/*
 * function hideTree. Paul Mendelson - 2012-10-22
 * Whenever a tree node is clicked, it will wait {acme.hideTimer} seconds before hiding
 * the tree. If another selection is made, it will restart the counter.
 */
acme.hideTree= (function () {
  var timer;
  var elm;
  return function (){
    clearTimeout(timer);
  var promptName = this.getName();

    //standard way of determing source of click.
    var targ;
    if (!e) var e = window.event;
    if(!e) return false;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ.nodeType == 3) // defeat Safari bug
      targ = targ.parentNode;

    timer = window.setTimeout(function() {  
      document.getElementById('treePrompt').style.display='none';
      document.getElementById('treeLabel').innerHTML = acme.getControl('Time').getValues()[0].display;
    },acme.hideTimer);
    return true;
    };
})();

acme.toggleTree = function()
{
  document.getElementById('treeprompt').style.display=document.getElementById('treeprompt').style.display=='none'?'block':'none'
}



/*acme.checkPostalCode = function()
{
  var rePostalCodeFormat = new RegExp( "[a-z][0-9][a-z] [0-9][a-z][0-9]", "gi" );
  if(rePostalCodeFormat.test(this.getValue())) return true;
  return false;
}
*/
acme.checkPostalCode = function()
{
  var rePostalCodeFormat = new RegExp( '^[0-9]{0,3}$', "gi" );
  if(rePostalCodeFormat.test(this.getValue())) return true;
  return false;
}
acme.getControl('textBox').setValidator(acme.checkPostalCode);
acme.getControl('Time').setValidator(acme.hideTree);
&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="2008-07-25T15:28:38.133Z" output="no"/></XMLAttributes><queries><query name="Time"><source><model/></source><selection><dataItem name="Time" aggregate="none"><expression>rootMembers([sales_and_marketing].[Time].[Time])</expression></dataItem></selection></query></queries><reportName>Paul - Tree prompt</reportName></report>

Cognos 10.1.1 bug: Charts breaking when switching between tabs

An annoying bug has been reported by several of my clients.

Any portal tab containing a chart will occasionally break when the user clicks away then returns:

If the user were to click on Public Folders, then return to the portal tab, suddenly the chart images are broken.

While I can’t explain why this is happening, I’m guessing that Cognos is flushing the image from the cache when the user leaves the page. When the user returns the image is no longer in the cache, so it’s returns a broken image.

Fortunately the refreshing the report will return the chart so this gives us a partial solution. If we can write a script that detects the state of the image (if it’s broken or not) we can have the portlet refresh.

First the report should be wrapped in a div with the display set to none. This will prevent users from seeing the broken charts. Second the chart itself should be wrapped in a div to give the function a place to start looking for broken images.

The function itself is fairly simple:

function checkImg()
{
var reportWrapper = document.getElementById('reportWrapper');
var chartWrapper = document.getElementById('chartWrapper');
var message = document.getElementById('message');
var img = chartWrapper.getElementsByTagName('IMG');
message.innerHTML = "checking image";
if (img[0].readyState == 'uninitialized') {refreshReport();message.innerHTML = "refreshing report";} 
else {reportWrapper.style.display="";message.innerHTML = "";}

}

It checks the image’s readyState attribute. If it’s unitialized, the image is broken and the report should be refreshed, otherwise everything is fine and show the report.

The refresh function is from one of the IBM knowledge base articles.

function refreshReport()
{
var intval;
var fW = (typeof getFormWarpRequest == "function" ? getFormWarpRequest() : document.forms["formWarpRequest"]);
if ( !fW || fW == undefined)  
{

    fW = ( formWarpRequest_THIS_ ? formWarpRequest_THIS_ : formWarpRequest_NS_ );

}
var preFix = "";
if (fW.elements["cv.id"])
{

    preFix = fW.elements["cv.id"].value;

}    
var nameSpace = "oCV" + preFix;
if(intval!="")
{

    self.clearInterval(intval);
    intval="";

}
self["RunReportInterval"] = self.setInterval( nameSpace + ".getRV().RunReport()",'0' );
intval = self["RunReportInterval"];
}

Finally the checkImg function needs to be called. It can’t be called as soon as the page is loaded, because the chart image itself takes a moment to load. If the function is called before the chart is loaded, it will refresh the page in an infinite loop. Instead it’s best to wait a moment. I find that 1 second works well.

setTimeout("checkImg()",1000);

Now when the page loads it will wait 1 second and check the chart. If the image is broken it will refresh the page:

It’s worth mentioning that this is a band-aid solution (and not a great one either). The true fix needs to come from IBM. There is an APAR open for this issue, but so far no hotfix. Slower computers may take longer to load the image, and may result in the user being stuck in an infinite loop. Additionally the report will only display after the function has a chance to check the image, effectively increasing the load time of the report by however long is set in the setTimeout.

Report XML: (Remember to create a page and add this to a cognos viewer)

<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"/>
				<queries>
					<query name="Query1">
						<source>
							<model/>
						</source>
						<selection><dataItem name="Gross margin" aggregate="automatic"><expression>[Sales (query)].[Gross margin]</expression><XMLAttributes><XMLAttribute name="RS_dataUsage" value="fact" output="no"/></XMLAttributes></dataItem><dataItem name="Product line" aggregate="none" rollupAggregate="none"><expression>[Sales (query)].[Products].[Product line]</expression><XMLAttributes><XMLAttribute name="RS_dataType" value="3" output="no"/><XMLAttribute name="RS_dataUsage" value="attribute" output="no"/></XMLAttributes></dataItem></selection>
					</query>
				</queries>
				<layouts>
					<layout>
						<reportPages>
							<page name="Page1"><style><defaultStyles><defaultStyle refStyle="pg"/></defaultStyles></style>
								<pageBody><style><defaultStyles><defaultStyle refStyle="pb"/></defaultStyles></style>
									<contents>
										<HTMLItem description="report Display None">
			<dataSource>
				<staticValue>&lt;div id="reportWrapper" style="display:none"&gt;</staticValue>
			</dataSource>
		</HTMLItem><HTMLItem description="Chart Wrapper">
			<dataSource>
				<staticValue>&lt;div id="chartWrapper"&gt;</staticValue>
			</dataSource>
		</HTMLItem><combinationChart showTooltips="true" maxHotspots="10000" refQuery="Query1" name="Combination Chart1">
								<legend>
									<legendPosition>
										<relativePosition/>
									</legendPosition>
									<legendTitle refQuery="Query1">
										<style>
											<defaultStyles>
												<defaultStyle refStyle="lx"/>
											</defaultStyles>
										</style>
									</legendTitle>
									<style>
										<defaultStyles>
											<defaultStyle refStyle="lg"/>
										</defaultStyles>
									</style>
								</legend>
								<ordinalAxis>
									<axisTitle refQuery="Query1">
										<style>
											<defaultStyles>
												<defaultStyle refStyle="at"/>
											</defaultStyles>
										</style>
									</axisTitle>
									<axisLine color="black"/>
									<style>
										<defaultStyles>
											<defaultStyle refStyle="al"/>
										</defaultStyles>
									</style>
								</ordinalAxis>
								<numericalAxisY1>
									<axisTitle refQuery="Query1">
										<style>
											<defaultStyles>
												<defaultStyle refStyle="at"/>
											</defaultStyles>
										</style>
									</axisTitle>
									<gridlines color="#cccccc"/>
									<axisLine color="black"/>
									<style>
										<defaultStyles>
											<defaultStyle refStyle="al"/>
										</defaultStyles>
									</style>
								</numericalAxisY1>
								<combinationChartTypes>
									<bar/>
								</combinationChartTypes>
								<style>
									<defaultStyles>
										<defaultStyle refStyle="ch"/>
									</defaultStyles>
								</style>
							<commonClusters><chartNodes><chartNode><chartNodeMembers><chartNodeMember refDataItem="Product line"><chartContents><chartTextItem><dataSource><memberCaption/></dataSource></chartTextItem></chartContents></chartNodeMember></chartNodeMembers></chartNode></chartNodes></commonClusters><defaultChartMeasure refDataItem="Gross margin"/></combinationChart>
									<HTMLItem description="closing divs and script">
			<dataSource>
				<staticValue>&lt;/div&gt;
&lt;/div&gt;
&lt;div id="message"&gt;
&lt;/div&gt;
&lt;script&gt;

function checkImg()
{
var reportWrapper = document.getElementById('reportWrapper');
var chartWrapper = document.getElementById('chartWrapper');
var message = document.getElementById('message');
var img = chartWrapper.getElementsByTagName('IMG');
message.innerHTML = "checking image";
if (img[0].readyState == 'uninitialized') {refreshReport();message.innerHTML = "refreshing report";} 
else {reportWrapper.style.display="";message.innerHTML = "";}

}

function refreshReport()
{
var intval;
var fW = (typeof getFormWarpRequest == "function" ? getFormWarpRequest() : document.forms["formWarpRequest"]);
if ( !fW || fW == undefined)  
{

    fW = ( formWarpRequest_THIS_ ? formWarpRequest_THIS_ : formWarpRequest_NS_ );

}
var preFix = "";
if (fW.elements["cv.id"])
{

    preFix = fW.elements["cv.id"].value;

}    
var nameSpace = "oCV" + preFix;
if(intval!="")
{

    self.clearInterval(intval);
    intval="";

}
self["RunReportInterval"] = self.setInterval( nameSpace + ".getRV().RunReport()",'0' );
intval = self["RunReportInterval"];
}

setTimeout("checkImg()",1000);
&lt;/script&gt;
</staticValue>
			</dataSource>
		</HTMLItem></contents>
								</pageBody>
								<pageHeader>
									<contents>
										<block><style><defaultStyles><defaultStyle refStyle="ta"/></defaultStyles></style>
											<contents>
												<textItem><style><defaultStyles><defaultStyle refStyle="tt"/></defaultStyles></style>
													<dataSource>
														<staticValue>This works</staticValue>
													</dataSource>
												</textItem>
											</contents>
										</block>
									</contents>
									<style>
										<defaultStyles>
											<defaultStyle refStyle="ph"/>
										</defaultStyles>
										<CSS value="padding-bottom:10px"/>
									</style>
								</pageHeader>
								<pageFooter>
									<contents>
										<table>
											<tableRows>
												<tableRow>
													<tableCells>
														<tableCell>
															<contents>
																<date>
																	<style>
																		<dataFormat>
																			<dateFormat/>
																		</dataFormat>
																	</style>
																</date>
															</contents>
															<style>
																<CSS value="vertical-align:top;text-align:left;width:25%"/>
															</style>
														</tableCell>
														<tableCell>
															<contents>
																<pageNumber/>
															</contents>
															<style>
																<CSS value="vertical-align:top;text-align:center;width:50%"/>
															</style>
														</tableCell>
														<tableCell>
															<contents>
																<time>
																	<style>
																		<dataFormat>
																			<timeFormat/>
																		</dataFormat>
																	</style>
																</time>
															</contents>
															<style>
																<CSS value="vertical-align:top;text-align:right;width:25%"/>
															</style>
														</tableCell>
													</tableCells>
												</tableRow>
											</tableRows>
											<style>
												<defaultStyles><defaultStyle refStyle="tb"/></defaultStyles>
												<CSS value="border-collapse:collapse;width:100%"/>
											</style>
										</table>
									</contents>
									<style>
										<defaultStyles>
											<defaultStyle refStyle="pf"/>
										</defaultStyles>
										<CSS value="padding-top:10px"/>
									</style>
								</pageFooter>
							</page>
						</reportPages>
					</layout>
				</layouts>
			<XMLAttributes><XMLAttribute name="RS_CreateExtendedDataItems" value="true" output="no"/><XMLAttribute name="listSeparator" value="," output="no"/><XMLAttribute name="RS_modelModificationTime" value="2011-06-09T13:50:33.233Z" output="no"/></XMLAttributes><reportName>Test 1</reportName></report>