6 Replies Latest reply: Aug 28, 2013 2:56 PM by Joe Upshaw RSS

    Is it Possible to "Interrupt" an Interactive Report Refresh

    Joe Upshaw

      We have a particular Interactive Report for which we want to enforce two column filters as mandatory. We've already figured out how to examine the current filters and determine if they are set.

       

      What we need now is some mechanism by which if the user changes the filter criteria (for example deleting one of these mandatory filters), we can stop the APEX refresh and produce an error message. For example, could some such logic be placed in the Before Refresh event?

       

      Does anyone have any ideas how this might be done?

       

      -Joe

        • 2. Re: Is it Possible to "Interrupt" an Interactive Report Refresh
          VC

          I guess you try Cancel Event in the dynamic action but I don't think it will serve your purpose!

           

          17.9 Implementing Dynamic Actions

          • 3. Re: Is it Possible to "Interrupt" an Interactive Report Refresh
            Tom Petrus

            I've looked at this for a bit but I don't think there is any even remotely fair way to deal with this. The ajax calls for IRs do not use jQuery.ajax calls (unfortunate) but use a call to htmldb_Get.getAsync. An XmlHttpRequest object is created there but is of course never exposed, thus not allowing interaction on it, and is probably too deeprooted in the apex javascript to change. If it was using jQuery you could've tried to use the ajaxSetup, such as described in javascript - Abort Ajax requests using jQuery - Stack Overflow or Stop all active ajax requests in jQuery - Stack Overflow (and all variations when looking for ajax aborting).

             

            There is nothing you can do from say the before refresh event since canceling that is only canceling the before refresh event, not the actual refresh.


            I believe that simply overriding some function on the gReport object might serve you best. Keeping in mind it is best not fiddled with and is unsupported etc etc - I suppose you know the drill by now.

            There are a couple of candidates for this. "gReport.action" for example: you could simply block of any ajax action on the report before it happens: remove filters, add filters, search, pull - without having to worry about xmlhttprequests. I explored some other routes but honestly they became too complex for what it was.

             

            //first store the original _Get function. We can't lose this because we still need it.
            var old_Get = gReport._Get;
            
            
            //now override the existing function with our own implementation. Preserve the signature so that the params can
            //be passed on
            gReport._Get = function(p_widget_mod,p_widget_action,p_widget_action_mod,p_id,p_value,p_x05,p_x06,p_x07,p_x08,p_x09,p_x10){
              //lets do some arbitrary check in here
              if(p_widget_mod == "PULL"){
                 //now nothing will happen when you want to pull the report
                 return false;
              };
              //and dont forget to at least execute the original function !
              old_Get(p_widget_mod,p_widget_action,p_widget_action_mod,p_id,p_value,p_x05,p_x06,p_x07,p_x08,p_x09,p_x10);
            };
            
            
            

             

            Now when executing

            gReport.pull()
            

            nothing will happen.

             

            You'll need to modify this to suit your needs though. If this is taking it too far for you then you may have hit a brick wall though, I can't see any other option personally and so far.

            • 4. Re: Is it Possible to "Interrupt" an Interactive Report Refresh
              Joe Upshaw

              Tom,

               

              Thanks for replying. I am pretty comfortable with JavaScript...you should see some of the things I have tried so far for this problem LOL.

               

              I have attempted something similar to the approach that you provided. In my case, I hijacked the clicks that would get one into the filter window. I actually call a function to strip out the onclick from the HTML and replace it with my own calls. Very ugly and, as you pointed out, there are just to many ways to kick of the refresh to possibly account for them all.

               

              $( 'a.dhtmlSubMenuN[href="javascript:gReport.dialog2(\'SHOW_FILTER\');"],a[onclick^="gReport.dialog2(\'SHOW_FILTER\'"]' ).live('click',

                function()

                {

                  var endOfEventStack = setTimeout(

                    function()

                    {

                      customizeButtonOnClick('button#apexir_btn_APPLY[onclick^="gReport.column.filter"]');   

                    }, 100 );

                  endOfEventStack = setTimeout(

                    function()

                    {

                      customizeButtonOnClick('button#apexir_btn_DELETE[onclick^="gReport.column.filter_delete"]');      

                    }, 100 );

                });

               

              If you don't mind, I need a bit more information on your solution. *Where* exactly are you placing that code? If I could block all executions and have them directed to my own custom function, then, within it, I could check for the required filters and, if they are present simply call the original function and, if they are not, return false. If this is what your sample will do then, it is exactly what I am looking for.

               

              Thanks,

               

              -Joe

              • 5. Re: Is it Possible to "Interrupt" an Interactive Report Refresh
                Tom Petrus

                Well, since _Get is actually one of the core functions of the interactive reports it means that every ajax call for the IRs go through that function. You can verify that by looking at the interactivereport.js in /i/libraries/apex. _Get is called, and it will in turn call GetAsync. The interesting part of it is that by overriding it like this you can simply block any ajax from being fired completely, so you wouldn't need to worry about aborting existing requests.

                My code can just be called on load of the page. You can easily testdrive it by running it from the console and just put some console.log in there instead of my arbitraty p_widget_mod check and see it work. In the end, it doesn't do all that much and it allows the core functionality to keep working as it was.

                So basically you could check your function, and then if it is ok call the old _Get function. Potentially you could put the "old" _Get function in the gReport object even. You might need to testdrive it but this looks like it could do what you want. Might not be the cleanest but I'm not sure if there is a clean way. If there is I'm totally not seeing it.

                • 6. Re: Is it Possible to "Interrupt" an Interactive Report Refresh
                  Joe Upshaw

                  Works like a charm, Tom. Thanks.

                   

                  Also, you kind of opened my eyes to a whole new way of overriding deep JS with APEX. I intend to thoroughly abuse this new knowledge! mu hah hah hah (evil laugh)

                   

                  Also, I am going to open a enhancement request to allow Admin to optionally specify report filters as "mandatory." Hopefully, that will get some traction because I do really see the potential that a report might return quite well when certain filters are applied but, head out to lunch when they are not.

                   

                  Cheers,

                   

                  -Joe