Checking an “All” option in a checkbox prompt

One of my readers sent me an interesting problem. They need a checkbox prompt in which the top option is “All” and checking on any other option would automatically uncheck the “All” choice. Similarly, checking “All” should uncheck the other choices. Taking it to the conclusion, when checking or unchecking all of the options, the “All” should be checked.

Since they are still on 10.1, I have not used the Prompt API, meaning this should work on all versions since 8.4. To begin, the prompt itself.
check this out

In this case, the prompt is based on the Retailers hierarchy in the Sales and Marketing cube. Other times you might want to add a static value.

The JavaScript itself is not that difficult. The JS will loop through the prompt each time an option is clicked. If the first option is clicked, it will check it and uncheck the other options. If any other option is click it will loop through the prompt, counting the number of checked options and act accordingly. If 0 or all of the options are checked, it will check the first option, otherwise it will simply uncheck it.

When working with Checkbox prompts in JavaScript, the thing to remember is that, for whatever reason, the checkboxes that we see are actually images. To show the prompt as checked, the input needs to have the class “dijitCheckBoxChecked”.

Now the JS:

<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;
      };
    }
    addEvent(element, event, func);
  }


// Cognos form and namespace identifier. Don't touch.
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;
 
function attacher(elm,prompt,clicked){
  var func = function() {
    //if all is selected, zero out everything else.
    if(clicked==0) {prompt[0].selected=true;prompt[0].checked=true;prompt[0].parentNode.className="dijitInline dijitCheckBox dijitCheckBoxChecked";for(var i=1;i<prompt.length;++i){prompt[i].selected=false;prompt[i].checked=false;prompt[i].parentNode.className="dijitInline dijitCheckBox"}}

    //if individual, count number of selected
    if(clicked>0) {var c=0;
      for(var i=1;i<prompt.length;++i){
        if(prompt[i].checked){++c}
      }
      //if the count of checked is 0, then set the all to checked
      if(c==0) {setter=false;prompt[0].selected=true;prompt[0].checked=true;prompt[0].parentNode.className="dijitInline dijitCheckBox dijitCheckBoxChecked"}
      //if the count of checked is equal to the length of the prompt, then set the all to checked and uncheck everything else
      else if(c==prompt.length-1) {setter=false;prompt[0].selected=true;prompt[0].checked=true;prompt[0].parentNode.className="dijitInline dijitCheckBox dijitCheckBoxChecked";        for(var i=1;i<prompt.length;++i){prompt[i].selected=false;prompt[i].checked=false;prompt[i].parentNode.className="dijitInline dijitCheckBox"}}
      //if the count is one and less than the length of the prompt then just set all to unchecked;
      else if(c>0&&c<prompt.length-1){prompt[0].checked=false;prompt[0].selected=false;prompt[0].parentNode.className="dijitInline dijitCheckBox"}
    }

    canSubmitPrompt();
    }
  addEvent(elm,'click',func)

}

var prompt=fW._oLstChoicesCountries;
for (var i=0;i<prompt.length;++i){
  attacher(prompt[i],prompt,i);
}

</script>

EDIT: An eagle-eyed reader noticed that the appearance of the checks are actually slightly different than they are when first rendered. The solution was to put a parentNode after prompt[i] when calling the className. Thanks Sue!

Checkbox Prompt - All option (1732 downloads)

Animated dropdown checkboxes and creating custom on-hover events

For those who missed it, PerformanceG2 is sponsoring my trip to the IOD this year. In return, I’ve written a couple of articles for their blog.

The first is a fancy way of converting
needing-to-scroll-for-prompts-make-users-angry

To
sliders-are-awesome

This is a very easy technique to use, simply copy in the main script into an HTML item at the top of the page, and add another script at the bottom to call the functions. Since it doesn’t use the 10.2 Prompt API, you can implement it in every version since 8.4. To learn more about that technique, read the post here.

The next technique is a bit more interesting (at least for me). There have been many times where clients have asked for a way to add more insights to the tooltips in charts. For example, users may want to hover over a micro chart and see a magnified version:
Magnifying Microcharts

In that image each chart had the country ID hidden right next to it. Hovering over the chart would then unhide a div with the same ID and position it directly over the cursor. Moving away from the chart would then hide it.

The same fading functions were used for this next technique:
filtering a list

Each area in the map has an onhover event attached. There are some internal Cognos JS functions that will pull the contextual data of that area. So if you’re hovering over a dot, the functions would return the series, category, and measure of the dot. Hovering over a legend would return that specific series. Since this is referencing internal Cognos JS functions I can’t guarantee that it will work in previous (or future) versions.

Read up on that technique here.

It looks like the post is down. The popups report XML can be found here: Popups on Hover Report XML (1630 downloads)

updated animated checkbox prompt: updated-animated-checkbox.txt (921 downloads)

Quickie: PDF Report in New Window

One of the biggest frustrations people have with Cognos is that it will use the same window to export a report to PDF. Excel will open a new page, but not PDF. Why? Who knows? (IBMers, please feel free to comment below.)

Fortunately we can use JavaScript to force Cognos to do our bidding.

Since the JavaScript API changed in 10.2 I have two implementations, one for 10.1.1 and lower and one for 10.2 and higher. Simply paste the correct JavaScript into an HTML item, and fix up the button to meet your needs.

10.1.1

<script>
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;

CViewerManager.prototype.viewInPDF = function(){
                var oReq =new CCognosViewerRequest("render")
                oReq.addOption("run.outputFormat", "PDF");
                this.viewPDFInNewWindow(oReq);
}  
</script>
<input type="button" onclick="window[nameSpace].getRV().viewInPDF()" value="Export to PDF"/>

10.2 is a bit easier to work with:

<script>
CViewerManager.prototype.runPDF = function ()
{
  var oReq = new ViewerDispatcherEntry(this.getCV());
  oReq.addFormField("ui.action","render");
  oReq.addFormField("run.outputFormat","PDF");
  this.viewPDFInNewWindow(oReq);
};
</script>
<input type="button" onclick="window['oCV'+'_THIS_'].getRV().runPDF()" value="Export to PDF"/>

Remember, use only one of them. The 10.1.1 version won’t work in 10.2, but should work in previous versions. I don’t have access to the 8 versions any more, so I’d appreciate if someone could leave a comment saying if it works or not.

Export to PDF Report XML (804 downloads)

EDIT:
Many people have experienced issues with the version posted above on 10.2.1 and above. The following version works perfectly for me on 10.2.1 with IE 8 and Firefox.
Export-to-PDF-10.21.txt (964 downloads)