Jun 19

It’s great to see other people posting on APEX & ExtJS integration. Tobias Arnhold recently blogged about adding in Ext theme switching. We decided to take it a step further as we required all our child iframes (as our navigation links open in the center pane in a new tab panel within an iframe) to have the theme applied as well as saving the state in order for the theme switch to remain after page refreshing.

As we don’t want to steal Tobias’ thunder, head over his blog on how to integrate it. Then to add in the state saving and child frames support include the following code/reference to it in each of your page templates which are in use. Note: we use the default theme so to make this work we simply added another reference to our non-existent default theme “xtheme-aero.css” (with the “id=theme” reference as this is the one we will use to swap the others with).

Note: Also make sure noth your CSS files appear in the “head” section of the page in the order shown as the “Ext.util.CSS.swapStyleSheet” will put the new stylesheet reference in the header. We originally had defined ours later in the body (with the js source) as we had defined a loading progress/mask wrapped around but the theme switch wasn’t working. This was because our new theme was in the header but our ext-all.css was in the body and was overriding it, hence the term Cascading.

<link rel="stylesheet" type="text/css" href="&amp;EXT_BASE_DIR./resources/css/ext-all.css" />
<link rel="stylesheet" id="theme" type="text/css" href="&amp;EXT_BASE_DIR./resources/css/xtheme-aero.css" />
function switchExtTheme(pTheme,pDirBase) {
   var cookie = new Ext.state.CookieProvider();
   Ext.state.Manager.setProvider(cookie);
	Ext.util.CSS.swapStyleSheet('theme', pDirBase+pTheme);
	for (i=0;i<window.frames.length;i++) {
		try { window.frames[i].switchExtTheme(pTheme,pDirBase); }
		catch(e) { alert(e); }
	}
	cookie.set('ext-theme',pTheme);
}
Ext.onReady(function() {
  var cookie = new Ext.state.CookieProvider();
  Ext.state.Manager.setProvider(cookie);
  var ext_theme_css = cookie.get('ext-theme');
  if(ext_theme_css){
     switchExtTheme(ext_theme_css,gcExtBase);
  }
});

In the above source we have a global substitution string defined for the Ext directory base and our theme LOV values excludes it. In the page template header we simply define the global variable which we reference in all our scripts if we need to refer to any files. We just wanted a simple way to change/manage what Ext source we were using. The great thing about this code is that it will handle child frames within child frames.

<head>
<script type="text/javascript">
  var gcExtBase = '&amp;EXT_BASE_DIR.';
</script>
#HEAD#

On a final note we override all APEX combo’s with an Ext one so if your doing this you should note that if you’re using an onclick event then it will disappear after the transform, here’s the source we use: our theme select list has a class of “ext-theme-switcher” to identify it and add an Ext event listener…

function extComboFields(){
  Ext.select("select",true).each(function(select){
    var combo = new Ext.form.ComboBox({
        typeAhead: true,
        triggerAction: 'all',
        transform:select,
        width:select.getWidth(),
        forceSelection:true
    });
	 if (select.dom.className=="ext-theme-switcher") {
		var cookie = new Ext.state.CookieProvider();
		Ext.state.Manager.setProvider(cookie);
		var ext_theme_css = cookie.get('ext-theme');
		if(ext_theme_css){
		  combo.setValue(ext_theme_css);
		}
		combo.addClass(select.dom.className);
	   combo.on("select",function(combobox,record,index) {switchExtTheme(record.data.value,gcExtBase);});
	 }
  });
}

Here’s an example of the end result in development, you’ll see that there’s still a few labels that we need to sort out which are APEX specific and not defined in the Ext css files. Otherwise it works really well and is really quick. Thanks Tobias for the inspiration!!

APEX ExtJS - Theme Switching

Tagged with:
Oct 30

The thing I love about APEX is that you can always work outside of the box. We decied to use APEX to build our website for a number of reasons. Monitoring activity, scalability, portability, etc. etc. so during the devlopment phase we were required to build in some content management pieces around news and events, and thus storing the frequently updated content in backend tables, and the frontend solution was to write an APEX report to display the content.

However the default report templates didn’t provide the layout we required as we wanted to report on the data in a multi column format. The idea of generating this entirely using PLSQL wasn’t attractive as it doesn’t reuse alot of good APEX features, e.g. pagination, PPR, etc.

Website Example:

APEX 2 column report template

So we decided to see what we could do with the templates, and low and behold we found a nice documented feature/reserved word – “OMIT” which gave us the flexibility. The key was to use OMIT in the “Before Each Row” and “After Each Row” sections and use the TR tags in the column templates. We simply used even and odd pages to define the 2 columns…. as per below

APEX 2 column report template

The final piece was then to put each report row into an individual table to control the content. This was achieved by embedding the HTML in the report SQL

SELECT '<a title="'||devnews_description||'" rel="lightbox[development]" href="'||:IMAGE_PREFIX||'e-dba-website/theme_e-dba/images/'||devnews_image||'"><img class="report-image" src="'||:IMAGE_PREFIX||'e-dba-website/theme_e-dba/images/'||devnews_image||'" alt="" /></a>' ||'
<table border="0" cellspacing="0" cellpadding="0" width="230">
<tbody>
<tr>
<td class="t12data red-title-small" width="100%"><a class="t12data red-title-small" style="text-decoration:none;" href="'|| CASE WHEN devnews_page IS NOT NULL THEN 'APEX_UTIL.COUNT_CLICK?p_url=f?p='||:APP_ID||':'||devnews_page||':'||:APP_SESSION||'::::'||devnews_items||':'||devnews_item_values||'&amp;p_cat=APEX Demo - '||devnews_name||'&amp;p_id='||:APP_SESSION||'&amp;p_workspace='||:WORKSPACE_ID WHEN devnews_url IS NOT NULL THEN devnews_url ELSE '#' END ||'">'||devnews_name||'</a></td>
<td class="t12data" style="white-space:nowrap;">'||to_char(devnews_date, 'MON-YYYY')||'</td>
</tr>
<tr>
<td class="t12data" colspan="2">'||devnews_description||'</td>
</tr>
</tbody></table>
' devnews_event
  FROM eweb_devnews
 WHERE enabled = 'Y'
ORDER BY devnews_date desc

So the verdict is: yes we had to embed some HTML code in the Region source to achieve the final result however we were still able to extract the value of pagination and page templates. That’s why we love APEX because you can always find a solution to your problem!

preload preload preload