Sonntag, 7. März 2010

Refresh template based extjs tree dynamically...

In the last few posts i talked about how to use apex templates to create extjs trees and property grids. In this post i will show you how to refresh these regions dynamically....
Our report statement needs a special result set...
<br />select  dname as CATEGORY<br />      , empno as ID<br />      , ename as NAME<br />      , rank() over (partition by emp.deptno order by empno asc) as ROW_ASC<br />from emp, dept<br />where emp.deptno=dept.deptno<br />

Next thing we need is a template... I called mine "ExtJS_Tree_Report_With_Refresh".... It's basically the same as before....
Row Template 1
<br />{"text":"#CATEGORY#","expanded":true,"leaf":false,"children":[<br />{"text":"#NAME#","id":"#ID#","leaf":true}<br />

Row Template 1 Expression
<br />#ROW_ASC#=1 and #ROWNUM#=1<br />

Row Template 2
<br />]},{"text":"#CATEGORY#","expanded":true,"leaf":false,"children":[<br />{"text":"#NAME#","id":"#ID#","leaf":true}<br />

Row Template 2 Expression
<br />#ROW_ASC#=1 and #ROWNUM#!=1<br />

Row Template 3
<br />,{"text":"#NAME#","id":"#ID#","leaf":true}<br />

Row Template 3 Condition
<br />#ROW_ASC#!=1<br />

Before Rows
<br /><div id="tree-div#REGION_ID#">[<br />

After Rows
<br />]}]</div><br /><script type="text/javascript"><br />  Ext.onReady(function(){<br />  initTreeRegion('#REGION_ID#');<br />  })<br /></script><br />

The function "initTreeRegion" looks like that....
<br />function initTreeRegion(pId) {<br />    var myDiv = $x('tree-div'+pId);<br />    var myData = Ext.util.JSON.decode(myDiv.innerHTML);    <br />        myDiv.innerHTML = '';<br />        new Ext.tree.TreePanel({<br />          renderTo: 'tree-div'+pId,<br />          border:false,<br />          id: 'REGION_'+pId+'_tree',<br />          cls: 'myTreePanel',<br />          margins: '2 2 0 2',<br />          autoScroll: true,<br />          rootVisible: false,<br />          root:{ "text": "rootnode",<br />                 "expanded": true,<br />                 "children": myData <br />                }<br />        });<br />}<br />

It just recreates the extjs tree using the json object generated by refreshing the report region via $a_report()....
You can now easily refresh every tree region like that...
<br />$a_report('9159609248948926','1','100');<br />initTreeRegion('R9159609248948926');<br />

You only need to know the ID of the region...
Have fun...
Post only available in english!

Freitag, 12. Februar 2010

ExtJS Property Grids in APEX...

I found this example for creating an extjs property grid, which made me think how nice it would be, to have this in apex.... so i played around and came up with another report template....
Let's look at the example....

var propsGrid = new Ext.grid.PropertyGrid({
renderTo: 'prop-grid',
width: 300,
autoHeight: true,
source: {
'(name)': 'Properties Grid',
grouping: false,
autoFitColumns: true,
productionQuality: false,
created: new Date(Date.parse('10/15/2006')),
tested: false,
version: 0.01,
borderWidth: 1
},
viewConfig : {
forceFit: true,
scrollOffset: 2 // the grid will never have scrollbars
}
});

As you can see, what we basically have to do is to create the source part.... pretty much usual value pairs....
So, i created a new report template of type "Generic Columns (column template)" ... I called it ExtJS_PropertyGrid_Report...
Before Rows

<div id="prop-grid#REGION_STATIC_ID#"></div>
<script type="text/javascript">
Ext.override(Ext.grid.PropertyGrid, {
removeProperty: function(property){
delete this.source[property];
var r = this.store.getById(property);
if(r){
// remove property
this.store.remove(r);
}
}
});

function initRegion#REGION_STATIC_ID#() {
var propsGrid = new Ext.grid.PropertyGrid({
applyTo: 'prop-grid#REGION_STATIC_ID#',
id: 'myPropertyGrid#REGION_STATIC_ID#',
width: 300,
autoHeight: true,
source: {

I copied more or less the example from above, added #REGION_STATIC_ID# to make the names and ids unique.... Then i just add a value pair for every column in the report.... (Reports, that use this template should only have one row!!!)

Column Template 1

'#COLUMN_HEADER#':'#COLUMN_VALUE#',

I have a comma to much, so i add a dummy entry, which i instantly remove when the grid is created.....
After Rows

'MYDUMMY123':''},
viewConfig : {
forceFit: true,
scrollOffset: 2 // the grid will never have scrollbars
}
});
propsGrid.removeProperty('MYDUMMY123'); // remove the dummy entry
}

Ext.onReady(function(){
initRegion#REGION_STATIC_ID#();
});
</script>

I put the whole magic inside a function, so i can call it again, wenn i refresh the report via $a_report()....
Now we can create a report region with any select, that generates a one row result set.... the column names have to be unique....
For example:

select '01.06.1980' as "Birthday"
, 'Anja' as "Firstname"
, 'Hildebrandt' as "Name"
, 'Developer' as "Profession"
from dual

Select your new created template...
The result shoul look something like this....

That's it....
Have fun...
Anja


Dienstag, 9. Februar 2010

ExtJS tree via Apex report template....


This morning i needed to show some data in a simple ExtJS tree... Just a view categories with a few children each.... I could have created the needed json string with the pl/sql function i described in an earlier post, but i finally decided to build a little report template to use for this easy stuff...
That's what i came up with....

Create a new report template of type "Named Column (row template)"... I called mine "ExtJS_Tree_Report"...

Define the Row Templates as follows...

Row Template 1
<br />{  "text"     : "#CATEGORY#"<br /> , "expanded" : true<br /> , "leaf"     : false<br /> , "children" : [<br />                  {  "text" : "#NAME#"<br />                   , "id"   : "#ID#"<br />                   , "leaf" : true<br />                  }<br />

Use Based on PL/SQL Expression:
<br />#ROW_ASC#=1 and #ROWNUM#=1<br />

Row Template 2
<br />]},{  "text"     : "#CATEGORY#"<br />    , "expanded" : true<br />    , "leaf"     : false<br />    , "children" : [<br />                    {  "text" : "#NAME#"<br />                     , "id"   : "#ID#"<br />                     , "leaf" : true<br />                    }<br />

Use Based on PL/SQL Expression:
<br />#ROW_ASC#=1 and #ROWNUM#!=1<br />

Row Template 3
<br />,{  "text" : "#NAME#"<br />  , "id"   : "#ID#"<br />  , "leaf" : true<br /> }<br />

Use Based on PL/SQL Expression
<br />#ROW_ASC#!=1<br />


Before Rows
<br /><div id="tree-div#REGION_STATIC_ID#"></div><br /><script type="text/javascript"><br />Ext.onReady(function(){<br />  new Ext.tree.TreePanel({<br />            renderTo    : 'tree-div#REGION_STATIC_ID#',<br />            border      : false,<br />            id          : 'tree-panel',<br />            margins     : '2 2 0 2',<br />            autoScroll  : true,<br />            rootVisible : false,<br />            root:{ <br />                 "text"     : "rootnode",<br />                 "expanded" : true,<br />                 "children" : [<br />


After Rows
<br />     ]} <br />   ]}<br />  }); // new Ext.tree.TreePanel...  <br />}); //Ext.onReady...<br /><br /></script><br />


Now, create a new report region in your page with the following statement...
<br />select  dname as CATEGORY<br />      , empno as ID<br />      , ename as NAME<br />      , rank() over (partition by emp.deptno order by empno asc) as ROW_ASC<br />from emp, dept<br />where emp.deptno=dept.deptno<br />

These are the minimum columns my report template needs...
In the report attributes select your created report template and disable pagination...
That's it... Your result should look like this....






Montag, 8. Februar 2010

APEX navigation bar in sexy extJS toolbar...

It's been a while ;).... But i have a lot of new APEX and ExtJS stuff to blog about. I've been working on a complete extJs based template for my latest APEX project... So here is my first part of the upcoming series.... It's about how to get the usual apex navigation bar to show up in a sexy extJS toolbar...
There are 3 options i always have in my toolbar - logout, help, home... I usually use image buttons, so my definition looks something like this...


And in more detail....

Now we have to build up a little JSON object via navigation bar template.... This is what i put in my page template....

navigation bar
[{
xtype: 'box',
el: 'my_reg_pos_08'
},'->'#BAR_BODY#]
navigation bar entry
,{
xtype: 'box',
autoEl: {
tag: 'a',
href: '#LINK#',
cn: '<img src="#IMAGE#" alt="#TEXT#" />',
title : '#TEXT#'
}
},{xtype: 'tbspacer', width: 10}
As you can see, I build the complete json string to define my toolbar items.... I also include one of my region-position-divs (defined in the body below), because i need a bit of form-magic inside my toolbar....
The body looks something like this...

body

<div id="my_nav_bar"></div>
<div id="myTabs"></div>
<div id="my_messages">#GLOBAL_NOTIFICATION##SUCCESS_MESSAGE##NOTIFICATION_MESSAGE#</div>
<div id="my_box_body" width="100%">#BOX_BODY#</div>
<div id="my_reg_pos_01">#REGION_POSITION_01#</div>
<div id="my_reg_pos_02">#REGION_POSITION_02#</div>
<div id="my_reg_pos_03">#REGION_POSITION_03#</div>
<div id="my_reg_pos_04">#REGION_POSITION_04#</div>
<div id="my_reg_pos_05">#REGION_POSITION_05#</div>
<div id="my_reg_pos_06">#REGION_POSITION_06#</div>
<div id="my_reg_pos_07">#REGION_POSITION_07#</div>
<div id="my_reg_pos_08">#REGION_POSITION_08#</div>

<script type="text/javascript">
Ext.onReady(function(){
var nb = #NAVIGATION_BAR#;
var tb = new Ext.Toolbar({renderTo: 'my_nav_bar', items: nb});

var myform = new Ext.ux.FormViewport({
layout:'border',
items:[new Ext.Panel({
region:'north',
id: 'my_toolbar',
height: 40,
collapsible: false,
margins:'0 0 0 0',
allowDomMove:false,
tbar: tb
}),new Ext.Panel({
region:'south',
id: 'footer',
height: 22,
collapsible: false,
margins:'0 0 0 0',
html:'<div id="DeveloperToolbar"></div>'
}),
new Ext.Panel({
region:'west',
id:'my_info',
title:'Info',
split:true,
width: 220,
minSize: 175,
maxSize: 400,
collapsible: true,
margins:'40 0 5 5',
cmargins:'40 0 5 5',
contentEl: 'my_reg_pos_01',
layoutConfig:{
animate:true
}
}),new Ext.Panel({region:'center',
margins:'40 5 5 5',
id: 'my_workarea',
items: [tabs],
layout : "fit"
})
]
});
});
</script>
I don't use any usual html table layout. I only define a bunch of div regions according to the region positions, messages, navigation bar etc...
In the onReady-function i use the #NAVIGATION_BAR# substitution string to put my created json string inside a variable.
var nb = #NAVIGATION_BAR#;
Then i use nb as item parameter for my toolbar object ...
var tb = new Ext.Toolbar({renderTo: 'my_nav_bar', items: nb});
After that i am able to use tb in my actual page layout.... If everything works, it shoul look something like this....



In case your wondering... I used the customized viewport from Mark Lancaster to make sure, that my elements stay inside my apex form...
To get my developer toolbar inside the footer i used another tip from Mark, which you find here...