7 Replies Latest reply: Aug 25, 2012 6:49 AM by 954839 RSS

    Ajax loader while classic report is being refreshed ?

    Yann39
      Hi,

      Apex 4.1, Oracle 11g.

      I have some classic reports that can be refreshed using something like :
      $a_report(l_report_id,'1','15','15');
      The problem is that the refresh time can be long (from 0 to 6s), so I want to show an ajax loader instead of the report, while the report is being refreshed.

      I tried :
      $('#my_report_id').hide();
      $('div.my_report_container').append('<div id="ajax_report_loader"><img alt="" src="'+IMAGES_PATH+'ajax-loader.gif" style="height:28px;width:28px;" /> loading report...</div>');
      $a_report(l_report_id,'1','15','15');
      $('#img_ajax_report_loader').remove();
      $('#my_report_id').show();
      $('#my_report_id').hide();
      $('div.my_report_container').append('<div id="ajax_report_loader"><img alt="" src="'+IMAGES_PATH+'ajax-loader.gif" style="height:28px;width:28px;" /> loading report...</div>');
      $a_report(l_report_id,'1','15','15');
      
      $('#my_report_id').load(function() {
           $('#img_ajax_report_loader').remove();
           $('#my_report_id').show();
      });
      Nothing worked.

      Is there any simple way to do that ?

      Thank you.

      Yann.
        • 1. Re: Ajax loader while classic report is being refreshed ?
          Kiran Pawar
          Hello Yann,

          I have following suggestions:
          <ul>
          <li>
          >
          I tried:
          $('#my_report_id').hide();
          $('div.my_report_container').append('<div id="ajax_report_loader"><img alt="" src="'+IMAGES_PATH+'ajax-loader.gif" style="" /> loading report...</div>');
          $a_report(l_report_id,'1','15','15');
          $('#img_ajax_report_loader').remove();
          $('#my_report_id').show();
          $('#my_report_id').hide();
          $('div.my_report_container').append('<div id="ajax_report_loader"><img alt="" src="'+IMAGES_PATH+'ajax-loader.gif" style="" /> loading report...</div>');
          $a_report(l_report_id,'1','15','15');
           
          $('#my_report_id').load(function() {
               $('#img_ajax_report_loader').remove();
               $('#my_report_id').show();
          });
          Where have you written this code? viz. Page HTML Header, Report Header/Footer, Report Template
          Debug it with the help of [url http://getfirebug.com/]Firebug addon/extension for Firefox Web Browser(If another browser use appropriate javascript debugger).
          </li>
          <li>
          $('#my_report_id').hide();
          Investigate the report template to get the appropriate report region id viz if you have given my_report as Static ID for your report region and if the template substitution for it is id="report_#REGION_STATIC_ID#" then your actual region id will be report_my_report and you are referencing wrong report region.
          </li>
          <li>
          $('div.my_report_container').append('<div id="ajax_report_loader"><img alt="" src="'+IMAGES_PATH+'ajax-loader.gif" style="" /> loading report...</div>');
          Is IMAGES_PATH a variable? What value is it holding?
          The best way to use the appropriate substitution string viz. #IMAGE_PREFIX#, #WORKSPACE_IMAGES# or #APP_IMAGES# depending upon where you have loaded the image:
          $('div.my_report_container').append('<div id="ajax_report_loader"><img alt="" src="#APP_IMAGES#ajax-loader.gif" style="" /> loading report...</div>');
          </li>

          In order to get accurate/appropriate response you should include at least following information with your question:
          <ul>
          <li>Full APEX version</li>
          <li>Full Database version</li>
          <li>APEX Web server architecture (EPG, OHS or APEX listener)</li>
          <li>Browser(s) and version(s) used</li>
          <li>Operating system with version, architecture(32/64)</li>
          </ul>

          Hope it helps!
          Regards,
          Kiran
          • 2. Re: Ajax loader while classic report is being refreshed ?
            Yann39
            Hi Kiran,

            The code is working fine, it is not a problem.
            The problem is that it does not what I want.

            However here is some information related to your questions :

            -----
            Kiran wrote:
            Where have you written this code? viz. Page HTML Header, Report Header/Footer, Report Template
            Debug it with the help of Firebug addon/extension for Firefox Web Browser(If another browser use appropriate javascript debugger).
            Kiran wrote:Is IMAGES_PATH a variable? What value is it holding?
            The best way to use the appropriate substitution string viz. #IMAGE_PREFIX#, #WORKSPACE_IMAGES# or #APP_IMAGES# depending upon where you have loaded the image:
            I use the following page template (header) :
            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
            <html xmlns="http://www.w3.org/1999/xhtml" lang="&BROWSER_LANGUAGE.">
              <head>
                <title>#TITLE#</title>
            
                <script type="text/javascript">
                  var IMAGES_PATH = '&DFS_IMAGES.';
                  var PAGE_ID = '&APP_PAGE_ID.';
                  var APPLICATION_USER = '&APP_USER.';
                  var APPLICATION_LANGUAGE = '&APP_LANGUAGE.';
                  var APPLICATION_ID = '&APP_ID.';
                  var SESSION_ID = '&APP_SESSION.';
                </script>
            
                #HEAD#
            
                <link type="text/css" rel="stylesheet" href="&DFS_CSS.theme.css" />
                ...
                <script type="text/javascript" src="&DFS_JS.scripts.js"></script>
                ...
            
              </head>
            
              <body #ONLOAD#>#FORM_OPEN#
                <div class="page_content">
            Javascript/JQuery code is in scripts.js,
            CSS code is in theme.css.
            We don't write any code directly in APEX.

            All our images, CSS, JavaScript files are hosted on a central server. DFS_JS, DFS_CSS, DFS_IMAGES, etc. are application items, computed using application computations to set the right HTTP path. That way we can change the path in one step, and we can use IMAGES_PATH, PAGE_ID, etc. as JavaScript variables.

            And of course I am using Firebug for several years now ^^
            Kiran wrote:
            Investigate the report template to get the appropriate report region id viz if you have given my_report as Static ID for your report region and if the template substitution for it is id="report_#REGION_STATIC_ID#" then your actual region id will be report_my_report and you are referencing wrong report region.
            my report template is the following :
            <div id="#REGION_STATIC_ID#" style="width:100%;"><table cellpadding="0" border="0" cellspacing="0" summary="" #REPORT_ATTRIBUTES# id="report_#REGION_STATIC_ID#" style="width:100%;">
            #TOP_PAGINATION#
            <tr>
            <td><table cellpadding="0" border="0" cellspacing="0" summary="" class="report_blue_standard">
            So there is no problem, the report is successfully refreshed.

            -----

            The real question is how can I trigger an event when the report refresh is finished...

            I did the following :
            1 - I hide the report
            2 - I show an ajax loader instead
            3 - I refresh it by calling $a_report
            4 - ?

            How can I show the report only when the refresh is done?
            Whatever I do in step 4, it is done immediately, because $a_report is not asynchronous.


            Using an interactive report for example, I can do :
            $x_Hide('apexir_REPORT');
            $('#my_ajax_loader').show();
            gReport.pull();
            $('#my_ajax_loader').hide();
            but it is the same problem as gReport.pull(); (or gReport.search('SEARCH');) is not asynchronous. The ajax loader is hidden before the end of the refresh. An advantage is that it automatically shows the report when the refresh is done.

            Thank you.

            Edited by: Yann39 on 8 févr. 2012 05:56
            • 3. Re: Ajax loader while classic report is being refreshed ?
              Kiran Pawar
              Hello Yann,

              >
              Yann wrote:(Question Post)

              Nothing worked.

              Is there any simple way to do that ?
              >
              Hence, my above reply!

              >
              Yann wrote:
              The real question is how can I trigger an event when the report refresh is finished...

              I did the following :
              1 - I hide the report
              2 - I show an ajax loader instead
              3 - I refresh it by calling $a_report
              4 - ?

              How can I show the report only when the refresh is done?
              >
              This should be in your question post.
              My suggestions for this are:
              <ul>
              <li>
              Use of [url http://api.jquery.com/jQuery.ajax]jQuery.ajax() API:
                 $.ajax({
                  url:"javascript:$a_report(l_report_id,'1','15','15');",
                  dataType:"script",
                  data:{
                   l_report_id: MY_REPORT_ID
                  },
                  beforeSend:function(){
                   /* Show loading image */
                   $('#my_report_id').hide();
                   $('div.my_report_container').append('<div id="ajax_report_loader"><img alt="" src="'+IMAGES_PATH+'ajax-loader.gif" style="" /> loading report...</div>');
                  },
                  success:function(){
                   /* Code to execute on success */
                  },
                  complete:function(){
                   /* Hide loading image */
                   $('#img_ajax_report_loader').remove();
                   $('#my_report_id').show();
                  }
                 });
              I am not assuming that the copy paste of above code will work, but will give you a way to work on your problem with reference to jQuery API mentioned above.
              </li>
              <li>
              Use of Dynamic Action type plugin: [url http://apex-plugin.com/oracle-apex-plugins/dynamic-action-plugin/loading-icon_81.html]Loading Icon developed by @Tobias Arnhold
              </li>
              </ul>

              Hope it helps!
              Regards,
              Kiran
              • 4. Re: Ajax loader while classic report is being refreshed ?
                Kiran Pawar
                Hello Yann,

                Just got a good blog post of @Jari Laine:

                [url http://dbswh.webhop.net/dbswh/f?p=BLOG:READ:0::::ARTICLE:347800346935688]Hacking Apex 3.2 $a_report function with jQuery

                which will help you solve the problem.

                Hope it helps!
                Regards,
                Kiran
                • 5. Re: Ajax loader while classic report is being refreshed ?
                  Yann39
                  It works using the function provided by Jari in the blog :)
                  But it is done for the pagination too, my first idea was to apply this only when calling $a_report "manually", not for the pagination.
                  So I simply renamed it and then it is done only when calling $a_report2, not for the pagination.
                  $a_report2 = function (pId,pMin,pMax,pFetched,pSort){
                       var url=$v("pFlowId")+":"+$v("pFlowStepId")+":"+$v("pInstance")+":FLOW_PPR_OUTPUT_R"+pId+"_";
                       url+=pSort?pSort+"::RP":"pg_R_"+pId+":NO";
                       $.ajax({
                            url:"f",
                            cache:false,
                            type:"POST",
                            dataType:"html",
                            data:{
                                 p:url,
                                 fsp_region_id:pId,
                                 pg_max_rows:pMax,
                                 pg_min_row:pMin,
                                 pg_rows_fetched:pFetched
                            },
                            beforeSend:function(){
                                 $('#report_'+pId+'_catch').parent().append('<div id="ajax_report_loader"><img alt="" src="'+IMAGES_PATH+'ajax-loader.gif" style="" /> loading report...</div>');
                                 $('#report_'+pId+'_catch').hide();
                            },
                            success:function(d){
                                 if($(d).attr("id")=="report_"+pId+"_catch")
                                      $("#report_"+pId+"_catch").replaceWith(d);
                            },
                            complete:function(){
                                 $('#ajax_report_loader').remove();
                                 $('#report_'+pId+'_catch').show();
                            }
                       });
                  }
                  Now I have to find a similar solution for interactive reports.
                  I am still wondering why it does not work using ajaxComplete() :
                  $(document).ready(function() {
                       $('#P0_BTN_APPLY_CART').click(function() {
                            $('#apexir_REPORT').hide();
                            gReport.pull();
                       });
                   
                       $(document).ajaxComplete(function(){
                            alert('ajax done');
                       });
                  });
                  It could be so simple...
                  It seems gReport.pull() is not considered as an ajax "event", it is not catch in the ajaxComplete() function.

                  Thank you very much for your help Kiran !
                  • 6. Re: Ajax loader while classic report is being refreshed ?
                    Yann39
                    OK, for interactive reports, I have tried the following and it seems to works great :) :
                    $g_report2 = function () {
                         $.ajax({
                              url:"wwv_flow.show",
                              type:"POST",
                              dataType:"html",
                              data:{
                                   p_flow_id: $v('pFlowId'),
                                   p_instance: $v('pInstance'),
                                   p_flow_step_id: $v('pFlowStepId'),
                                   p_request: "SUBMIT",
                              },
                              beforeSend:function(){
                                   $('#apexir_REPORT').parent().append('<div id="ajax_report_loader"><img alt="" src="'+IMAGES_PATH+'ajax-loader.gif" style="" /> loading report...</div>');
                                   $('#apexir_REPORT').hide();
                              },
                              success:function(d){
                                   $('#apexir_REPORT').html($(d).find('#apexir_REPORT').html());
                              },
                              complete:function(){
                                   $('#ajax_report_loader').remove();
                                   $('#apexir_REPORT').show();
                              }
                         });
                    }
                    See you !

                    Yann.
                    • 7. Re: Ajax loader while classic report is being refreshed ?
                      954839
                      I know this is a late post, but the thread helped me on the way. So here's my solution:
                      $('div.my_report_container').append('<div id="ajax_report_loader"><img alt="" src="'+IMAGES_PATH+'ajax-loader.gif" style="" /> loading report...</div>');
                      
                      $a_report(l_report_id,'1','15','15');
                      
                      $('#'+l_report_id).ajaxComplete(function() {
                           $('#ajax_report_loader').remove();
                      });