12 Replies Latest reply: Sep 29, 2010 6:11 AM by jariola RSS

    Apex 3.2 hook javascripts to IR and execute those when report is refreshed

    jariola
      Hi,

      You propably have see tricks to attache javascript to IR refresh using time out and gReport.l_LastFunction e.g. these.
      http://roelhartman.blogspot.com/2010/04/alternative-to-alternating-row-colors.html
      http://www.talkapex.com/2009/03/column-groups-in-apex-interactive.html


      Here is alternative solution:
      You need load jQuery 1.4.2 e.g. in page template header
      Create page zero if your application do not have one. Then create HTML region before footer with no template.
      Place code to region source
      <script type="text/javascript">
      ;(function($){
      $.htmldbIrBusyGrap=$.fn.htmldbIrBusyGrap=function(){
      /* for bind IR ajax */
       /* check do we have IR on page */
       if($('#apexir_WORKSHEET_REGION').length>0){
        /* replace apex internal function _BusyGraphic */
        gReport._BusyGraphic=function(pState){
         if(pState==1){
          /* ir ajax start trigger htmldbIrAjaxStart event and show loading icon */
          $.event.trigger('htmldbIrAjaxStart');
          $('#apexir_LOADER').show();
         }else{
          /* check is there data stored to #apexir_WORKSHEET */
          if(!$('#apexir_WORKSHEET').data('htmldb')){
            /* store data to #apexir_WORKSHEET */
            $('#apexir_WORKSHEET').data('htmldb',{irReady:true});
            /* trigger htmldbIrReady event */
            $.event.trigger('htmldbIrReady');
           }
           /* hide loading icon and trigger htmldbIrAjaxEnd*/
           $('#apexir_LOADER').hide();
          $.event.trigger('htmldbIrAjaxEnd');
         };
         return;
        };
        $.event.trigger('htmldbIrReady');
       }
      };
      $.htmldbIrReady=$.fn.htmldbIrReady=function(fn){
       $(function(){
        if($.isFunction(fn)&&$('#apexir_WORKSHEET_REGION').length>0){
         $('#apexir_WORKSHEET_REGION').bind('htmldbIrReady',fn);
        }
       });
      };
      })(jQuery);
      addLoadEvent(function(){$.htmldbIrBusyGrap();});
      </script>
      Now your IR will trigger htmldbIrReady event when report is refreshed.
      Usage example
      <script>
      $(function(){$('#foo').bind('htmldbIrReady',function(){alert('Hello');});});
      </script>
      Also it trigger htmldbIrAjaxStart and htmldbIrAjaxEnd events.
      Usage example
      <script>
      $(function(){$('#foo').bind('htmldbIrAjaxStart',function(){alert('Ajax start');});});
      $(function(){$('#foo').bind('htmldbIrAjaxEnd',function(){alert('Ajax end');});});
      </script>
      Or use function $.htmldbIrReady example
      <script>
      $(function(){$.htmldbIrReady(function(){alert('Hello');});});
      </script>
      Small demo that logs those events here
      http://actionet.homelinux.net/htmldb/f?p=100:87

      Hope this helps and you post other innovative solutions or usage examples about this

      Regards,
      Jari
        • 1. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
          Marco1975
          Hi Jari,

          i have tried this code, but i must be doing something wrong because i don't get any alert.

          I have copied the code in page 0. I have a ristriction that is only execute on my test page.

          And i have the code with the alert in the IR Region header.
          <script> 
          $(function(){$('#foo').bind('htmldbIrReady',function(){alert('Hello');});});
          </script>
           
          <script> 
          $(function(){$('#foo').bind('htmldbIrAjaxStart',function(){alert('Ajax start');});});
          $(function(){$('#foo').bind('htmldbIrAjaxEnd',function(){alert('Ajax end');});});
          </script>
          the javascript error message is "Object expected"

          can you help ?

          Marco
          • 2. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
            Marco1975
            ok the code with the alert should also be on page 0.

            so i get the message now. But when the search button is pressed or the pagination is changed of the IR i get no respond.

            have you any idea ?

            Just learning on the job ;-)
            • 3. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
              jariola
              Hi,


              Place to page HTML header
              <script>
              $(function(){
              $.htmldbIrReady(function(){alert('Hello')})
              });
              </script>
              Do you get alert when you paginate ?

              Regards,
              Jari

              Edited by: jarola on Sep 23, 2010 4:53 PM

              PS: #foo is jQuery selector. You need adjust that according your page
              • 4. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
                Marco1975
                Jari,

                i get an error "Object expected" in
                $(function()
                what should i put in stead of #foo the region_id ??

                Marco
                • 5. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
                  jariola
                  Hi,

                  Have you load jQuery library ?

                  Regards,
                  Jari
                  • 6. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
                    Marco1975
                    Jari,

                    i have loaded the folowing script
                    <script src="wwv_flow_file_mgr.get_file?p_security_group_id=829001774516334&p_flow_id=113&p_fname=jquery-1.4.2.min.js" type="text/javascript"></script>
                    Marco
                    • 7. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
                      jariola
                      Hi,

                      I did test on apex.oracle.com. Even it is Apex 4 this works
                      http://apex.oracle.com/pls/otn/f?p=40323:58

                      I did create report from select
                      select * from emp
                      HTML region before footer. Region source
                      <script type="text/javascript">
                      ;(function($){
                      $.htmldbIrBusyGrap=$.fn.htmldbIrBusyGrap=function(){
                      /* for bind IR ajax */
                       /* check do we have IR on page */
                       if($('#apexir_WORKSHEET_REGION').length>0){
                        /* replace apex internal function _BusyGraphic */
                        gReport._BusyGraphic=function(pState){
                         if(pState==1){
                          /* ir ajax start trigger htmldbIrAjaxStart event and show loading icon */
                          $.event.trigger('htmldbIrAjaxStart');
                          $('#apexir_LOADER').show();
                         }else{
                          /* check is there data stored to #apexir_WORKSHEET */
                          if(!$('#apexir_WORKSHEET').data('htmldb')){
                            /* store data to #apexir_WORKSHEET */
                            $('#apexir_WORKSHEET').data('htmldb',{irReady:true});
                            /* trigger htmldbIrReady event */
                            $.event.trigger('htmldbIrReady');
                           }
                           /* hide loading icon and trigger htmldbIrAjaxEnd*/
                           $('#apexir_LOADER').hide();
                          $.event.trigger('htmldbIrAjaxEnd');
                         };
                         return;
                        };
                        $.event.trigger('htmldbIrReady');
                       }
                      };
                      $.htmldbIrReady=$.fn.htmldbIrReady=function(fn){
                       $(function(){
                        if($.isFunction(fn)&&$('#apexir_WORKSHEET_REGION').length>0){
                         $('#apexir_WORKSHEET_REGION').bind('htmldbIrReady',fn);
                        }
                       });
                      };
                      })(jQuery);
                      addLoadEvent(function(){$.htmldbIrBusyGrap();});
                      </script>
                      Page HTML header
                      <script>
                      $(function(){$.htmldbIrReady(function(){alert('Hello');});});
                      </script>
                      Only difference for you is that you need also load jQuery , as it is not ready integrated to Apex 3.x.
                      Upload jquery-1.4.2.min.js to workspace Static Files and place at before anything else to page HTML header
                      <script src="#WORKSPACE_IMAGES#jquery-1.4.2.min.js" type="text/javascript"></script>
                      Regards,
                      Jari
                      • 8. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
                        Marco1975
                        Jari,

                        i have found my bug which prevented the Page from working.

                        i have a custom build apex_loader
                        <script src="#WORKSPACE_IMAGES#jquery-1.4.2.min.js" type="text/javascript"></script>
                        <script src="#APP_IMAGES#jquery.simplemodal-1.3.5.js" type="text/javascript"></script>
                        <script type="text/javascript">
                        /**
                         * @param pRegionStaticId ID of region to set to modal
                         * @param pOptions Options for modal Screen. See: http://www.ericmmartin.com/projects/simplemodal/#options for more info
                         */
                        goModal=function(pRegionStaticId, pOptions){
                          var vDefaults = {persist: true, overlayCss: {backgroundColor: '#606060'}}; // Note: It's important that you leave the persist = true otherwise items values will be cleared
                           
                          pOptions = jQuery.extend(true,vDefaults, pOptions);
                           
                          // To maintain order of APEX items (see forum posting above)
                          $('#' + pRegionStaticId).wrap('<div></div>');
                          // toon het ajax laad scherm
                          html_ShowElement('AjaxLoading'); 
                            
                          // Laat de region zien, in dit geval 'apexir_LOADER' --> het icoontje bovenin
                          //  $('#' + pRegionStaticId).show();
                           
                          // Open het modal scherm 
                          //  $('#' + pRegionStaticId).modal(pOptions); 
                         }// goModal
                         
                         /**
                         * Sluiten van het modal scherm
                         */
                         modalClose=function(){
                           // verberg het ajax laad scherm 
                           html_HideElement('AjaxLoading'); 
                           $.modal.close();
                        }// modalClose
                         
                        // OnLoad tasks
                        $(document).ready(function(){
                          // Voor alleen uit wanneer er een IR is op de pagina 
                          if ($('.apexir_WORKSHEET_DATA').length > 0) {
                            // See apex_ns_3_1.js for _BusyGraphic
                            
                            function dispIRBusyGraphics(pState){
                            if(pState == 1){
                                // Here apexir_LOADER is the object ID. 
                                // You can use your own region if you wanted to etc...
                             goModal('apexir_LOADER', {position:['30%',]});
                            }
                            else{
                               modalClose();
                            }
                            return;
                            }// dispIRBusyGraphics
                        
                          
                            function updateIRJS(){
                             // This time out is required since after the report is refreshed 
                             // via AJAX, need to reattach the l_LastFunction command
                             setTimeout(
                               function(){
                                gReport._BusyGraphic = function(pState){dispIRBusyGraphics(pState);};
                               },
                               1000
                              );
                             }
                             
                            gReport = new apex.worksheet.ws('');
                            gReport.l_LastFunction = function(){dispIRColGroups();}
                            // Need to put timeout since not registering on initialization
                            setTimeout(function(){gReport._BusyGraphic = function(pState){dispIRBusyGraphics(pState);};},500);
                            updateIRJS();
                          } //If IR exist
                        });
                        </script>
                        and when i disabled this on page 0 the functionality was working correctly.

                        Thanks for demoing this in the application.

                        Marco
                        • 9. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
                          jariola
                          Hi,

                          Ok, you can combine that custom loading you have taken from Martin's blog.
                          http://apex-smb.blogspot.com/2009/04/apex-interactive-reports-customize-wait.html
                          http://apex-smb.blogspot.com/2009/04/apex-interactive-reports-customize-wait_28.html

                          Remove code that you have copy from Martin's blog
                          Place this to page zero region before footer
                          <script type="text/javascript">
                          ;(function($){
                          $.htmldbIrBusyGrap=$.fn.htmldbIrBusyGrap=function(){
                          /* for bind IR ajax */
                           /* check do we have IR on page */
                           if($('#apexir_WORKSHEET_REGION').length>0){
                            /* replace apex internal function _BusyGraphic */
                            gReport._BusyGraphic=function(pState){
                             if(pState==1){
                              /* ir ajax start trigger htmldbIrAjaxStart event and show loading icon */
                              $.event.trigger('htmldbIrAjaxStart');
                              $('#apexir_LOADER').modal({persist:true,overlayCss:{backgroundColor:'#606060'},position:['30%',]});
                             }else{
                              /* check is there data stored to #apexir_WORKSHEET */
                              if(!$('#apexir_WORKSHEET').data('htmldb')){
                                /* store data to #apexir_WORKSHEET */
                                $('#apexir_WORKSHEET').data('htmldb',{irReady:true});
                                /* trigger htmldbIrReady event */
                                $.event.trigger('htmldbIrReady');
                               }
                               /* hide loading icon and trigger htmldbIrAjaxEnd*/
                               $.modal.close();
                              $.event.trigger('htmldbIrAjaxEnd');
                             };
                             return;
                            };
                            $.event.trigger('htmldbIrReady');
                           }
                          };
                          $.htmldbIrReady=$.fn.htmldbIrReady=function(fn){
                           $(function(){if($.isFunction(fn)&&$('#apexir_WORKSHEET_REGION').length>0){$('#apexir_WORKSHEET_REGION').bind('htmldbIrReady',fn)}});
                          };
                          })(jQuery);
                          addLoadEvent(function(){$.htmldbIrBusyGrap();});
                          </script>
                          And load jQuery and Simplemodal in page HTML header or page template HTML header

                          Regards,
                          Jari

                          Edited by: jarola on Sep 28, 2010 2:03 PM

                          Copy & paste mistake in code

                          Edited by: jarola on Sep 28, 2010 2:32 PM


                          I did update sample on apex.oracle.com
                          http://apex.oracle.com/pls/otn/f?p=40323:58
                          • 10. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
                            Marco1975
                            Jari,

                            thanks for the solution, i works now.

                            Now moving on to my pagination issues again ;-)
                            • 11. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
                              Marco1975
                              Jari,

                              do you have a way to capture a string in javascript

                              say i have a string "<td>10 - 50 of 200</td>" and i only want the "200" to be captured

                              i have tried with innerHTML.spilt('of') but then i get everything before the "of"

                              Marco
                              • 12. Re: Apex 3.2 hook javascripts to IR and execute those when report is refreshed
                                jariola
                                Hi,

                                I think you have typo "spilt". I guess it should be "split" ?

                                You can try something like
                                <script>
                                $(function(){
                                 var p=$.trim($('.pagination').find('span').text());
                                 var a= new Array();
                                 a=p.split(' ');
                                 alert('We have '+a.length+' objects in array');
                                 var j=a.length-1;
                                 $.each(a,function(i,v){
                                  alert('Object index '+i+' value is: '+v);
                                 });
                                 alert('Last object value is: '+a[j]);
                                });
                                </script> 
                                Regards,
                                Jari

                                Edited by: jarola on Sep 29, 2010 1:33 PM

                                I did forgot say you need jQuery for that. And for others this is about getting interactive report pagination page numbers and max rows from page span tag
                                Few examples more
                                <script>
                                $(function(){
                                 var p=$.trim($('#apexir_DATA_PANEL').find('td.pagination').find('span.fielddata').text());
                                 var a= new Array();
                                 var n= new Array();
                                 a=p.split(' ');
                                 alert('We have '+a.length+' objects in array');
                                 var j=a.length-1;
                                 $.each(a,function(i,v){
                                  alert('Object index '+i+' value is: '+v);
                                  if(!isNaN(v)){
                                   alert('Value '+v+' is number and will be stored to another array for later purpose');
                                   n.push(v);
                                  }
                                 });
                                 alert('Numbers we stored are:');
                                 $.each(n,function(l,m){
                                  alert(m);
                                 });
                                 return n;
                                });
                                </script> 
                                <script>
                                function IRgetPagination(){
                                 var p=$.trim($('#apexir_DATA_PANEL').find('td.pagination').find('span.fielddata').text());
                                 var a= new Array();
                                 var n= new Array();
                                 a=p.split(' ');
                                 $.each(a,function(i,v){
                                  if(!isNaN(v)){n.push(v)}
                                 });
                                 return n;
                                }
                                </script> 
                                With function IRgetPagination returns numbers from page "pagination" span in array.

                                Edited by: jarola on Sep 29, 2010 2:10 PM

                                I did correct typo in last example. One more example.
                                <script>
                                function IRgetPagination(){
                                 var p=$.trim($('#apexir_DATA_PANEL').find('td.pagination').find('span.fielddata').text());
                                 var a=new Array();var n=new Array();a=p.split(' ');
                                 $.each(a,function(i,v){if(!isNaN(v)){n.push(v)}});
                                 return n;
                                }
                                $(function(){
                                 var a=IRgetPagination();
                                 alert('Pagination first row: '+a[0]);
                                 alert('Pagination last row: '+a[1]);
                                 alert('Ir max rows: '+a[2]);
                                });
                                </script>