ZK - Open Source Ajax Java FrameworkZK - Open Source Ajax Java Framework

Maintain Tree status

Thiru
8 Mar 2010 08:55:08 GMT
8 Mar 2010 08:55:08 GMT

Hi,

I have a sample code to render data in zk Tree component.

There are two issues

1.Suppose after data is render , the user may collapse the groups.
If existing data is to modified or new data is added,how to maintain previous status
i.e collapsed status.

2.How to sort the data of treeitems by maintaing previous status.

Please provide any suggestions/ideas.Thanks in advance

Please find below the sample code...


<zk xmlns="http://www.zkoss.org/2005/zk/native"
xmlns:zul="http://www.zkoss.org/2005/zul"
xmlns:zk="http://www.zkoss.org/2005/zk">
<zul:zscript>
public class Person {
private String _name;
private String _email;
private String _accountId;
private boolean _groupItem = true;

public Person(String name, String email, String dep) {
super();
_name = name;
_email = email;
_accountId = dep;
}

public String getAccountId() {
return _accountId;
}

public void setAccountId(String account) {
_accountId = account;
}

public String getEmail() {
return _email;
}

public void setEmail(String email) {
_email = email;
}

public String getName() {
return _name;
}

public void setName(String name) {
_name = name;
}

public boolean isGroupItem() {
return _groupItem;
}

public void setGroupItem(boolean groupItem) {
_groupItem = groupItem;
}

}


import org.zkoss.zul.Treecell;
import org.zkoss.zul.Treeitem;
import org.zkoss.zul.TreeitemRenderer;
import org.zkoss.zul.Treerow;
import org.zkoss.zul.SimpleTreeNode;
public class PersonTreeitemRenderer implements TreeitemRenderer {

public void render(Treeitem item, Object data) throws Exception {
SimpleTreeNode t = (SimpleTreeNode)data;
Person person = (Person)t.getData();
Treecell tcEmail = new Treecell(person.getEmail());
Treecell tcName = new Treecell(person.getName());
Treecell tcAccountId = new Treecell(person.getAccountId());
Treerow tr = null;
if(item.getTreerow()==null){
tr = new Treerow();
tr.setParent(item);
}else{
tr = item.getTreerow();
tr.getChildren().clear();
}
tcName.setParent(tr);
tcEmail.setParent(tr);
tcAccountId.setParent(tr);
item.setOpen(true);
tr.addEventListener("onClick", new EventListener() {
public void onEvent(Event event) throws Exception {
updateItem(tr,t);
}
});

}
}



String[] name = {"Pierre","Adam","Thomas"};
String[] accountId = {"p001","a002","t003"};
ArrayList alc = new ArrayList();
for(int i =0; i < name.length; i++){
Person person = new Person(name,name + "@zkoss.org",accountId);
person.setGroupItem(false);
SimpleTreeNode stn = new SimpleTreeNode(person,new ArrayList());
alc.add(stn);
}


SimpleTreeNode rdDep = new SimpleTreeNode(new Person("RD","",""),alc);

String[] name2 = {"Paul","Eric","Gray"};
String[] accountId2 = {"p002","e009","g019"};
ArrayList alc2 = new ArrayList();
for(int i =0; i < name.length; i++){
Person person = new Person(name2,name2 + "@zkoss.org",accountId2);
person.setGroupItem(false);
SimpleTreeNode stn = new SimpleTreeNode(person,new ArrayList());
alc2.add(stn);
}


SimpleTreeNode salesDep = new SimpleTreeNode(new Person("Sales","",""),alc2);


ArrayList al = new ArrayList();
al.add(salesDep);
al.add(rdDep);
SimpleTreeNode root = new SimpleTreeNode("ROOT",al);


SimpleTreeModel stm = new SimpleTreeModel(root);

//create a PersonTreeitemRenderer
PersonTreeitemRenderer ptr = new PersonTreeitemRenderer();


public void updateItem(Treerow tr,SimpleTreeNode t){
//alert("ss");
Person test = (Person)t.getData();
System.out.println("t name "+ test.getName() + t.isLeaf());
test.setName(test.getName()+ "Clicked");
tr.getParent().setParent(null);
// tree.removeChild(tr);
//tree.setModel(stm);
}

public void update(treeid){

SimpleTreeNode firstNode = alc.get(0);
Person test = (Person)firstNode.getData();
test.setName("Name Updated");
treeid.setModel(stm);
}

public void add(treeid){

Person person = new Person("NewName", "@zkoss.org","767676");
SimpleTreeNode stn = new SimpleTreeNode(person,new ArrayList());
alc.add(stn);
treeid.setModel(stm);

}
</zul:zscript>
<zul:tree checkmark="true" multiple="true" width="450px" treeitemRenderer="${ptr}" model="${stm}" id="tree" >
<zul:treecols>
<zul:treecol width="120px" label="Name" />
<zul:treecol width="120px" label="Email" />
<zul:treecol width="120px" label="AccountId" />
</zul:treecols>
</zul:tree>

<zul:button label="Update" onClick="update(tree)"/>
<zul:button label="Add" onClick="add(tree)"/>
</zk>

jimmyshiau
8 Mar 2010 22:30:06 GMT
8 Mar 2010 22:30:06 GMT

Hi, Thiru
Maybe you can use a attribute to save the status

public class PersonTreeitemRenderer implements TreeitemRenderer {
			public void render(Treeitem item, Object data) throws Exception { 
				/* ........... */

				item.setOpen(person.getGroup().isOpen()); 

                                /* ........... */
				
			}
		}

Thiru
13 Mar 2010 07:38:35 GMT
13 Mar 2010 07:38:35 GMT

When I click Add button the follwing method is called toload data

public void add(treeid){

Person person = new Person("NewName", "@zkoss.org","767676");
SimpleTreeNode stn = new SimpleTreeNode(person,new ArrayList());
alc.add(stn);
treeid.setModel(stm);
}

Is it right way of adding new data?
Plz give any suggestions to add data without calling
last line of add() method i.e treeid.setModel(stm);

Thanks
Thiru

jimmyshiau
14 Mar 2010 23:37:57 GMT
14 Mar 2010 23:37:57 GMT

Yes, you have to call tree.setModel for sync model

Thiru
15 Mar 2010 09:43:45 GMT
15 Mar 2010 09:43:45 GMT

Hi,

Am pasting the code on same example with some modifications
i.e setting mold and pagesize attribute to tree component.

Now suppose drag the horizontal scroolbar to far right and click on add button.
The issues are
1.The Horizontal scroll bar will move to leftmost
2.Initiallly the total items are 8,after adding i has to be 9 but page count shows 15.


Please give suggestions...

Thanks in Advance




<zk xmlns="http://www.zkoss.org/2005/zk/native"
xmlns:zul="http://www.zkoss.org/2005/zul"
xmlns:zk="http://www.zkoss.org/2005/zk">
<zul:zscript>
public class Person {
private String _name;
private String _email;
private String _accountId;
private boolean _groupItem = true;
private boolean _open = true;

public Person(String name, String email, String dep) {
super();
_name = name;
_email = email;
_accountId = dep;
}

public String getAccountId() {
return _accountId;
}

public void setAccountId(String account) {
_accountId = account;
}

public String getEmail() {
return _email;
}

public void setEmail(String email) {
_email = email;
}

public String getName() {
return _name;
}

public void setName(String name) {
_name = name;
}

public boolean isGroupItem() {
return _groupItem;
}

public void setGroupItem(boolean groupItem) {
_groupItem = groupItem;
}

public boolean isOpen() {
return _open;
}

public void setOpen(boolean open) {
_open = open;
}

}

import org.zkoss.zul.Treecell;
import org.zkoss.zul.Treeitem;
import org.zkoss.zul.TreeitemRenderer;
import org.zkoss.zul.Treerow;
import org.zkoss.zul.SimpleTreeNode;
public class PersonTreeitemRenderer implements TreeitemRenderer {

public void render(Treeitem item, Object data) throws Exception {
SimpleTreeNode t = (SimpleTreeNode)data;
final Person person = (Person)t.getData();
Treecell tcEmail = new Treecell(person.getEmail());
Treecell tcName = new Treecell(person.getName());
Treecell tcAccountId = new Treecell(person.getAccountId());
Treerow tr = null;
if(item.getTreerow()==null){
tr = new Treerow();
tr.setParent(item);
}else{
tr = item.getTreerow();
tr.getChildren().clear();
}
tcName.setParent(tr);
tcEmail.setParent(tr);
tcAccountId.setParent(tr);
item.setOpen(person.isOpen());

item.addEventListener("onOpen", new EventListener() {
public void onEvent(Event event) throws Exception {
person.setOpen(item.isOpen());
}
});

}
}
String[] name = {"Pierre","Adam","Thomas"};
String[] accountId = {"p001","a002","t003"};
ArrayList alc = new ArrayList();
for(int i =0; i < name.length; i++){
Person person = new Person(name,name + "@zkoss.org",accountId);
person.setGroupItem(false);
SimpleTreeNode stn = new SimpleTreeNode(person,new ArrayList());
alc.add(stn);
}
SimpleTreeNode rdDep = new SimpleTreeNode(new Person("RD","",""),alc);
String[] name2 = {"Paul","Eric","Gray"};
String[] accountId2 = {"p002","e009","g019"};
ArrayList alc2 = new ArrayList();
for(int i =0; i < name.length; i++){
Person person = new Person(name2,name2 + "@zkoss.org",accountId2);
person.setGroupItem(false);
SimpleTreeNode stn = new SimpleTreeNode(person,new ArrayList());
alc2.add(stn);
}
SimpleTreeNode salesDep = new SimpleTreeNode(new Person("Sales","",""),alc2);
ArrayList al = new ArrayList();
al.add(rdDep);
al.add(salesDep);
SimpleTreeNode root = new SimpleTreeNode("ROOT",al);
SimpleTreeModel stm = new SimpleTreeModel(root);
PersonTreeitemRenderer ptr = new PersonTreeitemRenderer();
public void add(treeid){
Person person = new Person("NewName", "@zkoss.org","767676");
SimpleTreeNode stn = new SimpleTreeNode(person,new ArrayList());
alc.add(stn);
treeid.setModel(stm);
}

</zul:zscript>
<zul:tree mold="paging" pageSize="10" checkmark="true" multiple="true" width="300px" treeitemRenderer="${ptr}" model="${stm}" id="tree" >
<zul:treecols>
<zul:treecol width="150px" label="Name" />
<zul:treecol width="120px" label="Email" />
<zul:treecol width="120px" label="AccountId" />
</zul:treecols>
</zul:tree>
<zul:button label="Add" onClick="add(tree)"/>

</zk>

jimmyshiau
15 Mar 2010 23:16:59 GMT
15 Mar 2010 23:16:59 GMT

1.The Horizontal scroll bar will move to leftmost
Because it will rerender after setModel

2.Initiallly the total items are 8,after adding i has to be 9 but page count shows 15.
It works for me in zk-bin-5.0.1-FL-2010-03-09

Thiru
16 Mar 2010 04:07:29 GMT
16 Mar 2010 04:07:29 GMT

Hi Jimmy,

I tried with zk listbox, related to scroll issue.
I drag the scroll bar to right most and click on Description header.The Data is getting sorted and scroll position is retained.
Its working well and not with tree component when using model.
So i guess there should be some solution even for tree component.

The example i tried is given below.
<zk>
<button label="Toggle checkmark" onClick="box.checkmark = !box.checkmark"/>
<button label="Toggle multiple" onClick="box.multiple = !box.multiple"/>
<listbox width="350px" id="box" fixedLayout="true" multiple="true" checkmark="true">
<listhead>
<listheader label="Name" width="150px" sort="auto"/>
<listheader label="Gender" width="150px" sort="auto"/>
<listheader label="Age" width="150px" sort="auto"/>
<listheader label="Description" width="150px" sort="auto"/>
</listhead>
<listitem>
<listcell label="Mary"/>
<listcell label="FEMALE"/>
<listcell label="18"/>
<listcell label="A young lady."/>
</listitem>
<listitem>
<listcell label="John"/>
<listcell label="MALE"/>
<listcell label="20"/>
<listcell label="A college student."/>
</listitem>
<listitem>
<listcell label="Jane"/>
<listcell label="FEMALE"/>
<listcell label="32"/>
<listcell label="A remarkable artist."/>
</listitem>
<listitem>
<listcell label="Henry"/>
<listcell label="MALE"/>
<listcell label="29"/>
<listcell label="A graduate."/>
</listitem>
</listbox>
</zk>


Please help in fixing this issue....

Thanks
Thiru

jimmyshiau
19 Mar 2010 23:36:44 GMT
19 Mar 2010 23:36:44 GMT

OK
I extends simpleTreeModel
and create a add method
is that you want ?

index.zul

<zk>
	<window apply="ctrl.MyComposer">
		<tree id="tree" width="300px" height="500px">
			<treecols>
				<treecol width="150px" label="Name"/>
				<treecol width="120px" label="Email" />
				<treecol width="120px" label="AccountId" />
			</treecols>
		</tree>
		<button id="addBtn" label="add"/>
	</window>
</zk>


MyComposer.java
package ctrl;

import java.util.*;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.*;
import org.zkoss.zul.event.TreeDataEvent;
import org.zkoss.zul.event.TreeDataListener;

public class MyComposer extends GenericForwardComposer{	
	
	private Tree tree;
	private MySimpleTreeModel treeModel;
	private SimpleTreeNode rdDep, salesDep; 
	
	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);		
		
		//create a PersonTreeitemRenderer
		tree.setTreeitemRenderer(new TreeitemRenderer() {			
			@Override
			public void render(Treeitem item, Object data) throws Exception {
				if (data == null) return;
				
				SimpleTreeNode t = (SimpleTreeNode)data;
				final Person person = (Person)t.getData();
				Treerow tr = new Treerow();
				tr.setParent(item);
				tr.appendChild(new Treecell(person.getName()));
				tr.appendChild(new Treecell(person.getEmail()));
				tr.appendChild(new Treecell(person.getAccountId()));
				item.setOpen(person.isOpen()); 

				item.addEventListener("onOpen", new EventListener() { 
					public void onEvent(Event event) throws Exception {
						Treeitem item = (Treeitem) event.getTarget();
						person.setOpen(item.isOpen()); 
					} 
				}); 
			}
		});		
		
		//create treemodel and assign root
		treeModel = new MySimpleTreeModel(createTreeData());
		tree.setModel(treeModel);		
	}
	
	public void onClick$addBtn(){
		Person person = new Person("NewName", "@zkoss.org","767676"); 
		SimpleTreeNode stn = new SimpleTreeNode(person, new ArrayList<SimpleTreeNode>());		
		treeModel.add(rdDep, stn);
	}	
	
	private SimpleTreeNode createTreeData() {
		//Create nodes for department R and D
		String[] name = {"Pierre","Adam","Thomas"};
		String[] accountId = {"p001","a002","t003"};		
		//Create branch department R and D and assigned children to it. rdDep's children are contained in ArrayList alc.
		rdDep = new SimpleTreeNode(new Person("R&D","",""), createTreeChildren(name, accountId));
		
		//Create nodes for department sales
		String[] name2 = {"Paul","Eric","Gray"};
		String[] accountId2 = {"p002","e009","g019"};		
		//Create branch department sales and assigned children to it
		salesDep = new SimpleTreeNode(new Person("Sales","",""), createTreeChildren(name2, accountId2));
		
		//create root and assigned children to it 
		ArrayList<SimpleTreeNode> al = new ArrayList<SimpleTreeNode>();
		al.add(salesDep);
		al.add(rdDep);		
		return new SimpleTreeNode("ROOT",al);
	}

	private List<SimpleTreeNode> createTreeChildren(String[] name, String[] accountId) {
		ArrayList<SimpleTreeNode> alc = new ArrayList<SimpleTreeNode>();
		for(int i =0; i < name.length; i++){
			Person person = new Person(name<i >,name<i > + "@zkoss.org",accountId<i >);
			SimpleTreeNode stn = new SimpleTreeNode(person,new ArrayList<SimpleTreeNode>());
			alc.add(stn);
		}
		return alc;
	}

	private class MySimpleTreeModel extends SimpleTreeModel{
		
		public MySimpleTreeModel(SimpleTreeNode root) {
			super(root);
		}

		public void add(SimpleTreeNode parent, SimpleTreeNode newNodes){
			
			List<SimpleTreeNode> children = parent.getChildren();
			int length = children.size();
			children.add(newNodes);
			fireEvent(parent, length, length, TreeDataEvent.INTERVAL_ADDED);
		}
	}
	
	private class Person {
		
		private String _name;			
		private String _email;			
		private String _accountId;
		private boolean _open;
		
		public Person(String name, String email, String dep) {
			super();
			_name = name;
			_email = email;
			_accountId = dep;
		}
	
		public String getAccountId() {
			return _accountId;
		}
	
		public String getEmail() {
			return _email;
		}	
	
		public String getName() {
			return _name;
		}
		
		public boolean isOpen() { 
			return _open; 
		} 

		public void setOpen(boolean open) { 
			_open = open; 
		}
	}

}

magaby
15 Apr 2010 16:35:04 GMT
15 Apr 2010 16:35:04 GMT

a question??? I did a tree with values that can be modified .. since I cross this tree for the updates in a bd

jimmyshiau
15 Apr 2010 19:42:13 GMT
15 Apr 2010 19:42:13 GMT

Hi magaby
You can update DB when you save the tree value

liubobo
14 Jul 2010 03:32:04 GMT
14 Jul 2010 03:32:04 GMT

If I don`t have DB,how do I do? Now I do a project, it has a tree,but we don`t create table for it. Can you help me? Thank you very much!

jimmyshiau
14 Jul 2010 10:53:59 GMT
14 Jul 2010 10:53:59 GMT

Hi liubobo
You can store the status in the session or cookie