Search code examples
cognoscognos-10

Cognos 10 Report Studio: On Page Prompts & Performance


I have a report page which displays a crosstab. This is filtered by 5 paramaters. These paramaters are submitted by the user through on page checkbox prompts.

The requirement is to return the data with all values in all paramaters selected on the first run. If I leave default selections blank this behaviour is achieved but all the checkboxes are unchecked which gives misleading feedback to the user.

As an alternative I've manually specified all the values in default selections. However, this has a performance impact.

Does anyone have any alternative suggestions?

I've been looking for a way to specifically link a reprompt button to a value list so only those paramaters are resubmitted (rather than the whole page) but haven't found anything yet.

Thanks in advance - even if the answer is 'no and this is a bad way to go about it'!


Solution

  • One option is to use JavaScript to check all of the checkboxes after the page is rendered with no filtering applied. To do this all filters have to be set to optional. The page is rendered with all data and unchecked checkboxes. The JavaScript fires and checks all checkboxes so that the state of the prompts matches the state of the data. This happens so fast the user likely won't know the boxes weren't checked initially. A reprompt button will, when clicked, enforce whatever choices the user makes after that.

    Since version 10.2, Cognos has provided a fairly simple JavaScript API to allow for render-time manipulation of prompt controls. Hopefully, you are working with 10.2 or later otherwise the code provided will not work. Here is a bit of JavaScript code that will loop through all prompts and select all values within them:

    var report = cognos.Report.getReport("_THIS_");
    var prompts = report.prompt.getControls();
    
    if (typeof firstrun == "undefined") {
        var values;
        for (var i=0;i<prompts.length;i++) {
            values = prompts[i].getValues(true);
            prompts[i].addValues(values);
        }
        var firstrun = false;
    }
    

    Notes:

    All value prompts behave the same way regarding the 10.2+ JavaScript Prompt API. It doesn't matter whether you choose a drop-down, list, checkbox or radio button interface. The way we code for all of these variations is the same. The provided code would work just as well with a list as it would with checkboxes.

    Make sure that you wrap your code in script tags and that the HTML Item object you place on your page to hold the code appears below all prompt controls. If it is placed elsewhere it will not be able to find the prompt controls as they will not have been rendered when the code executes.

    The code assumes that the only prompts on the page are the checkboxes you want checked. If there are other prompts on the page then you will have to target individual prompts using the getControlByName() function provided in the API rather than looping through all prompts. More information on the Cognos JavaScript Prompt API can be found here.

    The key bits of code here are the getValues() and addValues() Cognos JavaScript Prompt API functions. getValues(true) returns a JSON-formatted object representing all values, selected or not, from a value prompt. addValues(values) takes a JSON-formatted object representing the values to be selected and selects them. Thus, it's a matter of grabbing all values and then passing them in to be selected.

    The reason for the if block is that we only want this code to run once at first page render. When the user first runs the report we want all checkboxes checked but after that we want the checkboxes to retain state. If we didn't use the if block the user's choices would be overwritten after a reprompt. For more information on this technique check out this tutorial on my blog: JavaScript: Running Code Only Once.

    Addendum

    If you don't want any filters to be applied when all boxes are checked in a section even after subsequent reprompts you can do so by tweaking your filter.

    Assume that we are checking against a model based item [Item1]. We have a current filter of: [Item1] in ?parameter1?. We also have four checkboxes with values of 'Choice1','Choice2','Choice3', and 'Choice4'.

    The following modified filter will only apply the checkboxes to the filter when all four aren't checked:

    (
    'Choice1' in ?parameter1?
    AND
    'Choice2' in ?parameter1?
    AND
    'Choice3' in ?parameter1?
    AND
    'Choice4' in ?parameter1?
    )
    OR
    [Item1] in ?parameter1?
    

    If all four checkboxes are checked then the first part of the OR is satisfied and all rows will be returned. It should be fast too because most languages, including iterations of SQL, will not test the second component of an OR if the first component is satisfied.