This discussion is archived
11 Replies Latest reply: May 29, 2013 4:26 AM by Howard (... in Training) RSS

Collapsed Tabular Form Heading when "No data found".

Howard (... in Training) Pro
Currently Being Moderated
The ' Collapsed Tabular Form Heading when "No data found" ' problem (speculated to be bug 9893564) is discussed here: {message:id=4419231}. Warning link is out of date. I'm still seeing it in APEX 4.2.

I support Kelly's comments "looks like something is broken" and "Now this header (which is sized smaller before data is retrieved) comes between the search items and the help message and looks clumsy.".{message:id=9185914}.

Any suggestion to get around it when no data is found?
1) Is there a way to hide the header when there is no data? Or,
2) Is there a way to adjust the width of the columns if the header must display? I'd like them to be about what they are when data is displayed. I know those lengths but not how to affect the header width for a tabular report with no data.

Example:
WS APEX_EXAMPLES_01
demo
demo
Appl 78329 Tabular Form - page 1. (I forced query not to find any data for demo purposes.)

Thanks,
Howard
  • 1. Re: Collapsed Tabular Form Heading when "No data found".
    Aljaz Explorer
    Currently Being Moderated
    Hi,

    I did modified your application and I hope that's ok with you?

    I have noticed that you have set static id for tabular form region to tabular-form

    On Page properties under Footer Text I have inserted this code
    <script>
      if ($("#tabular-form .nodatafound").length) {
        $("#tabular-form .nodatafound").hide();
        $("#report_tabular-form").hide();
      };
    </script>
    Also I have modified Action When Button Pressed for button Add Row to :
    javascript:$("#report_tabular-form").show();apex.widget.tabular.addRow();
    Can you take a look if this is what you are looking for?

    Regards,
    Aljaz
  • 2. Re: Collapsed Tabular Form Heading when "No data found".
    fac586 Guru
    Currently Being Moderated
    Howard (... in Training) wrote:
    The ' Collapsed Tabular Form Heading when "No data found" ' problem (speculated to be bug 9893564) is discussed here: {message:id=4419231}. Warning link is out of date. I'm still seeing it in APEX 4.2.

    I support Kelly's comments "looks like something is broken" and "Now this header (which is sized smaller before data is retrieved) comes between the search items and the help message and looks clumsy.".{message:id=9185914}.

    Any suggestion to get around it when no data is found?
    1) Is there a way to hide the header when there is no data?
    Which is equivalent to showing the header when there is. It often helps to consider a problem from the opposite direction.

    Add a static region ID (e.g. <tt>tabular-form</tt>).

    1. Start with CSS that hides the tabular form container:
    #report_tabular-form {
      display: none;
    }
    2. Create an After Refresh dynamic action on the tabular form region, with a Show action using a jQuery ID selector for the tabular form container: <tt>#report_tabular-form</tt>. Apply an Exists (SQL query returns at least one row) condition to the dynamic action using the tabular form query.

    3. Create a Page Load Execute JavaScript Code dynamic action to bind another click event to the "Add Row" button to show the tabular form:
    $('button#emp-add-row').click(function() {
        $('#report_tabular-form').show();
    });
    2) Is there a way to adjust the width of the columns if the header must display? I'd like them to be about what they are when data is displayed. I know those lengths but not how to affect the header width for a tabular report with no data.
    Again using a static region ID, use CSS to set a minimum width for the tabular form table and its container:
    #report_tabular-form,
    #report_tabular-form .report-standard {
      min-width: 90%;
    }
    Edited by: fac586 on 19-May-2013 14:27

    Changed selector in step 3 after realising that static IDs can be specified for buttons.
  • 3. Re: Collapsed Tabular Form Heading when "No data found".
    fac586 Guru
    Currently Being Moderated
    Aljaz wrote:
    Hi,

    I did modified your application and I hope that's ok with you?

    I have noticed that you have set static id for tabular form region to tabular-form
    No, I did. In demonstrating 2 different approaches to this we've got rather mixed up. To keep things clear I've moved your example to page 2.
  • 4. Re: Collapsed Tabular Form Heading when "No data found".
    Howard (... in Training) Pro
    Currently Being Moderated
    Aljaz / Paul,

    NEAT STUFF! So many things here that I have not seen / done before. Great! Thank you!. A couple things ...

    I erred in not making the original query with a WHERE clause (WHERE "EMPNO" = :P1_SELECT_EMPNO) so the "data found" case could be tested as well. So I modified both pages and added a Submit button.

    Aljaz --
    Thank you very much for this solution. It's simple and only requires two new places be modified. ... <strike>But when I changed the WHERE clause on page 1, your solution on page 2 began showing the header even when no data was found. And I think this was before I changed anything on page 2. To make sure the "tabular-form" conditions from page 1 would not conflict with page 2, I renamed the static ID on page 2 to "tabular-form2" everywhere I found it. But the header still displays! I don't know what I've broken. Can you take another look at it? </strike>

    <strike>Later: Oh, I think we're missing code to unhide the form. Let me see if I can come up with that. </strike>

    The heading is fine. What's missing is the "No data found" message. What controls that? I may (or may not) want to retain it. - - - Okay. I see which piece controls that. Thank you again. Edited by: Howard (... in Training) on May 17, 2013 9:47 AM

    Paul --
    Great! So many new techniques here -- new to me. Generally, I much prefer positive logic as well. But this solution seems to have more pieces than the other. I'm going to try both of them to make sure I understand all the pieces. I'm not sure which I will use in this project.

    And about the style code:
    #report_tabular-form,
    #report_tabular-form .report-standard {
      min-width: 90%;
    } 
    That is an improvement. I had read about it but not considered it for this. I tried the technique used to adjust column width on other reports but when I use "div," it makes the data in that column display only. I really want to adjust the width of the individual column header. Is there a way to do that?

    Thank you both!
    Howard
  • 5. Re: Collapsed Tabular Form Heading when "No data found".
    Aljaz Explorer
    Currently Being Moderated
    Howard,

    glad that I could help.

    Regards,
    Aljaz
  • 6. Re: Collapsed Tabular Form Heading when "No data found".
    Aljaz Explorer
    Currently Being Moderated
    Howard,

    one thing that can be done to eliminate copy paste of javascript code to other tabular form pages and save some time in the future

    Create new region template, so that you copy template Report Region to let say Tabular Form Hidden When Empty
    At the end of Definition -> Template add following code
    <script>
      if ($("##REGION_STATIC_ID# .nodatafound").length) {
        //$("##REGION_STATIC_ID# .nodatafound").hide();
        $("#report_#REGION_STATIC_ID#").hide();
      };
      
      function fnc_show_and_add_row(){
        $("#report_#REGION_STATIC_ID#").show();
        apex.widget.tabular.addRow();
      } 
    </script>
    (If you wish you can uncomment hidding of a "No data found" message)


    In your case, you are using Scarlet Theme, definition now looks like:
    <div class="rounded-corner-region" id="#REGION_STATIC_ID#" #REGION_ATTRIBUTES#>
      <div class="rc-gray-top"><div class="rc-gray-top-r">
        <div class="rc-title">#TITLE#</div>
      </div></div>
      <div class="rc-body"><div class="rc-body-r">
    <div class="rc-content-buttons">#CLOSE##PREVIOUS##NEXT##DELETE##EDIT##CHANGE##CREATE##CREATE2##EXPAND##COPY##HELP#</div>
    <div class="rc-content-main">#BODY#<div class="clear"></div></div></div></div>
      <div class="rc-bottom"><div class="rc-bottom-r"></div></div>
    </div>
    <script>
      if ($("##REGION_STATIC_ID# .nodatafound").length) {
        //$("##REGION_STATIC_ID# .nodatafound").hide();
        $("#report_#REGION_STATIC_ID#").hide();
      };
      
      function fnc_show_and_add_row(){
        $("#report_#REGION_STATIC_ID#").show();
        apex.widget.tabular.addRow();
      } 
    </script>
    On a page you can now change region template of tabular form region to Tabular Form Hidden When Empty

    Last step is to change property Action When Button Pressed of Add Row button to:
    javascript:fnc_show_and_add_row();
    If this is OK for your, then to next time you create new tabular form page, you do following three steps:

    1) Set Static ID for tabular form region
    2) Change template of a tabular form region to Tabular Form Hidden When Empty
    3) Change property Action When Button Pressed of Add Row button to: javascript:fnc_show_and_add_row();



    You can check this in your application on Page 5.


    Regards,
    Aljaz
  • 7. Re: Collapsed Tabular Form Heading when "No data found".
    Howard (... in Training) Pro
    Currently Being Moderated
    Aljaz,

    Great. Thanks for all your work. I've been postponing work with templates because I am unsure to what extent the folks here will allow template customization. But this really helps me to better understand how the pieces work together.
    <script>
      if ($("##REGION_STATIC_ID# .nodatafound").length) {
        //$("##REGION_STATIC_ID# .nodatafound").hide();
        $("#report_#REGION_STATIC_ID#").hide();
      };
     . . .
    I wanted to recode this as a "positive" test and the below does not make it clearer:
    <script>
      if (!$("##REGION_STATIC_ID# .nodatafound").length) {
        //$("##REGION_STATIC_ID# .nodatafound").hide();
        $("#report_#REGION_STATIC_ID#").show();
      }
      else
        //$("##REGION_STATIC_ID# .nodatafound").show();
        $("#report_#REGION_STATIC_ID#").hide();  
      };
     . . .
    These doesn't seem clearer/simpler logic to me either:
    <script>
      if ($("##REGION_STATIC_ID# .nodatafound").length == 0) {
        //$("##REGION_STATIC_ID# .nodatafound").hide();
        $("#report_#REGION_STATIC_ID#").show();
      }
      else
        //$("##REGION_STATIC_ID# .nodatafound").show();
        $("#report_#REGION_STATIC_ID#").hide();  
      };
     . . .
    Testing ".nodatafound" seems to force the use of negative logic
    since when the length is zero (0), then there is greater than zero (0) data
    and when the length is greater than zero (0), then there is zero (0) data.

    If all the indicators are "not found" indicators, then we seem forced to use negative logic. Say, rather than test the length of a what seems like a secondary indicator (.nodatafound), is there some item / value that's a primary indicator whether data is/was returned?

    Thanks,
    Howard
  • 8. Re: Collapsed Tabular Form Heading when "No data found".
    Aljaz Explorer
    Currently Being Moderated
    Hi,

    you could try using #TOTAL_ROWS# substitution variable, but I think that this only works in region footer, so you would need to move javascript in region footer.

    Check this thread: Number of Rows Returned For A Report

    Regards,
    Aljaz
  • 9. Re: Collapsed Tabular Form Heading when "No data found".
    Howard (... in Training) Pro
    Currently Being Moderated
    Thanks. The fact that 1) #TOTAL_ROWS# is NOT the "total number of rows for the whole query" and further, 2) it's not always up-to-date, rules out it's usefulness for me.

    As Dietmar points out here {message:id=10494388}
    Another problem is also tricky. This information in the region footer is static and will not be updated when you use "enable partial page refresh" on a classic report. On an interactive report it will not work at all since it uses AJAX all the time to retrieve the rows. Thus if you filter dynamically in an interactive report, the number of rows retrieved (#TOTAL_ROWS#) will not change. It will only be display when the page is rendered initially.
    Initially, it is sufficient to know is if there is at least one row retrieved on the first page. But if that one row were deleted and #TOTAL_ROWS# is not updated, I will then be displaying the header and no rows of data.

    Looks like there's no solution down this path.

    Thanks again,
    Howard
  • 10. Re: Collapsed Tabular Form Heading when "No data found".
    fac586 Guru
    Currently Being Moderated
    Howard (... in Training) wrote:

    Paul --
    Great! So many new techniques here -- new to me. Generally, I much prefer positive logic as well. But this solution seems to have more pieces than the other.
    There is method in that.

    Firstly, with Aljaz's approach you can see a flicker as the tabular form is actually rendered and then hidden when the script in the footer is eventually run. This will be more apparent with a longer or more complicated page where it takes longer to reach the script and more content needs to be adjusted following removal of the form. Reversing the logic and hiding the form using CSS in the page header prevents this as the form elements are initially created as hidden nodes in the DOM before any of the page is rendered.

    More important is that this approach applies the principles of the separation of concerns and unobtrusive JavaScript. At some point when developing in APEX you're going to find yourself seriously losing your cool in a situation where you know the app is executing some JavaScript, but you can't find where that script is defined (maybe you've already been there). Look at the page 2 definition using the tree view: where's the JavaScript that is going to run? Now look at page 1: ah, there are a couple of dynamic actions...

    APEX now includes a lot of containers specifically for JavaScript: File URLs, Function and Global Variable Declaration and Execute when Page Loads in page templates and page headers, and declarative and custom Execute JS Code Dynamic Actions. These provide for good separation of concerns: we should use these locations for JS code, and avoid the exasperation of hunting through templates, page/region headers/footers, page 0 regions, pre-/post-element text or wherever to find the script we can see in the page source or JS debugger.

    Aljaz's solution also depends on detecting the presence of the No Data Found message with class <tt>nodatafound</tt>, and on modifying the Add Row button.

    What if someone changes the class of the No Data Found message in the report attributes? The Exists... condition on the dynamic action performs this check in a more direct way (although it's not ideal: DRY is violated by having both 2 copies and 2 executions of the report SQL; nor is it reusable on other form regions).

    Modifying the Add Row button JavaScript directly is intrusive. Like footers and templates, it's another non-obvious location for JS customisation. By using a dynamic action to bind another click handler to the button we're making the modification more obvious, and more importantly we don't have to modify what it's already doing&mdash;or in this instance, even care what that is (in other circumstances we might need to change the order or propagation of events, or suppress the original behaviour).

    As for reusability, my original solution didn't really consider this (as it wasn't mentioned in the OP). Since the subject has been raised, and in accordance with my comments above, I'd approach it in a different way.

    As discussed, I suggest not squirrelling JavaScript away in region templates. I'd create a reusable report template for tabular forms rather than a region one. A <tt>class</tt> defined on the report container there will provide a more direct selector for hide/show behaviour. I'd stick to initially hiding this report via CSS, and use dynamic actions defined on the global page to conditionally show it on page load and bind show behaviour to the Add Row button click. To make these DAs reusable I'd remove the Exists... condition from the first one and replace it with a JS condition that checks to see if the tabular form report contains any visible data rows (the class on the report template will help there as well). Binding the show behaviour to the Add Row button would use the <tt>onclick</tt> attribute as a selector (rather than an ID selector that requires an intrusive edit of the button) so that all Add Row buttons would be affected: <tt>$('button[onclick^="apex.widget.tabular.addRow"]')</tt>.
    And about the style code:
    #report_tabular-form,
    #report_tabular-form .report-standard {
    min-width: 90%;
    } 
    That is an improvement. I had read about it but not considered it for this. I tried the technique used to adjust column width on other reports but when I use "div," it makes the data in that column display only. I really want to adjust the width of the individual column header. Is there a way to do that?
    I'm not really clear what you're asking here. (Use "div"? Where? How?)

    To control the width of individual report column headers, use the following CSS:
    th#COLUMN_ALIAS {
      width: 10em;
    }
    Where <tt>COLUMN_ALIAS</tt> is the alias of the column in the query: APEX uses this as the HTML <tt>id</tt> attribute for the column table header element. (Note that <tt>id</tt> attributes must be unique within a document, so it the same column appears in multiple reports/forms, ensure each column alias is unique.)
  • 11. Re: Collapsed Tabular Form Heading when "No data found".
    Howard (... in Training) Pro
    Currently Being Moderated
    <b>Thank you very much.</b> There is so much here. As I'm pulled away to other tasks now, I have tucked this away to ponder and try later.

    Re:
    And about the style code:
    #report_tabular-form,
    #report_tabular-form .report-standard {
    min-width: 90%;
    }

    That is an improvement. I had read about it but not considered it for this. I tried the technique used to adjust column width on other reports but <b>when I use "div," it makes the data in that column display only.</b> I really want to adjust the width of the individual column header. Is there a way to do that?
    I refer to using, say
    <div>#JOB_LNG_NM#</div>
    in a report(?) columns Column Formatting HTML Expression attribute(?) in order to use
    #bpr-proc td.data[headers="JOB_LNG_NM"] div {
      width: 250px;
      font-size: 11px;
      white-space: nowrap;
      word-wrap: break-word;
    }
    in the page HTML Header.

    This is a great technique but -- at least the way I have used this, it turns the column into a display (read only?) column. I was looking to control height, width, font, padding, color, etc. on data entry columns as well.
    =================

    Again, much thanks,
    Howard

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points