Wednesday, February 20, 2008

Moving the Developer toolbar with ExtJS

Received and email on my blog, asking how to move the developer toolbar into the "south" region of a typical ExtJS layout. This is one of those annoyances developers see, but the end users don't. For a screenshot see my post from last year here. The solution is very short: In your page template include a div tag with an id, this is where you want the toolbar to end up. e.g. <div id="DeveloperToolbar"></div> Add the following code into your application javascript:

Ext.app.moveDeveloperToolbar = function() {
  var dest = Ext.get('DeveloperToolbar');
  if (dest) {
      var els=Ext.select("table[summary='Developer Toolbar']",false);
      els.each(function(el){
          el.replace(dest);
      })
  }
}


Ext.onReady(function() {
    /** any other stuff you want to include */   
    Ext.app.moveDeveloperToolbar();
});

The code checks the div tag exists, and then searches for a table with a summary property of "Developer Toolbar". For each instance it finds (there is only ever one), it moves it to the destination position. ExtJS has a powerful DomQuery component, well worth learning. See the DomQuery tutorial for further examples. Mark

Thursday, February 14, 2008

ExtJS Ajax Search field

Here is a screenshot of an AJAX search field running in Apex. Putting an example up on the Oracle Apex demo site may not be possible, as I call a PL/SQL package directly. It's based on the ExtJS live search sample. We were running it with Ext version 1.1, but had issues with paging. By default it uses "start" and "limit" as parameters - both reserved words with PL/SQL. If you search the Ext forums, you'll find a solution for Ext 2.0 - just search for mark.lancaster.

Wednesday, February 13, 2008

Ext JS extension like Forms LOV

Just noticed on the ExtJS forums that someone has built an extension that behaves like an Oracle Forms LOV. Here is the post and a demo. Old forms programmers never die :)

Tuesday, February 12, 2008

Building a complete Oracle Apex page template using ExtJS

Following on from my earlier post on integrating ExtJS we will now build a complete page template.
This template will contain:
  • a "north" region containing a logo, title, navigation bar and show current user
  • a "west" region containing 2 sub-regions navigation and settings
  • a "center" region containing dynamic page content
  • a "south" region for footer elements, e.g. copyright notices, links etc.
When prototyping its often easier to build using static html pages, and then load it into Oracle Apex.

Create a sub-directory in the /ext-2.0.1/examples/ directory. I've called mine "playpen", but it really doesn't matter.

Save the following text as a html file into the directory, e.g. "apex layout.html".

<html lang="&BROWSER_LANGUAGE.">
<head>
 <title>#TITLE#</title>
 <!-- standard stylesheets -->
 <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />

 <!-- this style forces form to fit screen height -->
 <style type="text/css">
   #wwvFlowForm {width:100%; height:100%;}
 </style>

 <!-- Ext scripts -->
 <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
 <script type="text/javascript" src="../../ext-all.js"></script>

 <!-- application configuration -->
 <!-- eventually move "application" script to an external file -->
 <script type="text/javascript">
   Ext.onReady(function(){

      Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

      var myForm = new Ext.Panel({
        applyTo:'wwvFlowForm',
        layout:'border',
           items:[
               new Ext.BoxComponent({ // raw
                   region:'north',
                   el: 'north',
                   height:45
               }),
               new Ext.BoxComponent({ // raw
                   region:'south',
                   el: 'south',
                   height:32
               }),
              {
               region:'west',
               id:'west-panel',
               title:'West',
               split:true,
               width: 200,
               minSize: 175,
               maxSize: 400,
               collapsible: true,
               layout:'accordion',
               layoutConfig:{
                   animate:true
               },
               items: [{
                   contentEl: 'region_position_02',
                   title:'Navigation',
                   autoScroll:true,
                   border:false
               },{
                   contentEl: 'region_position_03',
                   title:'Settings',
                   autoScroll:true,
                   border:false
               }]
           },{
               region:'center',
               contentEl:'pageContent',
               layout:'column',
               autoScroll:true
           }]
       });

   myForm.doLayout();
   });
 </script>
</head>
<body>
<form id="wwvFlowForm">

<!-- -------------------------------------BODY SECTION start------------------------------------- -->
  <div id="north">
    <table cellpadding="0" cellspacing="0" border="0" width="100%" height="45px">
      <tr>
        <td valign="top">#LOGO#</td>
        <td align="center"><span style="{  }">Integrating ExtJS javascript library with Oracle Application Express</span></td>
        <td width="300px" align="right" border="0" style="padding-right:5px">
          <div style="height:20px">&USER.</div>
          <div id="navigation_bar">#NAVIGATION_BAR#</div>
        </td>
      </tr>
    </table>
  </div>

  <div id="west"></div>

  <div id="region_position_02">#REGION_POSITION_02#</div>
  <div id="region_position_03">#REGION_POSITION_03#</div>

  <div id="pageContent">
    <div id="region_position_01">#REGION_POSITION_01#</div>
    <div id="messages" align="center">#GLOBAL_NOTIFICATION##NOTIFICATION_MESSAGE##SUCCESS_MESSAGE#</div>
    <div id="region_box_body">#BOX_BODY#</div>
    <div id="region_position_04">#REGION_POSITION_04#</div>
    <div id="region_position_05">#REGION_POSITION_05#</div>
    <div id="region_position_06">#REGION_POSITION_06#</div>
    <div id="region_position_07">#REGION_POSITION_07#</div>
    <div id="customize">#CUSTOMIZE#</div>
    <div id="region_position_08">#REGION_POSITION_08#</div>
  </div>
<!-- -------------------------------------BODY SECTION end------------------------------------- -->

</form>

  <div id="south">Some footer content here</div>
</body>
</html>


Open it in your browser and you should see something like this:



Note the "West" panel expands and collapses and is resizable, and the navigation panel is also functional. Resize the width of the West panel, then refresh the page.

Did you notice it kept the new width?

This is all managed by a single line of code:

Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

The panels that make up the page are stateful and remember position, provided a cookie has been registered. Users typically don't even notice unless you point it out to them.

Spend a bit of time looking at the script used to build the layout, consult the ExtJS doco etc.

OK, to make this an Oracle Apex template do the following:

Do a search and replace:


<form id="wwvFlowForm"> becomes #FORM_OPEN#


</form> becomes #FORM_CLOSE#

Adjust the path of the javascript and css file links, so if you followed my previous post:
../../becomes /i/themes/ext-2.0.1/

Copy and paste the content into a page template using header, body and footer regions.
The html already contains comments identifying where to cut.

Whip up a quick page to test it out, and barring any mistakes it should work just like the static version.

Enjoy.

Tuesday, February 5, 2008

Integrating Ext javascript library into Oracle Application Express

So hopefully by now you’ve been to the website http://extjs.com and had a look at samples http://extjs.com/deploy/dev/examples and are ready to get your hands dirty.

The first step is to download the latest version from http://extjs.com/download and load it onto your http server 
(version 2.0.1 at the time of writing).
For Oracle Apex this can be either:
- Embedded PL/SQL gateway
- Oracle HTTP Server and mod_plsql.

For this article I have loading the complete set of unzipped files to a new folder in the 
apex/images/themes directory:
- http server - ORACLE_BASE/ORACLE_HOME/Apache/Apache/images/themes/ext-2.0.1/
- embedded PL/SQL gateway - /i/themes/ext-2.0.1/

Note: FTP access when using the embedded PL/SQL gateway is enabled as follows:

Open SQL*Plus and connect as SYSTEM

SQL> exec dbms_xdb.setftpport('21'); PL/SQL procedure successfully completed. SQL> alter system register; System altered.
If you have any issues do an internet search for "dbms_xdb.setftpport", there are numerous posts on the topic. Once the files are uploaded you can verify using the following urls: http://hostname:port/i/themes/ext-2.0.1/docs/index.html http://hostname:port/i/themes/ext-2.0.1/examples/index.html Using Ext with Oracle Apex The first step to using Ext with Oracle Apex is to reference the javascript libraries and CSS stylesheets in your page templates. Start Apex Builder and navigate to a page template: Home> Application Builder> Application 101> Shared Components> Templates> Edit Page Template A minimal header definition would look like this:
<html lang="&BROWSER_LANGUAGE."> <head> <title>#TITLE#</title> #HEAD# <!-- standard stylesheets --> <link rel="stylesheet" type="text/css" href="/i/themes/ext-2.0.1/resources/css/ext-all.css" /> </head> <body #ONLOAD#> <!-- Ext scripts --> <script type="text/javascript" src="/i/themes/ext-2.0.1/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="/i/themes/ext-2.0.1/ext-all.js"></script> <!-- application configuration --> <!-- add your custom scripts references here --> #FORM_OPEN#
This gives us access to the entire Ext library functionality. Depending on how much Ext functionality your web-site eventually uses you may want to consider only including a subset of the library. I’ll write more on this in a later article. If your using a standard theme that comes with Oracle Apex, you will probably want to keep existing javascripts and CSS stylesheets in your definition initially. Let’s build something The first example I want to demonstrate is resizable text areas. A demo is available at http://apex.oracle.com/pls/otn/f?p=200801:2001:0 Add the following code into your page template, or directly into a page containing one or more text areas.
<script type="text/javascript"> // convert html textareas into resizable textareas function makeResizable(){ var els=Ext.select("textarea",true); els.each(function(el){ var dwrapped = new Ext.Resizable(el, { wrap:true, pinned:true, //handles:'s', width:el.getWidth(), height:el.getHeight(), minWidth:el.getWidth(), minHeight: el.getHeight() }); }) } Ext.onReady(function() { makeResizable(); }); </script>
What this script does search the html document object model (dom) for html textarea elements. Html textarea elements are converted to an Ext resizable component, with grab handles pinned (visible). The minimum height and width are constrained to the original dimensions. Uncomment the //handles:'s' line to vertically resize only. You can read more about the api on your website if you used my instructions at http://hostname:port/i/themes/ext-2.0.1/docs/output/Ext.Resizable.html, or on the Ext website at http://extjs.com/deploy/dev/docs/index.html.