Tuesday, July 28, 2009

APEX: How to Pass Multiselect List Values in URL

When passing multiselect list values, or any multi LOV, in the URL you may have some unexpected behaviors. Here's an example: http://apex.oracle.com/pls/otn/f?p=20195:2100

If you take a look at the example you'll notice that the URL doesn't contain all the values that you may have submitted. For example I selected KING (7839), BLAKE (7698), and CLARK (7782). I would expect the URL to contain these values when I pass them via the URL. Instead the URL looks like this:

http://apex.oracle.com/pls/otn/f?p=20195:2100:1674288126968745::NO::P2100_EMPNO_LIST:7839:7698

Notice how only 2 values are passed in? That's because the delimiter used in LOVs is the same that is used in the URL. What can be even more confusing is that I selected 3 values but when I pass them in the URL only 1 is "accepted". This is because the last value in the URL is the "PrinterFriendly" parameter (please see: http://download.oracle.com/docs/cd/E14373_01/appdev.32/e11838/concept.htm#BEIJCIAG)

To fix the issue for all your mutli LOVs you can use a similar technique that I used to resolve the %null% issue. An example of the fix can be found here: http://apex.oracle.com/pls/otn/f?p=20195:2110. If you take a look at the example and select several employees the URL now looks like this:

http://apex.oracle.com/pls/otn/f?p=20195:2110:1674288126968745::NO::P2110_EMPNO_LIST:7839*7698*7782

Notice how the delimiters are *s for the empnos?

1- Create Application Process to replace colon delimiter with *
Note: You aren't limited to using * as your delimiter

Name: AP_REMOVE_URL_DELIM_FROM_ITEMS
Sequence: -10 (helps ensure that it is run before any other process
Point: On Submit: After Page Submission - Before Computations and Validations


BEGIN
FOR x IN (SELECT item_name,
REPLACE (v (item_name), ':', '*') new_item_value
FROM (SELECT item_name
FROM apex_application_page_items aapi
WHERE aapi.application_id = :app_id
AND aapi.page_id = :app_page_id
AND LOWER (display_as) IN ('checkbox', 'shuttle', 'select list', 'multiselect list') -- Limiting to these types. Can remove if you want to handle all types
AND ROWNUM > 0) x
WHERE INSTR (v (x.item_name), ':') > 0) LOOP
apex_util.set_session_state (x.item_name, x.new_item_value);
END LOOP;
END;


Note: This will replace the colon delimiter with a *. This may change some of your validations, page processes etc.

2- Create Application Process to replace * with colon delimiter on page load

Name: AP_RESET_URL_DELIM_FROM_ITEMS
Sequence: -10 (helps ensure that it is run before any other process)
Point: On Load: Before Header (page template header)


BEGIN
FOR x IN
(SELECT item_name,
REPLACE (v (item_name), '*', ':') new_item_value
FROM (SELECT item_name
FROM apex_application_page_items aapi
WHERE aapi.application_id = :app_id
AND aapi.page_id = :app_page_id
AND LOWER (display_as) IN
('checkbox', 'shuttle', 'select list', 'multiselect list') -- Limiting to these types. Can remove if you want
AND ROWNUM > 0) x
WHERE INSTR (v (x.item_name), '*') > 0) LOOP
apex_util.set_session_state (x.item_name, x.new_item_value);
END LOOP;
END;

3 comments:

  1. It appears that if you pass the values of a multiselect to a hidden value on the next page, they don't get 'reset' to the standard colon delimiter? For example, if I set the value of P2_FIELD on the submit of P1, the P2_FIELD always contains the *, and not the :.

    ReplyDelete
  2. Hi,

    On the Application Process that converts the "*" back to ":" you may want to include the Hidden and Protected item in the IN list so that they will get updated.

    Martin

    ReplyDelete
  3. Dear Martin
    I have a question.
    I am using one text field say DeptID, and and Multiselect list say ManagerID. Multi select gets populated automatically depending on the DeptID.
    Then I wish to have report depending on this DeptID and ManagerID. This works OK for a while and suddenly starts behaving strange by un-selecting these two fields at the time of submission for process and validation and I end up getting either No Data Found. Please suggest me a way to control this behavior of this report. I am using just one page with report regions and buttons.
    Your reply is very much appreciated.

    Regards
    Rao

    ReplyDelete