This solution was built on 10.2.1.1, but should work on all versions after 10.2. Versions prior to 10.2 will need some rewriting as this is based on the Prompt API.
One of the biggest complaints I get about search prompts is the amount of real estate they take from reports. The multiselect prompts are huge, and users hate them for it. So I was asked to find a way to shrink it down.
Obviously the solution was to everything but the search input and button. The keyword and instruction text can be controlled by the properties, simply setting it to “Specified Text” is sufficient to hide them:
That leaves the Options link and the search results. Personally I don’t believe the results list need to appear unless there are actually results. The options should be at the mercy of the report author, so my solution includes a way to choose a default value and to hide the options.
First a look at the JS
/* function paulScripts.advancedSnS - Paul Mendelson - 2013-09-16 * Will convert a standard search and select. It will add a button to expand/collapse the * are selection area. The button will display how many matches have been found, and how * many selected. * * The Option param will control the default search method. * 1 = Starts with any of these keywords **DEFAULT** * 2 = Starts with the first keyword and contains all of the remaining keywords * 3 = Contains any of these keywords * 4 = Contains all of these keywords * * Hide the options link by setting 1 in the hideOption param. */ paulScripts.advancedSnS = function(promptName,option,hideOption){ var prompt = paulScripts.getControl(promptName) , elm = document.getElementsByName(prompt.getParameterName())[0].parentNode , selectTable = elm.getElementsByTagName('table')[4] , selectDiv = document.createElement('div') , selectOptions = cognos.Report.getReport("_THIS_").prompt.getControlByName(promptName).getSelectOptions() , selectChoices = cognos.Report.getReport("_THIS_").prompt.getControlByName(promptName).getSelectChoices() , tr = elm.getElementsByTagName('button')[0].parentNode.parentNode.parentNode.appendChild(document.createElement('tr')) , td= tr.insertCell(0) , slideDiv = document.createElement('div') , btn = document.createElement('input'); if(option) elm.getElementsByTagName('input')[option+2].checked=true; if(hideOption) tr.parentNode.parentNode.parentNode.parentNode.nextSibling.style.display='none'; td.setAttribute('colSpan',2); //Hacky – Building a new dispatcher request to save the state of the SnS. Do any IBMers have any comments? if(typeof oReq ==='undefined') oReq = new ViewerDispatcherEntry(window['oCV'+'_THIS_'].getRV().getCV()); if(!oReq.getFormFields().m_aValues[promptName]) oReq.addFormField(promptName,'hidden') btn.type='button'; btn.value=''; if(!selectOptions&&!selectChoices) btn.value='click to open'; if(selectOptions) btn.value = selectOptions.length + ' found. '; if(selectChoices) btn.value += selectChoices.c.length + ' selected.'; selectTable.parentNode.insertBefore(selectDiv,selectTable); selectDiv.appendChild(selectTable); //the right side of the table is a bit ugly; not enough padding. selectDiv.style.paddingRight='5px'; // Sets the table of the select options to position absolute. This will prevent the page from expanding vertically // when the table is visible; selectDiv.style.position='absolute'; selectDiv.style.overflow='hidden'; selectDiv.style.backgroundColor='white'; btn.onclick = function() { if(selectDiv.style.visibility=='hidden') {slidedown(selectDiv); oReq.addFormField(promptName,'visible');} else {slideup(selectDiv);oReq.addFormField(promptName,'hidden');} return true; } selectDiv.style.visibility=oReq.getFormFields().m_aValues[promptName]; td.appendChild(btn); return true; }
The JS itself is fairly straight forward. The variables define the DOM element, a JSON array of the found options, another JSON array of the selected objects, and a couple of generated elements.
If a default search option is selected, it will set that.
if(option) elm.getElementsByTagName('input')[option+2].checked=true;
If hideOption is set to true, it will hide the options link.
if(hideOption) tr.parentNode.parentNode.parentNode.parentNode.nextSibling.style.display='none';
Then it will insert a button, and finally the “results” lists are moved into a generated div which can then be slid open or shut.
td.appendChild(btn);
Whenever I create a solution that changes the appearance of the page, showing or hiding an element, the users demand that the change persist through a page reset. The easiest way would be to create a new parameter to store the display state. Possibly a hidden text box with box type set to none. But if we always did things the easy way, we’d never learn anything.
//Hacky – Building a new dispatcher request to save the state of the SnS. Do any IBMers have any comments? if(typeof oReq ==='undefined') oReq = new ViewerDispatcherEntry(window['oCV'+'_THIS_'].getRV().getCV()); if(!oReq.getFormFields().m_aValues[promptName]) oReq.addFormField(promptName,'hidden')
I haven’t tested this on a wide scale, so I don’t know of any performance impact. To be honest, while I love figuring out little hacks like these, without a more in-depth understanding of what it’s doing, it may not be wise to push this to all reports. The attached report contains two functions, the first using the hacky dispatcher request, and the second using a secondary text box to retain the state. The disadvantage of using the text box is that you’ll need to remember to add that in.
Once the JS is in place, we can call the functions with a simple:
paulScripts.advancedSnS ('Retailers', 3,1);
It will look for the prompt named Retailers, set the option to “Contains any of these keywords”, and hide the options link.
And the final product:
Report XML:
Advanced SnS (4749 downloads)
Hi Paul,
this solution works fine !
But as we’d like to put 3 SnS in a row, we’d like to make it less large.
So is that imaginable to get rid of the search button on the right and to put it somewhere else (below the search input for example) ?
Hi Gocho,
Moving the button is fairly easy. First you need to find the button. Add the following to the var list (elm=document.getElementsByName()):
, searchButton = elm.getElementsByTagName(‘button’)[0]
Now that you have the button, you can move it to wherever you want. In the var list, we’re creating a new row and cell, so let’s move the button into there.
After the var list (after btn=document.createElement(‘input’);) add the following:
td.appendChild(searchButton);
That will put it immediately under the search input.
Nice !
Thanks a lot !
Is it possible to resize the results and selected results ?
We’d like to make them larger to display larger values.
And last but not least : Is there any documentation you use to give all these informations or is it just a lot of experience ?
There’s no documentation, mostly it’s a matter of experience. IE Dev Toolbar is an invaluable tool when building reports. Simply run the report, press F12, and explore the DOM structure. You can test various scripts by using the script tag. To answer your question, the easiest way to resize the result inputs would be to identify them using getElementsByTagName(‘select’), and modifying the inline style. something like
elm.getElementsByTagName('select')[0].style.width='auto';
That will find the first select inside elm, and set the width to auto.
Nice!
Is it possible for you to provide a step by step process to implement this in the report. I am unable to open the report form your XML. I am using 10.2 if this helps.
Regards
download should be fixed now.
Hi Paul, i am not able to download the report xml from above link. Is the link broken?
Should be fixed now.
Can I get a copy of the report. It will not download for me! Thanks
Try again now
This works only on the page and not on the prompt page
Hi Paul,
This script doesnt work in cognos connection. I have used it in Report Prompt page and works fine while running report from report studio. Any idea why it fails to run the script in cognos Connection running reports
Message: Unable to get value of the property ‘getRV’: object is null or undefined
Line: 397
Char: 33
This is the error in detail
Found the issue. its with below line
if(typeof oReq ==’undefined’) oReq = new ViewerDispatcherEntry(window[‘oCV’+’RV’].getRV().getCV());
Just replaced it with
if(typeof oReq ==’undefined’) oReq = new ViewerDispatcherEntry(window[‘oCV’+’_THIS_’].getRV().getCV());
Hi Paul,
Thanks for all your excellent tips and tricks!
I don’t get this to work in an portalpage report (cognos viewer), do you know if it is possible? I just get an malfunctioning search and select prompt when I use this code in it…
/Mat
Yeah, I’ve also had trouble with this. It looks like a bug with the API – the function to identify the dom element breaks after the page refreshes. So it works the first time, but not the second run. Does that jibe with the issues you’re experiencing?
Hi Mat and Paul,
I had same issue running this code in cognos viewer and Scheduler window. The modification i have posted made this work. Here is my working code
Nice one Gopi!
Hi CognosPaul,
I’m using this javascript code to define a default select on SnS prompt.
document.getElementById(‘mySpan1’).getElementsByTagName(‘input’)[4].click();
However, if user selects another option and do a search, the prompt backs to mark the default option instead of to keep the previous selected option, like works a native SnS prompt.
Do you have any idea to improve this code to accept this behavior?
Thanks in advance.
One of the tricks you could use is to create a hidden text prompt. If the user changes the selection, set the value of the prompt to 1. On the HTML item, set a render variable on the script, or a script that checks the value of the text prompt, so it doesn’t run if the user selected a value.
Hi Paul , Gopi
i just saw your code,all i need is just to enable and disable the Result box that comes next to the search box in select and search prompt.i don’t want the default value/the count that found .I just need to enable and disable the resultant box on click. Basically it should be in disabled status so if i need to see the searched item then i will click on the button.
kindly help me.
Hi,
This solution works perfectly fine, but I recently got a problem with it.
I’m just using a part of it to change the default option ant to hide the sns options.
With this, when I create a report view and filling the prompts, I can’t launch the report (button is unavailable)
Problem seems to be connected to the variable gateway.
I’ll check tomorrow if the upgrade proposed by Gopi has been implemented.
Meanwhile I’m wondering what is the purpose of this variable (i found “he gateway variable is pulling the gateway from the report you’re running. Another gateway could be entered here, if needed.” on another topic but that doesn’t help me much.)?
What if I just delete it from the script (I tried and this worked, but i’d like to know why and if that could be problematic)?
thanks,
Gocho
The gateway variable is used in other solutions, and can be safely deleted from this one. Usually that variable is used when running reports with the cognosLaunch method. It specifies against which gateway a report should be run. This is useful in wide distributed environments or in environments where certain types of reports should be run against specific gateways.
Hi cognospaul,
Nice article!!!
It works perfectly with the report studio report.
I want to use the same prompt in my Cognos workspace dashboard, however this solution doesnt work properly there.
Can you please tell what changes I need to make, to run this code perfectly in Cognos workspace ?
Hi Cognospaul
Very nice code!! Congrats man!
Prompt works perfect, but when tried to rerun the report using rerun once output is generated. unable to clear out the previous search values.. Do you have any fix here..? Tries using clearAllvalues from 10.2 API but still seems to be some where array is storing one value from previous search.
This code seems to have issue when re-running the report. This retains the previous values. Tries removing/clearning values using clearvalues(); but still a single value from previous selection is retained. Any solution/Fix out there for this issue?
Hi!
Im trying to create an autcomplete text box prompt. Its will filter the data from the lowest level of a dimension and should be optional. Any tips or directions where to go?
Br
Peter
Hi ! Paul
Thank you for such a great solution, unfortunately it is not working for me in Cognos 10.2.2 or in 11.0.12
Any idea why it is not working
In Version 11, i get error
XMLSyntaxError: xmlParseEntityRef: no name, line 257, column 55
In 10.2.2 no errors but the options is not hidden
Thank you
Sanjay
Hi Sanjay,
My first guess is that you don’t have interactive mode disabled. There’s a parser that disallows scripts in interactive mode. Disable that and try the script again.
Hello Paul,
thanks for this code.
I would like if you try to use it on 2 different pages and then activate the “View pages as tabs” property at the Report level ?
Without it’s working on the 2 pages, but when the property is enable it’s only working on the first page.
I guess it’s because there is no a full reload of the report.
Any idea ?
Or do you think we can develop the same behaviour with the new custom control ?
regards,