Using jQuery to Fix Broken APEX Interactive Report Drop-Down Menus

Whilst creating a new APEX theme recently I encountered an interesting problem whereby changes I had made to the CSS style sheet were causing the in-built Interactive Report header menus to drop down in the wrong place. The IR drop-down menus were consistently being rendered too far down and to the right of where they were supposed to be. After some investigation I discovered the cause of this problem and came up with a simple fix using jQuery.

The position of an IR header menu is always calculated relative to the top left corner of the <body> element. These coordinates are then applied to the HTML block containing the drop-down menu using the CSS properties position:absolute, left and top. This method works fine for the themes supplied with APEX. Unfortunately, if you are creating or editing your own APEX theme, setting position:relative on any element that could contain an Interactive Report will cause positioning errors for these menus. The reason for this is that the position of an absolutely positioned element is relative to the closest “positioned” containing element. In other words, an element with position:relative will define a local coordinate system for any contained elements with position:absolute. In effect, the IR header menu script calculates a position using one coordinate system (<body>) but a “positioned” containing element will cause these coordinates to be applied to its own coordinate system, resulting in a mis-placed drop-down menu.

My new APEX theme design called for the use of position:relative on all my region templates and I didn’t want to consider removing this property and compromising my design for just one errant script. Fortunately the solution proved to be quite simple: the IR menu blocks needed to be children of the <body> element i.e. the IR menu blocks needed to be children of the element defining the coordinate system being used to calculate their positions. This way the position property of any other element on the page becomes irrelevant to IR drop-down menus.

This solution can be applied quite simply using jQuery:

$("#apexir_rollover").appendTo("body");

This javascript manipulates the DOM to make any IR menu block (elements with an id of “apexir_rollover”) a child of the <body> element. Better still, it inserts these blocks after all other children, which mitigates any potential problems with stacking order.

There might be other reasons for in-built APEX drop-down menus to be incorrectly positioned (see Problems Using a DOCTYPE in APEX Theme Templates) but given the specific nature of this problem, if you are customising APEX themes and are experiencing similar problems, I would recommend double-checking your CSS for positioned elements. With this simple fix you can safely apply position:relative to any element you care to without the risk of breaking core APEX functionality.

Stephen

Stephen Blair is a freelance artist and designer. He has created numerous websites including those selling his own vector clipart and APEX themes.

4 Responses to “Using jQuery to Fix Broken APEX Interactive Report Drop-Down Menus”

  • Claudio says:

    Hi Stephen,
    congratulations for your skill about ApEx!
    I have the same problem, but I don’t use JQuery framework (I use ExtJs).
    Did you have suggestion on how to solve this problem with standard Javascript?

    Thanks a lot
    Claudio

    • Hi Claudio,

      The principle is the same, you need to move “apexir_rollover” to be a child of the BODY element.

      I don’t use much vanilla javascript but try:
      var q = document.getElementById('apexir_rollover');
      document.body.appendChild(q.parentNode.removeChild(q));

      -Stephen

  • Claudio says:

    You are a guru Stephen!
    That perfectly works in all my themes context!

  • David says:

    Stephen, thank you thank you thank you! I’ve been suffering with this annoying problem since I first developed my app — I am not a jQuery/javascript/html/css guru by any means, so I wasn’t sure how to solve it. I had an IR in a sub-region under jQuery tabs…and had this problem due to the jQuery tabs (I suppose).

    This little snippet fixed the problem finally — I’m so happy! Thanks a million!

    David Christopher

Comments can no longer be submitted.