воскресенье, 11 апреля 2010 г.

Создание плагина в Oracle Application Express 4.0

Подробный, пошаговый пример создания простого плагина в Apex 4.0.

  1. Создать новое Database-приложение:
  2. Выбрать тип создаваемого приложения From Scratch:
  3. Вводим имя приложения (например: SimpleGoogleMapPlugin):
  4. Добавляем страницу в приложение:
  5. Создаём приложение:
  6. Перейти в Shared Components\User Interface\Plug-ins и нажать Create:
  7. Ввести имя плагина (например: Simple Google Map), внутреннее имя (например: com.yourcompany.apex.simple_google_map) и тип плагина (в нашем случае - Region). После этого нажать Create:
  8. Создать аттрибут:
  9. Ввести следующие значения:
    Scope: Application
    Attribute: 1
    Label: API Key
    Type: Text
    Required: Yes
    Translatable: No
    Display Length: 90
    Max Length: 120
    Default Value: Get key at http://code.google.com/apis/maps

  10. Нажать Create and Create Another.
  11. Аналогичным образом создать ещё 4 аттрибута:
    • Scope: Component
      Attribute: 1
      Label: Width
      Type: Integer
      Required: Yes
      Display Width: 4
      Maximum Width: 4
      Default Value: 600
    • Scope: Component
      Attribute: 2
      Label: Height
      Type: Integer
      Required: Yes
      Display Length: 4
      Max Length: 4
      Default Value: 400
    • Scope: Component
      Attribute: 3
      Prompt: Page Item containing Location
      Type: Page Item
      Required: Yes
      Default Value: P1_LOCATION
    • Scope: Component
      Attribute: 4
      Prompt: Page Item containing Tooltip
      Type: Page Item
      Required: No
  12. Перейти на вкладку Source и ввести в поле PL/SQL Code следующее:
     procedure render_simple_google_map (  
       p_region     in apex_plugin.t_region,  
       p_plugin     in apex_plugin.t_plugin,  
       p_is_printer_friendly in boolean )  
     is  
       -- It's better to have named variables instead of using the generic ones,  
       -- makes the code more readable  
       l_api_key  apex_appl_plugins.attribute_01%type  := p_plugin.attribute_01;  
       l_width  apex_application_page_regions.attribute_01%type := p_region.attribute_01;  
       l_height  apex_application_page_regions.attribute_02%type := p_region.attribute_02;  
       l_location apex_application_page_regions.attribute_03%type := v(p_region.attribute_03);  
       l_tooltip  apex_application_page_regions.attribute_04%type := v(p_region.attribute_04);  
     begin  
       -- During plug-in development it's very helpful to have some debug information  
       if wwv_flow.g_debug then  
        apex_plugin.debug_region (  
          p_plugin     => p_plugin,  
          p_region     => p_region,  
          p_is_printer_friendly => p_is_printer_friendly );  
       end if;  
       -- ***********************************  
       -- Here starts the actual plug-in code  
       -- ***********************************  
       apex_javascript.add_library (  
        p_name    => 'maps?file=api&v=2&key='||l_api_key,  
        p_directory  => 'http://maps.google.com/',  
        p_version   => null,  
        p_skip_extension => true );  
       -- Output the placeholder for the Google Map which is used by the Javascript code  
       sys.htp.p('<div id="'||p_region.static_id||'_map" style="width:'||l_width||'px; height:'||l_height||'px"></div>');     
       -- Initialize the Google map with location stored in the specified location page item.  
       -- The Javascript code is executed when the page has been rendered in the browser.  
       -- apex_javascript.escape are used to make sure that the values are properly escaped,  
       -- otherwise a " in the concatenated strings would break our Javascript code.  
       apex_javascript.add_onload_code (  
        p_code => '  
          if (GBrowserIsCompatible()) {    
          var lBounds = new GLatLngBounds();  
          var lMap = new GMap2($x("'||p_region.static_id||'_map"));  
          lMap.addControl(new GSmallMapControl());  
          lMap.addControl(new GMapTypeControl());  
          var lPoint = new GLatLng('||apex_javascript.escape(l_location)||');  
          lBounds.extend(lPoint);  
          lMap.setCenter(lPoint);  
          lMap.setZoom(lMap.getBoundsZoomLevel(lBounds)-4);'||  
          case when l_tooltip is not null then  
           ' var lTitle = "'||apex_javascript.escape(l_tooltip)||'";  
            var lMarker = new GMarker(lPoint);  
            lMap.addOverlay(lMarker);  
            lMarker.openInfoWindowHtml("<div class=\"tiny\">" + lTitle.replace(/~/g,"<br />") + "</div>");'  
          end||  
          '}' );  
     end render_simple_google_map;  
    
  13. Переходим в закладку "Callbacks" и в поле "Render Function Name" вводим "render_simple_google_map":
  14. Переходим в закладку "Settings". Заходим на http://code.google.com/apis/maps/signup.htm и запрашиваем API Key. Его значение вводим в поле API Key:
  15. Создаём новый регион:
  16. Выбирает тип региона - Plug-Ins:
  17. Выбираем доступный плагин:
  18. Вводим наименование региона (в нашем случае - Maps):
  19. Вводим значения аттрибутов (Width=600,Height=400,P1_LOCATION,P1_TOOLTIP):
  20. Создаём регион:
  21. Создаём новый элемент:
  22. Выбираем тип элемента - Text:
  23. Оставляем по-умолчанию:
  24. Вводим наименование элемента - P1_LOCATION:
  25. Вводим наименование поля на странице:
  26. Завершаем создание элемента. Аналогично создаем элемент P1_TOOLTIP.
  27. Создаем кнопку:
  28. Завершаем создание кнопки:
  29. Запускаем страницу:

четверг, 8 апреля 2010 г.

Application Express: создание CSS-кнопки

Создание три кнопки вместо cтандартных в Apex:

  1. Home -> Application Builder -> Application 101 -> Shared Components -> Templates -> Button:

     1.1  Definition (для первой кнопки):
     <span class="buttons">  
     <a href="#LINK#" class="positive">  
      <img src="#IMAGE_PREFIX#themes/ThemeName/img/positive.png" alt=""/>  
       #LABEL#</a>  
     <span>  
    
     1.2 Definition (для второй кнопки):
     <span class="buttons">  
     <a href="#LINK#" class="negative">  
       <img src="#IMAGE_PREFIX#themes/ThemeName/img/negative.png" alt=""/>  
       #LABEL#</a>  
     </span>  
    
     1.3 Definition (для третьей кнопки):
     <span class="buttons">  
       <a href="#LINK#" class="regular">  
       #LABEL#</a>  
     </span>  
    
  2. Создать css-файл для описания кнопки:
     .buttons a, .buttons button{  
       display:block;  
       float:left;  
       margin:0 7px 0 0;  
       background-color:#f5f5f5;  
       border:1px solid #dedede;  
       border-top:1px solid #eee;  
       border-left:1px solid #eee;  
       font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif;  
       font-size:12px;  
       line-height:130%;  
       text-decoration:none;  
       font-weight:bold;  
       color:#565656;  
       cursor:pointer;  
       padding:5px 10px 6px 7px; /* Links */  
     }  
     .buttons button{  
       width:auto;  
       overflow:visible;  
       padding:4px 10px 3px 7px; /* IE6 */  
     }  
     .buttons button[type]{  
       padding:5px 10px 5px 7px; /* Firefox */  
       line-height:17px; /* Safari */  
     }  
     *:first-child+html button[type]{  
       padding:4px 10px 3px 7px; /* IE7 */  
     }  
     .buttons button img, .buttons a img{  
       margin:0 3px -3px 0 !important;  
       padding:0;  
       border:none;  
       width:16px;  
       height:16px;  
     }  
     /* STANDARD */  
     button:hover, .buttons a:hover{  
       background-color:#dff4ff;  
       border:1px solid #c2e1ef;  
       color:#336699;  
     }  
     .buttons a:active{  
       background-color:#6299c5;  
       border:1px solid #6299c5;  
       color:#fff;  
     }  
     /* POSITIVE */  
     button.positive, .buttons a.positive{  
       color:#529214;  
     }  
     .buttons a.positive:hover, button.positive:hover{  
       background-color:#E6EFC2;  
       border:1px solid #C6D880;  
       color:#529214;  
     }  
     .buttons a.positive:active{  
       background-color:#529214;  
       border:1px solid #529214;  
       color:#fff;  
     }  
     /* NEGATIVE */  
     .buttons a.negative, button.negative{  
       color:#d12f19;  
     }  
     .buttons a.negative:hover, button.negative:hover{  
       background:#fbe3e4;  
       border:1px solid #fbc2c4;  
       color:#d12f19;  
     }  
     .buttons a.negative:active{  
       background-color:#d12f19;  
       border:1px solid #d12f19;  
       color:#fff;  
     }  
     /* REGULAR */  
     button.regular, .buttons a.regular{  
       color:#336699;  
     }  
     .buttons a.regular:hover, button.regular:hover{  
       background-color:#dff4ff;  
       border:1px solid #c2e1ef;  
       color:#336699;  
     }  
     .buttons a.regular:active{  
       background-color:#6299c5;  
       border:1px solid #6299c5;  
       color:#fff;  
     }  
    
  3. Загрузить данный файл на Web server (аналогично, тому как делается в Интеграции Oracle ApEx и extJS ).
  4. Загрузить следующие картинки в #IMAGE_PREFIX#themes/ThemeName/img:
    positive.png
    negative.png
  5. Получаются такие кнопки:


вторник, 6 апреля 2010 г.

Application Express: что такое Websheets? (на пошаговом примере приложения)

С выходом Apex 4.0 Early Adopter Phase II (EA2) стал доступен один из новых компонентов Apex 4.0 - Websheets. Данная функциональность позволяет конечным пользователям (быстро и просто) вводить, безопасно "расшарить" и предоставлять информацию. С помощью Web-браузера пользователь может создавать (если есть на права) страницы, секции страницы, таблицы и отчёты.


Рассмотрим возможности WebSheets на примере приложения.

  1. Создаём приложение типа WebSheets:
  2. Вводим название приложения (например: WebSheets Demo):
  3. Подтверждаем создание приложения:
  4. Запускаем приложение:
  5. Входим в приложение текущим пользователем Apex (по-умолчанию механизм аутентификации Application Express Account)
  6. Домашняя страница:
  7. Изменим текст региона на домашней странице:
  8. Для работы с текстом используется полноценный WYSIWYG-редактор:
  9. Создадим новую таблицу (DataGrid):
  10. Выбираем тип создаваемой страницы (в нашем случае - From Scratch):
  11. Определяем наименование таблицы и колонки:
  12. Таблица создана:
    Конечный пользователь может изменять свойства таблицы, колонок, добавлять колонки, валидацию, группировку и т.п.
  13. Добавим данные в таблицу:
  14. Получаем по-сути интерактивный отчёт с возможностью изменения структуры таблицы:
  15. Вернёмся на домашнюю страницу и создадим новый регион:
  16. Выбираем тип региона - Data:
  17. Выбираем источник данных:
  18. Завершаем создание региона:
  19. Аналогично добавим регион типа Chart:
  20. Добавим аннотации - один файл, один тэг и одну заметку:
  21. Получилась следующая страница:
  22. Теперь настроим авторизацию. Переходим в меню "Administration" -> "Access Control":
  23. Создаем новую запись(entry):
  24. Создадим ещё одну запись(entry). Получаем:
  25. Теперь зайдя в приложение под пользователем reader (он предварительно должен быть создан) видим что есть только права на просмотр страниц:

Application Express: использование всплывающих модальных окон из фреймворка jQuery

Варианты реализации:

Предлагаю два способа:
  • с использованием плагина SimpleModal;
  • с использованием стандартных диалоговых окон входящих в состав jQuery UI.

На мой взгляд второй вариант предпочтительнее, за счёт использования стандартного функционала Apex 4.0 (jQuery UI) и большей функциональности.

С использованием плагина SimpleModal

  1. Загрузить плагин SimpleModal с сайта: http://www.ericmmartin.com/projects/simplemodal
  2. Создаем две страницы в приложении (одна из которой открывается всплывающее модальное окно, вторая - собственно само содержимое всплывающего окна; в нашем случае страницы №1 и №2 соответственно)
  3. На странице №1 в свойствах установить в закладке "HTML Header and Body Attribute" значение "HTML Header":
     <style type="text/css">  
     body {height:100%; margin:0;}  
     h3 {color:#5f87ae; font-size:1.6em; padding:0; margin:0;}  
     #basic-modal-content {display:none;}  
     /* Overlay */  
     #simplemodal-overlay {background-color:#000; cursor:wait;}  
     /* Container */  
     #simplemodal-container {height:320px; width:600px; color:#bbb; background-color:#333; border:4px solid #444; padding:12px;}  
     #simplemodal-container code {background:#141414; border-left:3px solid #65B43D; color:#bbb; display:block; margin-bottom:12px; padding:4px 6px 6px;}  
     #simplemodal-container a {color:#ddd;}  
     #simplemodal-container a.modalCloseImg {background:url(../img/basic/x.png) no-repeat; width:25px; height:29px; display:inline; z-index:3200; position:absolute; top:-15px; right:-16px; cursor:pointer;}  
     #simplemodal-container #basic-modal-content {padding:8px;}  
     </style>  
     <script type="text/javascript" src="http://simplemodal.googlecode.com/files/jquery.simplemodal-1.3.4.js"></script>  
    
    здесь мы импортируем JavaScript-плагин SimpleModal на страницу, а так же CSS-стили для него:
  4. На странице №1 в свойствах установить в закладке "JavaScript" значение "Function and Global Variable Declaration":
     function modalOpen(pageNumber){  
      var newURL = window.location.protocol + "//" + window.location.host + "/apex/f?p=" +$v('pFlowId')+":"+pageNumber+":"+$v('pInstance')+":::::";  
      apex.jQuery.modal('<iframe src="' + newURL + '" height="100%" width="100%" style="border:0">', {  
      closeHTML:'',  
      containerCss:{  
       backgroundColor:"#fff",  
       borderColor:"#BDBDBD",  
       padding:0,  
       height:200,  
       width:200  
      },  
      overlayClose:false  
      });  
     }  
     function modalClose(){  
       apex.jQuery.modal.close();  
     }  
    
  5. На странице №1 создаём регион и добавляем туда кнопку по нажатие на которую будет открываться всплывающее модальное окно. Для этого в свойствах кнопки в закладке "Action When Button Clicked" установить значения полей:
    Action: Redirect to URL
    URL Target: javascript:modalOpen(2)

    ,где параметр функции есть номер страницы открываемой во всплывающем окне.
  6. Запускаем страницу №1 и нажимаем на кнопку:

С использованием стандартных диалоговых окон входящих в состав jQuery UI

  1. Создаем две страницы в приложении (одна из которой открывается всплывающее модальное окно, вторая - собственно само содержимое всплывающего окна; в нашем случае страницы №1 и №2 соответственно)
  2. На странице №1 в свойствах установить в закладке "JavaScript" значение "Function and Global Variable Declaration":
     var modalDialog=null;  
     function modalOpen(pageNumber,windowTitle,windowWidth,windowHeight){  
      var newURL = window.location.protocol + "//" + window.location.host + "/apex/f?p=" +$v('pFlowId')+":"+pageNumber+":"+$v('pInstance')+":::::";  
      modalDialog=apex.jQuery('<div></div>').html('<iframe src="' + newURL + '" height="100%" width="100%" style="border:0" frameborder="0">').dialog({autoOpen: false,modal: true,height: windowHeight,width: windowWidth,title: windowTitle});  
      modalDialog.dialog('open')  
     }  
     function modalClose(){  
      if (modalDialog!=null){  
       modalDialog.dialog('close');  
       modalDialog=null;  
      }  
     }  
    
  3. На странице №1 создаём регион и добавляем туда кнопку по нажатие на которую будет открываться всплывающее модальное окно. Для этого в свойствах кнопки в закладке "Action When Button Clicked" установить значения полей:
    Action: Redirect to URL
    URL Target: javascript:modalOpen(2,'Testing modal windows!!!',220,220)

    ,где первый параметр функции есть номер страницы открываемой во всплывающем окне, второй - наименование окна, третий - ширина окна, четвертый - высота окна.
  4. Запускаем страницу №1 и нажимаем на кнопку:

Дополнительные материалы: