-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hi,
I guess that zk has a bug on gruping component when it is paginated:
When I enter on screen, the groups are closed by default. On follow image, see the pagination data in right bottom:
Closed group
Now, we open the group: It seems ok:
Opened
When group is closed, the value of paging decreases!
Closed again
What do you think about this?
tks
Gerson.
I can't reproduce your problem.
Can you provide your sample code?
The pagingation calculated the visible items.
Therefore, when a group is not open, its rows can't be visible, and not be counted.
In your screenshot, I found tti006 group disappear after open and close. Could it be the reason cause the couting error?
Sincerely,
Peter
<grid id="placesGrid" mold="paging" pageSize="10" height="450px"> <columns> <column label="${c:l('LB_PLACE')}" valign="middle" hflex="5" align="left" /> <column label="${c:l('LB_PLACE_WEEK')}" valign="middle" hflex="2" align="center" /> <column label="${c:l('LB_PLACE_SATURDAY')}" valign="middle" hflex="2" align="center" /> <column label="${c:l('LB_PLACE_SUNDAY')}" valign="middle" hflex="2" align="center" /> <column label="" width="100px" align="center"> <button sclass="buttonAdd" id="doAdd" /> <button sclass="buttonSearch" id="doSearch" /> </column> </columns> </grid>
private RowRenderer placeRowRenderer = new RowRenderer() { @Override public void render(Row placeGroupListRow, Object data) { PlaceGroupList placeGroupListData = (PlaceGroupList) data; if (placeGroupListRow instanceof Group) { placeGroupListRow.appendChild(new Label(placeGroupListData.getTxPlace())); ((Group) placeGroupListRow).setOpen(false); } else { Label lTxPeriod = new Label(placeGroupListData.getTxPeriod()); lTxPeriod.setStyle("padding-left:15px"); placeGroupListRow.appendChild(lTxPeriod); placeGroupListRow.appendChild(new Label(placeGroupListData.getTxWeek())); placeGroupListRow.appendChild(new Label(placeGroupListData.getTxSat())); placeGroupListRow.appendChild(new Label(placeGroupListData.getTxSun())); placeGroupListRow.addEventListener(Events.ON_CLICK, doActionView(placeGroupListData)); placeGroupListRow.setStyle("cursor: pointer"); Hlayout hlButtons = new Hlayout(); Button btEdit = new Button(); Button btDel = new Button(); btEdit.setSclass("buttonUpdate"); btDel.setSclass("buttonDel"); btEdit.setAttribute("id", "editButtonList"); btEdit.addEventListener("onClick",doActionEditar(placeGroupListData)); btDel.setAttribute("id", "deleteButtonList"); btDel.addEventListener("onClick",doActionDeletar(placeGroupListData)); hlButtons.appendChild(btEdit); hlButtons.appendChild(btDel); hlButtons.setParent(placeGroupListRow); } } };
@gersonlc
I use following code try to mimic your scenario, and still can't reproduce the problem.
Can you provide reproducible sample code? For example , PlaceGroupList is missing?
I'm still wondering the bug is from somewhere else.
<zk>
<grid width="500px" mold="paging" pageSize="10" height="450px">
<columns>
<column label="Type" />
</columns>
<rows>
<group open="false">
<label value="Group 1" />
</group>
<row>
<label value="r1" />
</row>
<row >
<label value="r2" />
</row>
<row >
<label value="r3" />
</row>
<row >
<label value="r4" />
</row>
<row >
<label value="r5" />
</row>
<row >
<label value="r6" />
</row>
<row >
<label value="r7" />
</row>
<row >
<label value="r8" />
</row>
<group label="Group 2" open="false" />
<row>
<label value="r1" />
</row>
<row >
<label value="r2" />
</row>
<row >
<label value="r3" />
</row>
<row >
<label value="r4" />
</row>
<row >
<label value="r5" />
</row>
<row >
<label value="r6" />
</row>
<row >
<label value="r7" />
</row>
<row >
<label value="r8" />
</row>
<group label="Group 3" open="false" />
<row>
<label value="r1" />
</row>
<row >
<label value="r2" />
</row>
<row >
<label value="r3" />
</row>
<row >
<label value="r4" />
</row>
<row >
<label value="r5" />
</row>
<row >
<label value="r6" />
</row>
<row >
<label value="r7" />
</row>
<row >
<label value="r8" />
</row>
</rows>
</grid>
</zk>
Ok Peter... here we go:
PlaceGroupList is a simple pojo class:
/** * Classe Wrapper da lista agrupada de Place * @author gerson * */ public class PlaceGroupList { Long idPlace; String txPlace; String txPeriod; String txWeek; String txSat; String txSun; public PlaceGroupList(String txPlace, String txPeriod, String txWeek, String txSat, String txSun) { this.txPlace = txPlace; this.txPeriod = txPeriod; this.txWeek = txWeek; this.txSat = txSat; this.txSun = txSun; } public PlaceGroupList(Long idPlace, String txPlace, String txPeriod, String txWeek, String txSat, String txSun) { this.idPlace = idPlace; this.txPlace = txPlace; this.txPeriod = txPeriod; this.txWeek = txWeek; this.txSat = txSat; this.txSun = txSun; } public Long getIdPlace() { return idPlace; } public void setIdPlace(Long idPlace) { this.idPlace = idPlace; } public String getTxPlace() { return txPlace; } public String getTxPeriod() { return txPeriod; } public String getTxWeek() { return txWeek; } public String getTxSat() { return txSat; } public String getTxSun() { return txSun; } @Override public String toString() { return "PlaceGroupList [idPlace="+idPlace+", txPlace=" + txPlace + ", txPeriod=" + txPeriod + ", txWeek=" + txWeek + ", txSat=" + txSat + ", txSun=" + txSun + "]"; }
Full composer (imports omitted):
public class PlaceListComposer extends GenericForwardComposer { private static final long serialVersionUID = 6056292390297152745L; static Logger logger = Logger.getLogger(PlaceListComposer.class); @Autowired private PlaceService placeService; @Autowired private SecContextService secContextService; private Grid placesGrid; private PlaceFilter placeFilter; private Window placeListWindow; @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); UserInfo userInfo = (UserInfo) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); doPopulateGrid(); } public void doPopulateGrid() { UserInfo userInfo = (UserInfo) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); SecContext secContext = secContextService.consultar(userInfo.getContext().getIdContext()); placeFilter = new PlaceFilter(secContext); placeFilter.setSecStatus(secContext.getSecStatus()); List<PlaceGroupList> placeGroupList = null; try { placeGroupList = placeService.search(placeFilter); execution.setAttribute("placeGroupList", placeGroupList); } catch (Exception e) { logger.error("Erro..:" + e.getMessage() + " Local do erro..: "+ e.getStackTrace()); } GroupsModelArray groupModelArray = new GroupsModelArray(placeGroupList, new PlaceComparator()); placesGrid.setRowRenderer(placeRowRenderer); placesGrid.setModel(groupModelArray); } private RowRenderer placeRowRenderer = new RowRenderer() { @Override public void render(Row placeGroupListRow, Object data) { PlaceGroupList placeGroupListData = (PlaceGroupList) data; if (placeGroupListRow instanceof Group) { placeGroupListRow.appendChild(new Label(placeGroupListData.getTxPlace())); ((Group) placeGroupListRow).setOpen(false); } else { Label lTxPeriod = new Label(placeGroupListData.getTxPeriod()); lTxPeriod.setStyle("padding-left:15px"); placeGroupListRow.appendChild(lTxPeriod); placeGroupListRow.appendChild(new Label(placeGroupListData.getTxWeek())); placeGroupListRow.appendChild(new Label(placeGroupListData.getTxSat())); placeGroupListRow.appendChild(new Label(placeGroupListData.getTxSun())); placeGroupListRow.addEventListener(Events.ON_CLICK, doActionView(placeGroupListData)); placeGroupListRow.setStyle("cursor: pointer"); Hlayout hlButtons = new Hlayout(); Button btEdit = new Button(); Button btDel = new Button(); btEdit.setSclass("buttonUpdate"); btDel.setSclass("buttonDel"); btEdit.setAttribute("id", "editButtonList"); btEdit.addEventListener("onClick",doActionEditar(placeGroupListData)); btDel.setAttribute("id", "deleteButtonList"); btDel.addEventListener("onClick",doActionDeletar(placeGroupListData)); hlButtons.appendChild(btEdit); hlButtons.appendChild(btDel); hlButtons.setParent(placeGroupListRow); } } }; /** * Evento disparado ao clicar no botão Editar * @param attendantCallTypeListData * @return EventListener */ private EventListener doActionEditar(final PlaceGroupList placeGroupList){ return new EventListener() { @Override public void onEvent(Event event) throws Exception { Place placeEdit = PlaceListComposer.this.placeService.consultar(placeGroupList.getIdPlace()); execution.setAttribute("placeEdit", placeEdit); Window winPlaceConsult = (Window) Executions.createComponents("place.zul", null, null); winPlaceConsult.doModal(); } }; } /** * Evento disparado ao clicar no botão Delete * @param placeGroupList * @return EventListener */ private EventListener doActionDeletar(final PlaceGroupList placeGroupList){ return new EventListener() { @Override public void onEvent(Event event) throws Exception { Messagebox.show(Labels.getLabel("MSG_DEFAULT_DELETE_REGISTER"), "", Messagebox.YES | Messagebox.NO, Messagebox.QUESTION, excluirPlace(placeGroupList)); } }; } /** * Evento que exclui um PlaceGroupList * @param placeGroupList * @return EventListener */ private EventListener excluirPlace(final PlaceGroupList placeGroupList){ return new EventListener() { @Override public void onEvent(Event event) throws Exception { if (((Integer) event.getData()).intValue() == Messagebox.YES) { if(placeGroupList != null){ try{ Place placeDel = PlaceListComposer.this.placeService.consultar(placeGroupList.getIdPlace()); PlaceListComposer.this.placeService.excluir(placeDel); doPopulateGrid(); }catch (Exception e) { try { Messagebox.show(Labels.getLabel("MSG_DEFAULT_CAN_NOT_DELETE_DEPENDENCY") , "Mensagem", Messagebox.OK, Messagebox.EXCLAMATION); } catch (Exception ex) { logger.error("Erro..:" + ex.getMessage() + " Local do erro..: "+ ex.getStackTrace()); } } } } } }; } private EventListener doActionView(final PlaceGroupList placeGroupList){ return new EventListener() { @Override public void onEvent(Event event) throws Exception { Place placeView= PlaceListComposer.this.placeService.consultar(placeGroupList.getIdPlace()); execution.setAttribute("placeView", placeView); Window winPlaceConsult = (Window) Executions.createComponents("placeConsult.zul", null, null); winPlaceConsult.doModal(); } }; } public void onClick$doAdd() throws SuspendNotAllowedException, InterruptedException{ Window secPersonAddWindow = (Window) Executions.createComponents("place.zul", null, null); secPersonAddWindow.doModal(); } public void onClick$doSearch() throws SuspendNotAllowedException, InterruptedException{ Window secPersonSearchWindow = (Window) Executions.createComponents("placeSearch.zul", null, null); secPersonSearchWindow.doModal(); } }
PlaceComparator.java
public class PlaceComparator implements Comparator<PlaceGroupList>, Serializable { /** * */ private static final long serialVersionUID = 1220955601531023272L; @Override public int compare(PlaceGroupList pgl1, PlaceGroupList pgl2) { return pgl1.getTxPlace().compareTo(pgl2.getTxPlace()); } }
full zul file:
<?init class="org.zkoss.zk.ui.util.Composition" arg0="/WEB-INF/layout/template.zul"?> <?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c" ?> <zk> <window id="placeListWindow" apply="com.tti.servicebot3.zk.composer.PlaceListComposer" self="@{define(content)}" closable="true" forward="onCancelWinUserList=onCancelWindow()"> <style src="../css/geral.css" /> <label id="lblLabelPlaceSearch" style="color:red;font-style:italic;"/> <grid id="placesGrid" mold="paging" pageSize="10" height="450px"> <columns> <column label="${c:l('LB_PLACE')}" valign="middle" hflex="5" align="left" /> <column label="${c:l('LB_PLACE_WEEK')}" valign="middle" hflex="2" align="center" /> <column label="${c:l('LB_PLACE_SATURDAY')}" valign="middle" hflex="2" align="center" /> <column label="${c:l('LB_PLACE_SUNDAY')}" valign="middle" hflex="2" align="center" /> <column label="" width="100px" align="center"> <button sclass="buttonAdd" id="doAdd" /> <button sclass="buttonSearch" id="doSearch" /> </column> </columns> </grid> </window> </zk>
template.zul:
<?page title="" contentType="text/html;charset=UTF-8"?> <?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c" ?> <zk> <!-- *************************** --> <script type="text/javascript" src="/js/jquery-ui-1.8.6.custom.min.js"></script> <script type="text/javascript" src="/js/maskedinput-1.2.2.min.js"></script> <script type="text/javascript" src="/js/masks.js"></script> <zscript> void callScreen(String screeName) { final Window win = (Window) Executions.createComponents(screeName, null, null); win.setMaximizable(false); win.setClosable(true); try { win.doModal(); } catch (InterruptedException ex) { win.onClose(); ex.printStackTrace(); } } void exit() { Executions.sendRedirect("/j_spring_security_logout"); //Clients.evalJavaScript("window.close()"); } </zscript> <!-- *************************** --> <style src="/css/geral.css" /> <!-- *************************** --> <window id="winTemplate" border="none" height="100%" width="100%" > <borderlayout style="padding:0px;"> <north border="none" collapsible="true" title="Tree Tools Informática Ltda."> <vlayout> <grid id="gridTopo" style="border:none"> <columns> <column align="left" /> <column align="center" /> <column align="right" /> </columns> <rows > <row style="border:none"> <image src="/images/logo_TTI.png" /> <label style="font-size: large;" value="Service BOT-3" /> <image src="/images/logoServiceBot3.png" /> </row> </rows> </grid> <separator bar="true" height="2px"/> <grid width="100%" style="border:none"> <columns height="30px"> <column /> <column align="right"/> </columns> <rows> <row> <hbox apply="com.tti.servicebot3.zk.composer.InfoBarComposer" id="hboxInfoBar"></hbox> <hbox align="end"> <bandbox> <bandpopup id="bd"> <vbox> <hbox> Search <textbox /> </hbox> <listbox width="200px"> <listhead> <listheader label="Name" /> <listheader label="Description" /> </listhead> <listitem> <listcell label="John" /> <listcell label="CEO" /> </listitem> <listitem> <listcell label="Joe" /> <listcell label="Engineer" /> </listitem> <listitem> <listcell label="Mary" /> <listcell label="Supervisor" /> </listitem> </listbox> </vbox> </bandpopup> </bandbox> <button id="menuLogout" label="Sair" image="/images/exit.png" onClick="exit()" /> <button label="Help" image="/images/help_icon.gif" /> </hbox> </row> </rows> </grid> <borderlayout height="30px"> <west width="100%" id="mainMenuBar" > <menubar apply="com.tti.servicebot3.zk.composer.MenuComposer"/> </west> </borderlayout> </vlayout> </north> <center> <div self="@{insert(content)}"></div> </center> <south border="none" splittable="true" collapsible="true" open="false"> <vlayout> <grid> <columns> <column hflex="1" /> <column hflex="1" /> <column hflex="1" /> <column hflex="7" /> </columns> <rows> <row> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar">99/99/99 99:99</label> </a> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar">9999999999</label> </a> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar">9999999999</label> </a> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar"> Nonononononononononononononononononon ononononono nononononononon onononononononononon ononononononon ononononononno. </label> </a> </row> <row> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar">99/99/99 99:99</label> </a> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar"> 9999999999 </label> </a> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar"> 9999999999 </label> </a> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar"> Nonononononononononononononononononon ononononono nononononononon onononononononononon ononononononon ononononononno. </label> </a> </row> <row> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar"> 99/99/99 99:99 </label> </a> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar"> 9999999999 </label> </a> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar"> 9999999999 </label> </a> <a onClick='callScreen("relatorConsultar.zul");'> <label sclass="fontWarningBar"> Nonononononononononononononononononon ononononono nononononononon onononononononononon ononononononon ononononononno. </label> </a> </row> </rows> </grid> </vlayout> </south> </borderlayout> </window> </zk>
that's it... i think.
It's still too hard for me to reproduce your scenario.
I don't have SecurityContextHolder,
Can't your reduce the sample code to most simple?
It seems like not problem of group and open.
I'm wondering it's some bug about the model.
Ok Peter, I have simplified and the problem persist:
placeListTest.zul
<zk> <window title="Place" border="normal" id="placeListWindow" apply="com.tti.servicebot3.zk.composer.PlaceListTestComposer"> <style src="../css/geral.css" /> <label id="lblLabelPlaceSearch" style="color:red;font-style:italic;"/> <grid id="placesGrid" mold="paging" pageSize="10" height="450px"> <columns> <column label="Place" valign="middle" hflex="5" align="left" /> <column label="Week" valign="middle" hflex="2" align="center" /> <column label="Saturday" valign="middle" hflex="2" align="center" /> <column label="Sunday" valign="middle" hflex="2" align="center" /> </columns> </grid> </window> </zk>
PlaceListTestComposer:
package com.tti.servicebot3.zk.composer; import java.util.ArrayList; import java.util.List; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.util.GenericForwardComposer; import org.zkoss.zul.Grid; import org.zkoss.zul.Group; import org.zkoss.zul.GroupsModelArray; import org.zkoss.zul.Label; import org.zkoss.zul.Row; import org.zkoss.zul.RowRenderer; import com.tti.servicebot3.samples.PlaceComparator; import com.tti.servicebot3.samples.PlaceGroupList; /** * PlaceListTestComposer. * * @author Gerson * @updated * @since 22/07/2011 * @version 1.0 * */ public class PlaceListTestComposer extends GenericForwardComposer { private Grid placesGrid; @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); grid(); } public void grid() { List<PlaceGroupList> placeGroupList = null; placeGroupList = getPlaceGroupList(); GroupsModelArray groupModelArray = new GroupsModelArray(placeGroupList, new PlaceComparator()); placesGrid.setRowRenderer(placeRowRenderer); placesGrid.setModel(groupModelArray); } private List<PlaceGroupList> getPlaceGroupList() { List<PlaceGroupList> list = new ArrayList<PlaceGroupList>(24); list.add(new PlaceGroupList("Place1", "T1", "08:00 - 12:00", "09:00 - 13:00", " - ")); list.add(new PlaceGroupList("Place1", "T2", "13:00 - 18:00", " - ", " - ")); list.add(new PlaceGroupList("Place1", "T3", " - ", " - ", " 19:15 - 23:00 ")); list.add(new PlaceGroupList("Place2", "T1", " - ", "12:00 - 20:00", " - ")); list.add(new PlaceGroupList("Place2", "T2", " - ", " - ", " - ")); list.add(new PlaceGroupList("Place2", "T3", " - ", " - ", " - ")); list.add(new PlaceGroupList("Place3", "T1", " - ", " - ", "08:30 - 12:30")); list.add(new PlaceGroupList("Place3", "T2", " - ", " - ", "13:30 - 19:00")); list.add(new PlaceGroupList("Place3", "T3", " - ", " - ", " - ")); list.add(new PlaceGroupList("Place4", "T1", "07:20 - 14:00", " - ", " - ")); list.add(new PlaceGroupList("Place4", "T2", "16:00 - 22:00", " - ", " - ")); list.add(new PlaceGroupList("Place4", "T3", " - ", " - ", " - ")); list.add(new PlaceGroupList("Place5", "T1", "05:15 - 11:00", "05:15 - 11:00", "05:15 - 11:00")); list.add(new PlaceGroupList("Place5", "T2", " - ", " - ", " - ")); list.add(new PlaceGroupList("Place5", "T3", " - ", " - ", " - ")); list.add(new PlaceGroupList("Place6", "T1", " - ", " - ", " - ")); list.add(new PlaceGroupList("Place6", "T2", " - ", "14:00 - 20:00", " - ")); list.add(new PlaceGroupList("Place6", "T3", " - ", " - ", " - ")); list.add(new PlaceGroupList("Place7", "T1", " - ", " - ", " - ")); list.add(new PlaceGroupList("Place7", "T2", " - ", " - ", " - ")); list.add(new PlaceGroupList("Place7", "T3", "19:00 - 23:45", " - ", " - ")); list.add(new PlaceGroupList("Place8", "T1", " - ", " - ", " - ")); list.add(new PlaceGroupList("Place8", "T2", " - ", "13:45 - 19:45", "20:45 - 23:50")); list.add(new PlaceGroupList("Place8", "T3", " - ", " - ", " - ")); return list; } private RowRenderer placeRowRenderer = new RowRenderer() { @Override public void render(Row placeGroupListRow, Object data) { PlaceGroupList placeGroupListData = (PlaceGroupList) data; if (placeGroupListRow instanceof Group) { placeGroupListRow.appendChild(new Label(placeGroupListData.getTxPlace())); ((Group) placeGroupListRow).setOpen(false); } else { Label lTxPeriod = new Label(placeGroupListData.getTxPeriod()); lTxPeriod.setStyle("padding-left:15px"); placeGroupListRow.appendChild(lTxPeriod); placeGroupListRow.appendChild(new Label(placeGroupListData.getTxWeek())); placeGroupListRow.appendChild(new Label(placeGroupListData.getTxSat())); placeGroupListRow.appendChild(new Label(placeGroupListData.getTxSun())); placeGroupListRow.setStyle("cursor: pointer"); } } }; }
PlaceComparator class is on the above post.
Thanks in advance.
I found the bug, seems like ZK didn't handle the following line well.
((Group) placeGroupListRow).setOpen(false);
It'll cause the count number wrong.
After I fix it, I'll add comment at the tracker system:
http://tracker.zkoss.org/browse/ZK-212
Won't fix.
It's an application problem,
but ZK should provide more doc for such use case.
By use model, we should let it handle how to render the Component.
And GroupsModelArray has concept of whether the group is close or not.
Therefore, you should modify the state while prepare the model,
not change the status while render it.
Its lifecycle is then tangled, and the result not like you wanted.
The code to modify in your sample code would be like:
public void grid() {
List<PlaceGroupList> placeGroupList = null;
placeGroupList = getPlaceGroupList();
GroupsModelArray groupModelArray = new GroupsModelArray(placeGroupList, new PlaceComparator());
int count = groupModelArray.getGroupCount();
for(int i = 0 ; i < count ; i++){ groupModelArray.setClose(i, true); }
placesGrid.setRowRenderer(placeRowRenderer);
placesGrid.setModel(groupModelArray);
}
private RowRenderer placeRowRenderer = new RowRenderer() {
public void render(Row placeGroupListRow, Object data) {
PlaceGroupList placeGroupListData = (PlaceGroupList) data;
if (placeGroupListRow instanceof Group) {
placeGroupListRow.appendChild(new Label(placeGroupListData.getTxPlace()));
// ((Group) placeGroupListRow).setOpen(false);
Asked: 2011-07-13 07:45:58 +0800
Seen: 655 times
Last updated: Jul 25 '11