Search code examples
oracle-apexoracle-apex-19.1

Oracle APEX - How to refresh parent page IG if child modal dialog page opened from custom button


I have an IG on my page with a custom toolbar button that opens a Modal Dialog page. Because of how the modal dialog is opened, ther eisn't a way for me to capture its closure using native Dialog Close.

The javascript I use in my IG to open Modla Dialog is:

            apex.server.process(    
                'GenerateURL',
                {x01: l_url},
                {success: function (pData) {           
                    console.log(pData);
                    // Call Modal Dialog Page
                    apex.navigation.redirect(pData);
                },
                dataType: "text"     
           });

The issue is that after the modal dialog is closed I need to refresh my IG. How can I capture modal dialog closure from the parent page?


Solution

  • Modal dialogs should be opened with apex.navigation.dialog. When one calls apex_util.prepare_url for a modal page, it generates the correct JavaScript code that takes into account the settings for the destination page.

    There's an option, p_plain_url, that can be used to get just the URL, but don't enable that in GenerateURL as the rest is important. Another parameter, p_triggering_element, allows you to specify the element for a Dynamic Action (that's not an option with apex_page.get_url, which works similarly).

    Let's say GenerateURL looked like this (note that I'm passing document as the triggeringElement):

    declare
    
      l_url varchar2(512);
    
    begin
    
      l_url := apex_util.prepare_url(
        p_url                => 'f?p=' || :APP_ID || ':51:' || :APP_SESSION || ':::::P51_ID:' || apex_application.g_x01,
        p_triggering_element => 'document'
      );
    
      apex_json.open_object();
      apex_json.write('url', l_url);
      apex_json.close_object();
    
    end;
    

    Then the JavaScript code could be modified to this:

    apex.server.process(    
        'GenerateURL',
        {x01: idForURL},
        {success: function (pData) {           
          var funcBody = pData.url.replace(/^"javascript:/, '').replace(/\"$/,'');
    
          new Function(funcBody).call(window);
        }
    });
    

    Note that the JavaScript is passing an ID to the process that generates the URL, not the whole URL. This makes the use of the process somewhat limited which helps prevent users from abusing it. You could even add a check that verifies the user is able to view the ID value passed in.

    With that in place, you can add a Dynamic Action listening for the Dialog Closed event on the document (JavaScript Expression = document). Note that the event will not fire if the dialog is closed via the close or cancel buttons.