Tuesday, January 22, 2008

Zapatec AJAX tree in APEX

In this post, I would like to demonstrate the way of using Zapatec AJAX tree in Apex.
From http://www.zapatec.com/ I downloaded the DHTML tree files.

After this, I applied some of them into my application. I decided to store them in my database, for maintainability.

There is the list of files that I used:
  • Java Script files
    • .. \zptree\src\tree.js
    • .. \utils\zapatec.js
  • CSS file
    • .. \zptree\themes\kde1.css
    • .. \zptree\themes\default.css
    • .. \zptree\themes\empty.css
    • .. \website\css\zpcal.css
    • .. \website\css\template.css
  • Images
    • Tree icons
      • .. \zptree\themes\kde1\folder_open.png
      • .. \zptree\themes\kde1\folder.png
      • .. \zptree\themes\kde1\document.png
    • Tree structure
      • .. \zptree\themes\img\fetching.gif
      • .. \zptree\themes\img\lines-b.gif
      • .. \zptree\themes\img\lines-c.gif
      • .. \zptree\themes\img\lines-s.gif
      • .. \zptree\themes\img\lines-t.gif
      • .. \zptree\themes\img\lines-v.gif
      • .. \zptree\themes\img\minus.gif
      • .. \zptree\themes\img\plus.gif
      • .. \zptree\themes\img\zpempty.gif

I imported it using Shred Documents -> Static Files -> Create
Next step, was adding css and javascript files to HTML Header of my page:
After that I changed all paths, that is used in css and javascripts to APEX ‘paths’, for example:
Original kde1.css

div.tree-item td.customIcon {
background: url("kde1/document.png") no-repeat 0 50%;
}

div.tree-item-expanded td.customIcon {
background: url("kde1/folder_open.png") no-repeat 0 50%;
}

div.tree-item-collapsed td.customIcon {
background: url("kde1/folder.png") no-repeat 0 50%;
}

APEX compatible:

div.tree-item td.customIcon {
background: url("wwv_flow_file_mgr.get_file?p_security_group_id=948527760686885&p_flow_id=100&p_fname=document.png") no-repeat 0 50%;
}

div.tree-item-expanded td.customIcon {
background: url("wwv_flow_file_mgr.get_file?p_security_group_id=948527760686885&p_flow_id=100&p_fname=folder_open.png") no-repeat 0 50%;
}

div.tree-item-collapsed td.customIcon {
background: url("wwv_flow_file_mgr.get_file?p_security_group_id=948527760686885&p_flow_id=100&p_fname=folder.png") no-repeat 0 50%;
}

After that I was ready to create a dynamical content for my tree. There is the needed structure for tree content:

<ul id="tree_defaults">
<li>Group 1
<ul>
<li>Sub Group 1
<ul>
<li>Document 1</li>
<
li>Document 2</li>
</ul>
</li>
<
li>Sub Group 2
<ul>
<
li>Document 3</li>
</ul>
<
/li>
</ul>
<
/li>
<
/ul>

<script type="text/javascript">
var tree_defaults = new
Zapatec.Tree({
tree: "tree_defaults",
defaultIcons: "customIcon",
saveState: true,
saveId: "saveState",
expandOnLabelClick: true,
highlightSelectedNode: true
});

</script>

In my case, I have to create content from two tables. One is the table of ‘groups’, another is the table of ‘documents’.


There is the source code of tree generating procedure:

function enum_documnet_tree (v_session integer) return varchar2
is
res varchar2(32000);

procedure add_str(v_str varchar2) is
begin
res := res || v_str || chr(10);
end;


procedure add_group(v_nid integer) is
v_name varchar2(256);
begin
select cname into v_name from group_table where nid = v_nid;
add_str('
<li>'||v_name);
add_str('<ul>');
for rec in (select nid, cname from group_table
where nparent_group = v_nid
order by 2) loop
add_group(rec.nid);
end loop;
for o_rec in (select o.cname, o.nid from documents o where ngroup = v_nid) loop

add_str('<li><a href="f?p=100:19:'||v_session||'::NO::P19_DOCUMENT_ID:'||o_rec.nid||'">'||o_rec.cname||'</a></li>');
end loop;
add_str('
</ul>');
add_str('
</li>');
end;
begin
res := '
<ul id="tree_defaults">';

for m_rec in (select nid from group_table where nparent _group is null) loop
add_group(m_rec.nid);
end loop;
for o_rec in (select o.cname, o.nid from documents o where ngroup is null) loop
add_str('
<li><a href="f?p=100:19:'||v_session||'::NO::P19_DOCUMENT_ID:'||o_rec.nid||'">'||o_rec.cname||'</a></li>');
end loop;
add_str('
</ul>');
add_str('
<script type="text/javascript">
var tree_defaults = new Zapatec.Tree({
tree: "tree_defaults",
defaultIcons: "customIcon",
saveState: true,
saveId: "saveState",
expandOnLabelClick: true,
highlightSelectedNode: true
});

<
/script>');
return res;
end;


Finaly I created a hidden item :P19_TREE. HTML region with source:
htp.p(:P19_TREE);

And process PL/SQL anonymous block (On Load – Before Header):
:P19_TREE:= enum_documnet_tree(:SESSION);

That’s it!

P.S. If you want to use this AJAX component, you have to read a Zapatec tree license agreement on http://www.zapatec.com/website/main/products/prod3/license.jsp

4 comments:

rain said...

Hi,
I want to learn something.How can I learn my project (p_security_group_id )?
thanks..

Kostya said...

The easiest way is to export your application and look at the source code of exported script. You can also find it in internal workspace as workspace identifier.

Phil Winfield said...

Have you got a demo of this on the APEX Oracle site please?

Kostya said...

I can made it. Because I'm very busy right now it will take some time.

Google