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:
apex.oracle.com/pls/otn/f?p=20195:2100:1674..::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:
apex.oracle.com/pls/otn/f?p=20195:2110:1674..::P2110_EMPNO_LIST:783976987782 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;