среда, 21 декабря 2011 г.

Делаем ссылки

Ссылки на страницы в большинстве случаев APEX генерирует самостоятельно. Но иногда это приходится делать самому. Подробно про ссылки написано тут: Understanding URL Syntax, а кратко - читайте ниже.



Теория

Ссылка на страницу выглядит так:

http://mysite.com/apex/f?p=App:Page:Session:Request:Debug:ClearCache:itemNames:itemValues:PrinterFriendly

параметры, идущие после f?p, означают следующее:
App - номер приложения APEX
Page - номер страницы в приложении
Session - ID сессии
Request - это параметр, заполняемый при нажатии кнопки. Каждая кнопка приложения может заполнять этот параметр значением (которое можно задать в свойствах кнопки); таким образом, на странице можно узнать, с какой кнопки осуществлялся заход.
Debug - параметр, указывающий, показывать или нет отладочную информацию, может принимать значение 'YES' или 'NO'. Честно скажу - пока использовать не пробовал.
ClearCache - параметр указывает, очищать или нет значения итемов. Принимает значения 'YES' или 'NO', также через двоеточие можно указать страницу, к которой этот параметр будет применяться.
itemNames и itemValues - названия и значения итемов, которые нужно передать на страницу. Если нужно передать несколько параметров, названия и значения пишутся через запятую.
PrinterFriendly - параметр, также принимающий значения 'YES' или 'NO'. YES будет означать, что со страницы будет убрано оформление, мешающее печати (заголовки регионов, средства навигации и т. п.).

Практика

На практике, скорее всего, вы можете захотеть вставить ссылку статично (написав один раз руками в разделе Source региона страницы) или генерировать в PL/SQL коде (например, в PL/SQL регионе).
Конечно, вы можете просто писать так:

http://mysite.com/apex/f?p=123:456

Но если страница непубличная, пользователь ее не увидит, потому что для доступа на страницу пользователь должен будет предъявить "входной билет" - ID сессии в URL. Или вы можете захотеть, чтобы в зависимости от внешних условий ссылка вела в разные места или передавала параметры на новую страницу.

Задаем URL в тексте

Здесь нам понадобятся Substitution Strings - строки подстановки. Перечисленные выше параметры задаются таким способом:

ПараметрСпособ задания
App&APP_ID.
Page&APP_PAGE_ID.
Session&APP_SESSION.
Debug&DEBUG.
PrinterFriendly&PRINTER_FRIENDLY.

Обратите внимание: вместо &APP_ID., &APP_PAGE_ID. и &APP_SESSION. апекс подставит в URL номера текущих приложения, страницы и сессии. И если для приложения и сессии это имеет смысл (вы ссылаетесь на страницу в том же приложении, в каком сейчас работаете), то вставлять в ссылку номер текущей страницы бессмысленно - вы и так на ней находитесь. Поэтому, скорее всего, вы будете ставить туда просто номер нужной страницы.
Отдельный разговор - про передачу параметров. Например, нам нужно сделать ссылку на страницу  5, на которой есть три поля P5_NUMBER1, P5_NUMBER2 и P5_NUMBER3, и в которые надо поместить значения 5, NULL и 6 соответственно. Нам нужно будет перечислить названия этих полей через запятую, а потом также через запятую перечислить их значения и поставить на нужные места в URL:

http://mysite.com/apex/f?p=&APP_ID.:5:&APP_SESSION.::NO:5:P5_NUMBER1,P5_NUMBER2,P5_NUMBER3:5,,6:

Теперь осталось создать регион с типом HTML Text и в поле Source написать:
<a href="http://mysite.com/apex/f?p=&APP_ID.:5:&APP_SESSION.::NO:5:P5_NUMBER1,P5_NUMBER2,P5_NUMBER3:5,,6:">Ссылка на страницу 5</a>

Создаем ссылку на PL/SQL

Строки подстановки в PL/SQL выглядят так:

ПараметрСпособ задания
AppAPEX_APPLICATION.G_FLOW_ID
Page:APP_PAGE_ID
SessionV('APP_SESSION')
Debug:DEBUG
PrinterFriendlyV('PRINTER_FRIENDLY')

Для большего упрощения можно использовать вот такую функцию:

function link(
    p_number      in number,                                      -- номер страницы
    p_site        in varchar2 default null,                       -- адрес сайта
    p_app_id      in varchar2 default APEX_APPLICATION.G_FLOW_ID, -- номер приложения
    p_session     in varchar2 default V('APP_SESSION'),           -- ID сессии
    p_clear_cache in varchar2 default '::NO',                     -- очистка кэша
    p_parameters  in varchar2 default null,                       -- список параметров
    p_values      in varchar2 default null                        -- список значений параметров
    ) return varchar2
is
begin
  return p_site || 'f?p=' || p_app_id || ':' || p_number || ':' || p_session || p_clear_cache || ':' || 
         p_number || ':' || p_parameters || ':' || p_values;
end; 

Теперь нам достаточно написать в PL/SQL коде такую строчку:

url := link(5);

И в переменной url у нас окажется сгенерированная ссылка:

f?p=123:5:390416190148979

Для удобства вы можете объявить функцию несколько иначе - например, сделать больше обязательных параметров, а какие-то из них вообще выкинуть (например, p_site и p_app_id - если точно знаете, что в ближайшем будущем у вас будет один сайт и одно приложение на нем).

4 комментария:

  1. Спасибо за статью.
    Жаль только не нашел того что искал.
    Если конкретнее, то как передавать в item переменную.
    Например:
    'f?p=&APP_ID.:1:&SESSION.::NO::P1_BUN_ID:#bun_id#:'
    Такая ссылка не работает.
    А также я не нашел в этой статье того как можно добавить условия на переход на ту или иную страницу и передачу тех или иных данных.

    ОтветитьУдалить
  2. "Если конкретнее, то как передавать в item переменную. "

    Давайте еще конкретнее ;)
    У вас есть страница, на которой есть item BUN_ID, и вам надо на этой странице разместить ссылку на страницу 1 так, чтобы при переходе по ссылке в item P1_BUN_ID попало значение item BUN_ID с предыдущей страницы? Тогда url должен выглядеть так:
    'f?p=&APP_ID.:1:&SESSION.::NO::P1_BUN_ID:&bun_id.:'

    Ну и естественно, на момент рендеринга страницы item BUN_ID должен иметь какое-то значение, иначе там будет NULL.

    Символ # используется, когда нужно сделать ссылку из столбца отчета, а в качестве передаваемого значения передать значение столбца bun_id из результата запроса.

    Про второй вопрос (" как можно добавить условия на переход на ту или иную страницу и передачу тех или иных данных") не очень понятно, что именно нужно сделать. Если сделать ссылку так, чтобы один и тот же url вел в разные места - то напрямую это невозможно, есть ряд обходных путей, в зависимости от того, что уже есть и что хочется сделать.

    ОтветитьУдалить
  3. Здравствуйте решил воспользоваться new htmldb_Get(null,html_GetElement('pFlowId').value, 'APPLICATION_PROCESS=GET_PHONE',0); при вызове метода get('XML') возвращает null что делать, ондемонд процесс валиден проверял названия совпадают

    ОтветитьУдалить
    Ответы
    1. Общий план действий при отладке ajax такой:
      1. В javascript функцию после htmldb_Get() надо вставить вызов функции alert() - она выводит сообщение на экран. Нужно для того, чтобы убедиться, что вызов вообще происходит.
      2. Убедиться, что серверный процесс выполняется. Для этого проще всего сделать отдельную таблицу для логирования, и сделать вставку в эту таблицу в начале и в конце процесса. Тогда можно будет убедиться, что вызов происходит и какой-то результат есть.
      3. После этого можно взяться за обработку получаемого ответа опять в javascript. Для начала - сравнить, что отправляется с сервера с тем, что приходит в браузер.

      А вообще отладка javascript для меня пока выглядит больше шаманством, чем программированием. Я его плохо знаю.

      Удалить