1. Mastering Custom IRs in APEX 4.0: How you can fully control the look and feel of your Interactive Reports Toolbar

    Mastering Custom IRs in APEX 4.0: How you can fully control the look and feel of your Interactive Reports Toolbar

    One of my favorite undocumented feature of APEX 4.0 is the vastly improved usage of DIVs for laying out many of APEX’s UI components. This move away from table-based layouts gives developers more control and less html markup to futz with. What was very difficult or even impossible in previous iterations of APEX is now possible and very easy to do having just a little HTML and CSS knowledge.

    In this first How To series of my blog, I will go through how Interactive Reports are rendered in APEX 4 and how you can use CSS and image sprites to completely modify the way your IR looks. We’ll take a look at an example that features an extremely customized version of an Interactive Report, and then drill deeper into the code that makes it happen. Let’s begin!

    Customizing the Interactive Report Toolbar

    I’ll start off with this post by restyling the Interactive Reports toolbar. You will find the CSS and image sprites I used so you can modify and customize the Interactive Reports toolbar for your applications.

    Here is a screenshot of what our toolbar will look like once we have added our CSS and image sprites:

    Screenshot of Interactive Reports Toolbar

    This IR toolbar is from a new theme for APEX 4 you will learn about in a future blog post!

    In pervious iterations, the structure of the interactive reports toolbar was table and image based, and thus extremely difficult to style using CSS. As we are now on a div based structure, things are much easier.

    The HTML that makes this possible is actually very simple. Here is a screenshot of the markup for the toolbar:

    The structure is quite simple and allows us to pick each element of the toolbar we’d like to customize.

    Lets walk through the CSS that makes this interactive report toolbar possible.

    DIV#apexir_TOOLBAR (that’s the DIV tag with ID “apexir_TOOLBAR”) is the container for the IR toolbar. Inside the container, we have another two container DIVs that are especially helpful for laying a background image to. If left completely unstyled, these DIVs will have no impact. Here is some CSS we can use to add a background image to our IR Toolbar:

    /* APEX IR TOOLBAR */
    #apexir_TOOLBAR {
        padding: 0 0 10px 0 !important;
        }
    .apexir_TOOLBAR_OPEN {
        background:url("../images/sIRControllerBG.png") 100% -50px !important;
        float:left;
        height:40px;
        overflow:hidden;
        padding:0 10px 0 0;
        }
    .apexir_TOOLBAR_OPEN .apexir_TOOLBAR_CLOSE {
        background:url("../images/sIRControllerBG.png") 0 0 no-repeat !important;
        color:#000000;
        height:38px;
        overflow:hidden;
        padding-top: 2px;
        }
    

    Now that we have given the IR toolbar a nice boundary and made it look like user control, we can proceed to the individual items inside. The next element to style is the DIV.apexir_COLUMN_SELECTOR which contains the column search icon. We can change this Search Button (using an Image Sprite) through the following styles:

    div.apexir_COLUMN_SELECTOR {
        padding: 4px 0 4px 4px;
        }
    div.apexir_COLUMN_SELECTOR a.apexir_SEARCHICON {
        background: url(../images/sIRButton.png) 0 -250px no-repeat;
        /* sIRButton.png is an image sprite that contains several elements of the Interactive Report Toolbar */
        display:block;
        float:left;
        height:28px;
        width:28px;
        }
    

    Next, lets style the search field (contained in DIV.apexir_SEARCH and give it have some nice rounded corners for Firefox and Webkit-based browsers:

    div.apexir_SEARCH {
        padding: 7px 0 6px 2px;
        }
    input#apexir_SEARCH {
        border: 1px solid #999;
        border: 1px solid rgba(0,0,0,.4);
        padding: 2px 4px 2px 4px;
        font: normal 14px/14px Arial, sans-serif;
        background-color: #FFF;
        color: #222;
        -moz-border-radius: 6px;
        -webkit-border-radius: 6px;
        margin: 0 8px 0 0;
        }
    
    /* The following for Webkit Based browsers to fine-tune the positioning of the search field */
    @media screen and (-webkit-min-device-pixel-ratio:0) {
        input#apexir_SEARCH {
            padding-top: 1px;
            }
    }
    

    Now, to the “Go” button that will perform the search. The GO button has different classes than those used for other buttons within Interactive Reports so that it can be formatted accordingly. Additionally, as the GO button and other buttons in IRs should be of similar size, we can repeat the same styles used for many types of buttons used in IRs.

    button.apexir-button, button.apexir-go-button,
    #apexir_TOOLBAR button.dhtmlMenu,
    #apexir_TOOLBAR button.dhtmlMenuOn { 
        position: relative;
        border: 0; 
        cursor: pointer;
        overflow: visible; /* removes extra side padding in IE */
        padding: 0 11px 0 0;
        margin-left: 5px;
        font: normal 13px/13px Arial, sans-serif !important;
        margin: 0;
    }
    #apexir_TOOLBAR button.dhtmlMenu,
    #apexir_TOOLBAR button.dhtmlMenuOn {
        padding: 0 22px 0 0;
        }
    button.apexir-go-button {
        padding: 0 15px 0 0;
        }   
    button.apexir-button::-moz-focus-inner, 
    button.apexir-go-button::-moz-focus-inner,
    #apexir_TOOLBAR button.dhtmlMenu::-moz-focus-inner,
    #apexir_TOOLBAR button.dhtmlMenuOn::-moz-focus-inner {
        border: none;  /* overrides extra padding in Firefox */
        padding: 0 !important;
    }
    
    button.apexir-button span, 
    button.apexir-go-button span,
    #apexir_TOOLBAR button.dhtmlMenu span, 
    #apexir_TOOLBAR button.dhtmlMenuOn span {
            padding: 4px 4px 0 15px;
            height: 22px;
            color: #000;
            text-shadow: 0 1px 0 rgba(255,255,255,.5);
        }
    #apexir_TOOLBAR button.dhtmlMenu span, 
    #apexir_TOOLBAR button.dhtmlMenuOn span {
        padding: 4px 8px 0 15px;
        }
    button.apexir-go-button span {
        padding: 4px 0 0 15px;
        text-shadow: 0 1px 0 rgba(255,255,255,.75);
        }
        
    @media screen and (-webkit-min-device-pixel-ratio:0) {
        /* Safari and Google Chrome only - fix margins */
        
        button.apexir-button, 
        button.apexir-go-button, 
        #apexir_TOOLBAR button.dhtmlMenu, 
        #apexir_TOOLBAR button.dhtmlMenuOn,  {
            margin-top: -1px;
            padding-top: 4px !important;
        }
    }
    

    While this CSS may look complicated, the majority of it is simply setting up the right spacing so that button appears cohesive and text is aligned properly.

    Using Image Sprites

    to Create the IR Toolbar View Selector Pill

    Now that we have created our IR toolbar frame, styled the column search button, the search input field, as well as the toolbar buttons, we can now move on to something a little more interesting: image sprites.

    What is an image sprite? Before I explain, let me show you a picture of one:

    It looks like a bunch of images put together into one image, right? That’s exactly what an image sprite is. It’s one image file that contains multiple “images” or “sprites.” Using an image sprite, we can reference one image in our CSS and simply select which portion of the sprite we’d like to use.

    In the case of the IR toolbar, we can use this image sprite to completely render the active and inactive states of the different views (Icon View, Report View, Detail View, Group-By View, and Chart View).

    Normally we’d have one image for each of these states, that could mean at minimum 10 different images. Now we must take into account if a certain view is possible, or if a view is at the beginning or end of the pill. That could well over increase the number of images by 50%! Now imagine that we can accomplish all of this, use only one image file, and make it drastically easier for someone to customize the look and feel (they only have to modify one image, and save it once). Now you’re seeing the true power of image sprites.

    The extent of the modularity you’d like to achieve with your image sprite is in high correlation with the modularity of the underlying HTML structure. What does that mean for us? In order for us to use this image sprite to create all possible states of the IR pill, our HTML must be dynamic enough to call the right classes. And the HTML that renders this IR pill in APEX 4 is. Here is the CSS we use to define all states:

    /* Interactive Report Pill */
    .irr-pill {
        float:left;
        display:block;
        height:22px;
        width: 28px;
        outline: none;
    }
    .irr-pill span {
        display: block;
        text-indent: -99999px;
        height:22px;
        width: 28px;
        }
    .irr-pill-icons-left span{background:url(../images/sIRPill.png) -100px 0 no-repeat;}
    .irr-pill-report-center span,.irr-pill-report-left span{background:url(../images/sIRPill.png) -100px -50px no-repeat;}
    .irr-pill-report-right span{background:url(../images/sIRPill.png) -101px -50px no-repeat;}
    .irr-pill-details-right span{background:url(../images/sIRPill.png) -102px -100px no-repeat;}
    .irr-pill-icons-left-active span{background:url(../images/sIRPill.png) -150px 0 no-repeat;}
    .irr-pill-report-center-active span,.irr-pill-report-left-active span{background:url(../images/sIRPill.png) -150px -50px no-repeat;}
    .irr-pill-report-right-active span{background:url(../images/sIRPill.png) -151px -50px no-repeat;}
    .irr-pill-details-right-active span{background:url(../images/sIRPill.png) -152px -100px no-repeat;}
    
    .irr-pill-icons-left,.irr-pill-report-left{background:url(../images/sIRPill.png) 0 0 no-repeat;}
    .irr-pill-icons-left-active,.irr-pill-report-left-active{background:url(../images/sIRPill.png) -50px 0 no-repeat;}
    .irr-pill-report-center{background:url(../images/sIRPill.png) 0 -50px no-repeat;}
    .irr-pill-report-center-active{background:url(../images/sIRPill.png) -50px -50px no-repeat;}
    .irr-pill-details-right,.irr-pill-report-right{background:url(../images/sIRPill.png) 0 -100px no-repeat;}
    .irr-pill-details-right-active,.irr-pill-report-right-active{background:url(../images/sIRPill.png) -50px -100px no-repeat;}
    
    .irr-pill-chart, .irr-pill-group, .irr-pill-report {
        background: url(../images/sIRPill.png) 0px -150px no-repeat;
        width: 40px;
        margin-left: 8px;
        }
    .irr-pill-chart-active, .irr-pill-group-active, .irr-pill-report-active {
        background: url(../images/sIRPill.png) -50px -150px no-repeat;
        width: 40px;
        margin-left: 8px;
        }
    
    .irr-pill-chart span{background:url(../images/sIRPill.png) -100px -150px no-repeat;}
    .irr-pill-chart-active span{background:url(../images/sIRPill.png) -150px -150px no-repeat;}
    .irr-pill-group span{background:url(../images/sIRPill.png) -100px -200px no-repeat;}
    .irr-pill-group-active span{background:url(../images/sIRPill.png) -150px -200px no-repeat;}
    
    .irr-pill-report span{background:url(../images/sIRPill.png) -94px -50px no-repeat;}
    .irr-pill-report-active span{background:url(../images/sIRPill.png) -144px -50px no-repeat;}
    

    With this CSS in place and the images in their proper locations, we have successfully completed restyling our Interactive Report toolbar from:

    Screenshot of Default Interactive Reports Toolbar

    to

    Screenshot of Completed Interactive Reports Toolbar

    The next step will be to take this one step further and style our Interactive Reports toolbar’s menus, action panels (Filters, Save, Download boxes), as well as getting to the actual report table! That’s all coming in a future blog posts.

    You can find the PSD files for the sprites used for our IR toolbar below:

    Downloadables

    1. sIRPill.psd - Report View Selector Pill
    2. sIRButton.psd - Column Search Button/Icon, Go Button, and other Buttons in IRs
    3. sIRControllerBG.psd - Toolbar Background

    Last Updated: Sept 20 2010 - 10:45 EST