0

Dynamic grid creation

asked 2010-02-09 08:33:38 +0800

maurix gravatar image maurix
9 1 1 1

I'm usign ZK 5.0 and i want to build a grid with dynamic columns and dynamic data. I have a pojo called Page, this has a List<PageRow> fmember and every PageRow has a List<PageField> fields member. I have a zul page with a grid and in his controller class i set the model in this way:
Page page = mycode...return...

ListModelList model = new ListModelList(page.getPageRows());
mygrid.setModel(model);

in zul page i have:
<grid id="mygrid">

<rows>
<row self="@{each=item}" value="@{item}">
<custom-attributes campi="@{item.fields}" composite="list"/>
<label value="@{each}" forEach="@{campi}" ></label>
</row>
</rows>

But i have a resulting grid with all the rows but only a column with no value inside. Where i'm wrong?
It's possible draw this grid with zul page mixin with java code in controller, or i must create the grid programmatically only in java code??

delete flag offensive retag edit

35 Replies

Sort by ยป oldest newest

answered 2011-04-25 11:29:54 +0800

jimmyshiau gravatar image jimmyshiau
4921 5
http://www.zkoss.org/ ZK Team

updated 2011-04-25 11:38:58 +0800

Hi EznatiZK,
I have created a sample

zul

<zk>
	<window apply="MyComposer">
		<grid rowRenderer="${renderer}" model="${model}">
			<columns>
				<column label="Article"/>
				<column label="SubArticle"/>
				<column label="SubSubArtiicle"/>
			</columns>
			<rows />
		</grid>
	</window>
</zk>

MyComposer.java

import java.util.*;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.*;

public class MyComposer extends GenericForwardComposer {
	public void doBeforeComposeChildren(Component comp) throws Exception {
		super.doBeforeComposeChildren(comp);
		
		comp.setAttribute("model", createModel());
		comp.setAttribute("renderer", new MyRowRenderer());
	}

	
	private ListModel createModel() {
		List data = new ArrayList();
		
		List articleList = MyDAO.getArticle();
		for (int i = 0, j = articleList.size(); i < j; i++) {
			String article = (String) articleList.get(i);
			List subArticleList =  MyDAO.getSubArticle(article);
			
			for (int k = 0, l = subArticleList.size(); k < l; k++) {
				String subArticle = (String) subArticleList.get(k);
				List subSubArticleList =  MyDAO.getSubSubArticle(subArticle);
				
				for (int m = 0, n = subSubArticleList.size(); m < n; m++) {
					String subSubArticle = (String) subSubArticleList.get(m);
					data.add(new String[]{article, subArticle, subSubArticle});
				}
			}
		}
		return new ListModelList(data);
	}


	public static class MyDAO {
		public static List getArticle() {
			List list = new ArrayList();
			for (int i = 0; i < 5; i++)
				list.add("Article " + i);
			return list;
		}
		public static List getSubArticle(String article) {
			List list = new ArrayList();
			for (int i = 0; i < 5; i++)
				list.add(article + i);
			return list;
		}
		public static List getSubSubArticle(String SubArticle) {
			List list = new ArrayList();
			for (int i = 0; i < 5; i++)
				list.add(SubArticle + i);
			return list;
		}
		
		public static int getTotalArticleCount(String article) {
			List subArticleList =  getSubArticle(article);
			int rowSpan = 0;
			for (int i = 0, j = subArticleList.size(); i < j; i++) {
				String subArticle = (String) subArticleList.get(i);
				rowSpan += getSubSubArticle(subArticle).size();
			}
			return rowSpan;
		}
	}
	
	public static class MyRowRenderer implements RowRendererExt, RowRenderer {
		private int index = 0;
		private String template = "./myRow.zul";
		private String prevArticle = "", prevSubArticle="";
		private String[] curData;
		
		public Row newRow(Grid grid) {
			
			curData = getData(grid.getModel());
			boolean isNextArticle = !prevArticle.equals(curData[0]);
			boolean isNextSubArticle = !prevSubArticle.equals(curData[1]);
			
			Map arg = new HashMap();
			
			// first row of each SubArticle
			if (isNextSubArticle) {
				
				// first row of each article
				if (isNextArticle) {
					prevArticle = curData[0];
					arg.put("field1", prevArticle);
					arg.put("rowspan1", MyDAO.getTotalArticleCount(prevArticle));
					System.out.println(prevArticle);
				}
				
				prevSubArticle = curData[1];
				arg.put("field2", prevSubArticle);
				arg.put("rowspan2", MyDAO.getSubSubArticle(prevSubArticle).size());
			}
			return (Row) Executions.createComponents(template, null, arg);
		}
		private String[] getData(ListModel model) {
			if (model != null)
				return (String[]) model.getElementAt(index++);
			return null;
		}
		public Component newCell(Row row) {
			return new Label(curData[2].toString());
		}
		public int getControls() {
			return 0;
		}
		public void render(Row row, Object data) throws Exception {
		}
	}
}




myRow.zul

<zk>
	<row>
		<cell rowspan="${arg.rowspan1}" unless="${empty arg.field1}">
			<label value="${arg.field1}"/>
		</cell>
		<cell rowspan="${arg.rowspan2}" unless="${empty arg.field2}">
			<label value="${arg.field2}"/>
		</cell>
	</row>
</zk>

link publish delete flag offensive edit

answered 2011-04-26 05:25:02 +0800

EznatiZK gravatar image EznatiZK
60

Hi as1225...
First of all...thank you veryyyy much for helping me! i really appreaciate it!
i will test it right the way!
by i have a simple question!
why did you separate the grid zul file and the myRow.zul?
couldn't we mix it ?

link publish delete flag offensive edit

answered 2011-04-26 05:38:07 +0800

EznatiZK gravatar image EznatiZK
60

when executing i have this Error :
org.zkoss.zk.ui.UiException: Only one rows child is allowed: <Grid tQ2Q1>
Note: rows is created automatically if live data
org.zkoss.zul.Grid.beforeChildAdded(Grid.java:1187)
org.zkoss.zk.ui.AbstractComponent.insertBefore(AbstractComponent.java:1082)
org.zkoss.zul.Grid.insertBefore(Grid.java:1212)
org.zkoss.zk.ui.AbstractComponent.setParent(AbstractComponent.java:992)
org.zkoss.zk.ui.impl.AbstractUiFactory.newComponent(AbstractUiFactory.java:91)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:714)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:685
.....
....
..
.

link publish delete flag offensive edit

answered 2011-04-26 06:48:37 +0800

jimmyshiau gravatar image jimmyshiau
4921 5
http://www.zkoss.org/ ZK Team

Yes, at first, I just want to use a template zul,
You can do that without template,
here is new sample

<zk>
	<zscript><![CDATA[
		import java.util.*;
		
		import org.zkoss.zk.ui.Component;
		import org.zkoss.zk.ui.Executions;
		import org.zkoss.zk.ui.util.GenericForwardComposer;
		import org.zkoss.zul.*;
		
		public class MyComposer extends GenericForwardComposer {
			public void doBeforeComposeChildren(Component comp) throws Exception {
				super.doBeforeComposeChildren(comp);
				
				comp.setAttribute("model", createModel());
				comp.setAttribute("renderer", new MyRowRenderer());
			}
		
			
			private ListModel createModel() {
				List data = new ArrayList();
				
				List articleList = MyDAO.getArticle();
				for (int i = 0, j = articleList.size(); i < j; i++) {
					String article = (String) articleList.get(i);
					List subArticleList =  MyDAO.getSubArticle(article);
					
					for (int k = 0, l = subArticleList.size(); k < l; k++) {
						String subArticle = (String) subArticleList.get(k);
						List subSubArticleList =  MyDAO.getSubSubArticle(subArticle);
						
						for (int m = 0, n = subSubArticleList.size(); m < n; m++) {
							String subSubArticle = (String) subSubArticleList.get(m);
							data.add(new String[]{article, subArticle, subSubArticle});
						}
					}
				}
				return new ListModelList(data);
			}
		
		
			public static class MyDAO {
				public static List getArticle() {
					List list = new ArrayList();
					for (int i = 0; i < 5; i++)
						list.add("Article " + i);
					return list;
				}
				public static List getSubArticle(String article) {
					List list = new ArrayList();
					for (int i = 0; i < 5; i++)
						list.add(article + i);
					return list;
				}
				public static List getSubSubArticle(String SubArticle) {
					List list = new ArrayList();
					for (int i = 0; i < 5; i++)
						list.add(SubArticle + i);
					return list;
				}
				
				public static int getTotalArticleCount(String article) {
					List subArticleList =  getSubArticle(article);
					int rowSpan = 0;
					for (int i = 0, j = subArticleList.size(); i < j; i++) {
						String subArticle = (String) subArticleList.get(i);
						rowSpan += getSubSubArticle(subArticle).size();
					}
					return rowSpan;
				}
			}
			
			public static class MyRowRenderer implements RowRendererExt, RowRenderer {
				private int index = 0;
				private String prevArticle = "", prevSubArticle="";
				private String[] curData;
				
				public Row newRow(Grid grid) {
					Row row = new Row();
					curData = getData(grid.getModel());
					boolean isNextArticle = !prevArticle.equals(curData[0]);
					boolean isNextSubArticle = !prevSubArticle.equals(curData[1]);
					
					Map arg = new HashMap();
					
					// first row of each SubArticle
					if (isNextSubArticle) {
						
						// first row of each article
						if (isNextArticle) {
							Cell cell = new Cell();
							prevArticle = curData[0];
							cell.setRowspan(MyDAO.getTotalArticleCount(prevArticle));
							cell.appendChild(new Label(prevArticle));
							row.appendChild(cell);
						}
						
						prevSubArticle = curData[1];
						Cell cell = new Cell();
						cell.setRowspan(MyDAO.getSubSubArticle(prevSubArticle).size());
						cell.appendChild(new Label(prevSubArticle));
						row.appendChild(cell);
					}
					return row;
				}
				private String[] getData(ListModel model) {
					if (model != null)
						return (String[]) model.getElementAt(index++);
					return null;
				}
				public Component newCell(Row row) {
					return new Label(curData[2].toString());
				}
				public int getControls() {
					return 0;
				}
				public void render(Row row, Object data) throws Exception {
				}
			}
		}
	]]></zscript>
	<window apply="MyComposer">
		<grid rowRenderer="${renderer}" model="${model}">
			<columns>
				<column label="Article"/>
				<column label="SubArticle"/>
				<column label="SubSubArtiicle"/>
			</columns>
			<rows />
		</grid>
	</window>
</zk>

I have tested with ZK 5.0.6
what version of ZK are you use?

link publish delete flag offensive edit

answered 2011-04-26 07:04:24 +0800

EznatiZK gravatar image EznatiZK
60

Am using 5.0.5

link publish delete flag offensive edit

answered 2011-04-26 07:05:52 +0800

EznatiZK gravatar image EznatiZK
60

same ERROR:
org.zkoss.zk.ui.UiException: Only one rows child is allowed: <Grid l2HQ1>
Note: rows is created automatically if live data
org.zkoss.zul.Grid.beforeChildAdded(Grid.java:1187)
org.zkoss.zk.ui.AbstractComponent.insertBefore(AbstractComponent.java:1082)
org.zkoss.zul.Grid.insertBefore(Grid.java:1212)
org.zkoss.zk.ui.AbstractComponent.setParent(AbstractComponent.java:992)
org.zkoss.zk.ui.impl.AbstractUiFactory.newComponent(AbstractUiFactory.java:91)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:714)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:685)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:629)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:596)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:730)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:685)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:629)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:596)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:730)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:685)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:629)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:661)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:629)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:596)
org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage0(UiEngineImpl.java:382)
org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage(UiEngineImpl.java:305)
org.zkoss.zk.ui.http.DHtmlLayoutServlet.process(DHtmlLayoutServlet.java:225)
org.zkoss.zk.ui.http.DHtmlLayoutServlet.doGet(DHtmlLayoutServlet.java:146)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

link publish delete flag offensive edit

answered 2011-04-26 08:01:15 +0800

jimmyshiau gravatar image jimmyshiau
4921 5
http://www.zkoss.org/ ZK Team

updated 2011-04-26 08:01:34 +0800

You can try to remove the rows in grid

link publish delete flag offensive edit

answered 2011-04-26 13:01:52 +0800

EznatiZK gravatar image EznatiZK
60

I removed the row in the ZUL grid and it worked...
One more Question!
can I add a Filter Functionnality ? (a search area where i type a word an the grid or an other List appears showing the SubSubArticles that match the word entred in the search field) and modify them?
because i don't see that those elements have any "id" that i can work with .

link publish delete flag offensive edit

answered 2011-04-26 16:46:17 +0800

EznatiZK gravatar image EznatiZK
60

It's me again!
i tried to usyour example with my real data... here is the code that I cannot understand : parag= Paragraphe=SubArticle...... Ligne=SubsubArticle
i tried to work with objects rather than String ! but i have a problem:

private ListModel createModel() {
List data = new ArrayList();

List articleList = articleDAO.getListAllArticles(); // returns a list of Article objects !!
for (int i = 0, j = articleList.size(); i < j; i++) {
//String article =((Article) articleList.get(i)).getNomArticle();// getNomArticle= getNameArticle();
Article article = (Article) articleList.get(i);
List ParagList = paragDAO.getListParagByArticleO(article); //returns List of Objects

for (int k = 0, l = ParagList.size(); k < l; k++) {
//String parag = ((Paragraphe) ParagList.get(k)).getNomParag();
Paragraphe parag = (Paragraphe) ParagList.get(k);
List LigneList = ligneDAO.getListLignesByParag(parag); //returns also Liste of objects

for (int m = 0, n = LigneList.size(); m < n; m++) {
//String ligne = ((Ligne) LigneList.get(m)).getNomLigne();
Ligne ligne = (Ligne) LigneList.get(m);
data.add(new String[]{article, parag, ligne});//############## HEEEEEERRRREEEEE########
}
}
}
return new ListModelList(data);
}


Bold TextHow could I use data.add() with Objects ???

link publish delete flag offensive edit

answered 2011-04-26 19:58:11 +0800

jimmyshiau gravatar image jimmyshiau
4921 5
http://www.zkoss.org/ ZK Team

You can add a object to the list,
and retrieve the object by grid.getModel().getElementAt(index),
you can render the row by object.

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2010-02-09 08:33:38 +0800

Seen: 10,691 times

Last updated: Nov 15 '12

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More