APEX row selector part 2

后端 未结 1 1157
甜味超标
甜味超标 2021-01-15 18:45

This is a follow on to \"APEX row selector\" posted 5 days ago.

The problem was collecting multiple values from an interactive grid. From the excellent links to pos

1条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-15 19:09

    There are various ways you could do this. Here's one way, perhaps someone else will offer a more efficient option.

    The JavaScript options for navigation in APEX are documented here: https://docs.oracle.com/en/database/oracle/application-express/19.1/aexjs/apex.navigation.html

    Since you're trying to open a separate page, you probably want to use apex.navigation.dialog, which is what APEX automatically uses when opening modal pages from reports, buttons, etc.

    However, as noted in the doc, the URL for the navigation must be generated server-side for security purposes. You need a dynamic URL (one not known when the page renders), so you'll need a workaround to generate it. Once you have the URL, navigating to it is easy. So how do you get the URL? Ajax.

    Create an Ajax process to generate the URL

    1. Under the processing tab of the report/grid page, right-click Ajax Callback and select Create Process.
    2. Set Name to GET_FORM_URL.
    3. Set PL/SQL code to the following

    code:

    declare
    
      l_url varchar2(512);
    
    begin
    
      l_url := apex_page.get_url(
        p_application => :APP_ID,
        p_page        => 3,
        p_items       => 'P3_ITEM_NAME',
        p_values      => apex_application.g_x01
      );
    
      apex_json.open_object();
      apex_json.write('url', l_url);
      apex_json.close_object();
    
    end;
    

    Note that I'm using apex_item.get_url to get the URL, this is an alternative to apex_util.prepare_url. I'm also using apex_json to emit JSON for the response to the client.

    Also, the reference to apex_application.g_x01 is important, as this will contain the selected values from the calling page. You'll see how this was set in the next step.

    Open the URL with JavaScript

    Enter the following code in the Function and Global Variable Declaration attribute of the calling page:

    function openFormPage(ids) {
      apex.server.process(
        'GET_FORM_URL', 
        {
          x01: ids.join(':')
        }, 
        {
          success: function (data) {
            var funcBody = data.url.replace(/^"javascript:/, '').replace(/\"$/,'');
    
            new Function(funcBody).call(window);
          },
          error: function (jqXHR, textStatus, errorThrown) {
            console.error(errorThrown);
            // handle error
          }
        }
      );
    
    }
    

    In this case, I'm using apex.server.process to call the server-side PL/SQL process. Note that I'm passing the value of ids.join(':') to x01. That value will become accessible in the PL/SQL code as apex_application.g_x01. You can use additional items, or you can pass a colon-delimited string of values to just one item (as I'm doing).

    The URL that's returned to the client will not be a standard URL, it will be a JavaScript snippet that includes the URL. You'll need to remove the leading and trailing parts and use what's left to generate a dynamic function in JavaScript.

    This is generally frowned upon, but I believe it's safe enough in this context since I know I can trust that the response from the process call is not malicious JavaScript code.

    Add a security check!!!

    Because you're creating a dynamic way to generate URLs to open page 3 (or whatever page you're targeting), you need to ensure that the modal page is protected. On that page, create a Before Header process that validates the value of P3_ITEM_NAME. If the user isn't supposed to be able to access those values, then throw an exception.

    0 讨论(0)
提交回复
热议问题