Sunday, 26 April 2009

Master-Detail View in ZK

In my latest ZK application, I implemented a typical master-detail view: a split bar in the middle; a tree view on the left and a table/grid on the right. Whenever an item in the treeview is clicked, the grid on the right-hand-side is updated to display the details of the clicked treeview item. The only thing 'special' about this application is that I factored the master (treeview) and details (grid) views as separate files and the main window/page uses <include> to put them together:
<?page title="" contentType="text/html;charset=UTF-8"?>
<zk>
<window border="none" width="100%" height="100%">
 <hbox spacing="0" width="100%" height="100%">
  <include src="analytical.zul"/>
  <splitter collapse="before"/>
  <include src="metricDetails.zul"/>
 </hbox>
</window>
</zk>

The <include> complicates things slightly: the master view which is firing the event has no visibility of who is going to handle the event. Therefore, the event's target field is set to null so that the event is broadcast to all root-level components on the page - including the included details view.

The event sending code is shown below. Note that the treeview of the master view is built using model and renderers and the event sending code is embedded in the renderer.

public class MetricTreeitemRenderer implements TreeitemRenderer {

 @Override
 public void render(Treeitem item, Object data) throws Exception {
  SimpleTreeNode t = (SimpleTreeNode)data;
  Metric metric = (Metric)t.getData();
  ... // construct Treecells
  Treerow tr = null;
  ... // construct the Treerow
  
  final Event e=new Event("onMetricClick", null, metric);
  tr.addEventListener(Events.ON_CLICK, new EventListener(){

   @Override
   public void onEvent(Event arg0) throws Exception {
    Events.postEvent(e);
   }
   
  });
 }
}
The event handling side is part of the included details view file:
<?page title="Metric Details" contentType="text/html;charset=UTF-8"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<zk>
<window id="win" title="Metric Details" border="none" width="100%" height="100%">
<attribute name="onMetricClick">
... handle the event by populating the grid 
</attribute>
<grid id="grid" vflex="true" width="100%" height="100%">

  <columns sizable="true">
   <column label=""/>
   <column label=""/>
  </columns>
  <rows>
...
  </rows>
 </grid>
</window>
</zk>
Note that even though the <window> is inside of the <zk> tag, it is still the root component (since it has no parent component in the .zul file). Also, although the .zul file has been included in the main file, it seems that it still has its own life cycle and its root component is unchanged.

1 comment:

Gunnerzz said...

I am having issues in including a .zul file in another .zul file. Basically I am including the second file into a tabpanel inside the main zul file.

Do we have to explicitly write java caode to render the second form in the first?