-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hi everybody, I need help for the problem I'm going to describe.
I've 2 grids: GridFrom and GridTo. GridFrom has 2 columns: in the first one I show data using a label; in the second one there's a toolbarbutton to add the data value from GridFrom to GridTo. Depending on the objects of the GridFrom model, it may occurs that in a row I have a combobox in place of the label. Now, if I click on the toolbarbutton of the last row, after click the focus goes to the first combobox in the grid, even if it is readonly. How can I avoid this behaviour?
In fact I need the grid doesn't move after any click action. I've looked for a solution on the forum, and I've tried some exotic solution, but still found neither a solution nor a workaround.
Any suggestion will be really appreciated.
Here is a simplified code to reproduce the problem. After loading, if you scroll the GridFrom to add the row 9, after clicking the "+", the grid will scroll up to row 2, where the combobox is.
For any doubt don't hesitate to ask.
FocusTestViewModel
package my.package;
import java.util.ArrayList;
import java.util.List;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
public class FocusTestViewModel {
private List<RowData> fromData;
private List<RowData> toData;
private List<String> comboData;
private String comboDefault;
@init
public void init() {
fromData = new ArrayList<RowData>();
toData = new ArrayList<RowData>();
comboData = new ArrayList<String>();
for (int i = 1; i <= 9; i++) {
fromData.add(new RowData("Row data " + i, false));
}
fromData.get(1).setComboValue(true);
for (int i = 1; i <= 2; i++) {
comboData.add("Combo value " + i);
}
comboDefault = comboData.get(0);
}
@Command
@NotifyChange({ "fromData", "toData" })
public void doAddTo(@BindingParam("data") RowData data) {
toData.add(data);
fromData.remove(data);
}
@Command
@NotifyChange({ "fromData", "toData" })
public void doAddFrom(@BindingParam("data") RowData data) {
fromData.add(data);
toData.remove(data);
}
public List<RowData> getFromData() {
return fromData;
}
public List<RowData> getToData() {
return toData;
}
public List<String> getComboData() {
return comboData;
}
public void setFromData(List<RowData> fromData) {
this.fromData = fromData;
}
public void setToData(List<RowData> toData) {
this.toData = toData;
}
public void setComboData(List<String> comboData) {
this.comboData = comboData;
}
public String getComboDefault() {
return comboDefault;
}
public void setComboDefault(String comboDefault) {
this.comboDefault = comboDefault;
}
public class RowData {
protected String descr;
protected boolean comboValue;
public RowData(String descr, boolean comboValue) {
this.descr = descr;
this.comboValue = comboValue;
}
public String getDescr() {
return descr;
}
public boolean isComboValue() {
return comboValue;
}
public void setDescr(String descr) {
this.descr = descr;
}
public void setComboValue(boolean comboValue) {
this.comboValue = comboValue;
}
}
}
focusTest.zul
<?xml version="1.0" encoding="UTF-8"?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<?link rel="stylesheet" type="text/css" href="/css/styles.css"?>
<zk xmlns="http://www.zkoss.org/2005/zul"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd">
<window apply="org.zkoss.bind.BindComposer" title="Focus test"
viewModel="@id('vm') @init('my.package.FocusTestViewModel')">
<grid model="@load(vm.fromData)" width="300px" height="150px"
style="margin-left: 50px">
<columns>
<column label="GridFrom" />
<column width="32px" />
</columns>
<template name="model">
<row>
<cell>
<label value="${each.descr}"
unless="${each.comboValue}" />
<combobox hflex="1" model="@load(vm.comboData)"
readonly="true" if="${each.comboValue}">
<template name="model">
<comboitem label="@load(each)" />
</template>
</combobox>
</cell>
<cell>
<toolbarbutton label="+"
onClick="@command('doAddTo', data=each)" />
</cell>
</row>
</template>
</grid>
<grid model="@load(vm.toData)" width="300px" height="150px"
style="margin-left: 50px; margin-top: 20px">
<columns>
<column label="GridTo" />
<column width="32px" />
</columns>
<template name="model">
<row>
<label value="${each.descr}" />
<toolbarbutton label="-"
onClick="@command('doAddFrom', data=each)" />
</row>
</template>
</grid>
</window>
</zk>
Edit: override replaceWidget and use sclass to target specific component
This is caused by ZK try to restore the focus after the old focused widget (the clicked toolbarbutton) removed, you can try override the replaceWidget function as below:
<?xml version="1.0" encoding="UTF-8"?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<?link rel="stylesheet" type="text/css" href="/css/styles.css"?>
<zk xmlns="http://www.zkoss.org/2005/zul"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd">
<script><![CDATA[
zk.afterLoad("zul", function () {
var _wgt = {};
zk.override(zk.Widget.prototype, _wgt, {
replaceWidget: function (newwgt) {
// is the specific rows that contains '+' button
if (jq(this.$n()).find('.s-tbbtn').length) {
// clear focus since we know it will be replaced
zk.currentFocus = null;
}
_wgt.replaceWidget.apply(this, arguments);
}
});
});
]]></script>
<window apply="org.zkoss.bind.BindComposer" title="Focus test"
viewModel="@id('vm') @init('my.package.FocusTestViewModel')">
<grid model="@load(vm.fromData)" width="300px" height="150px"
style="margin-left: 50px">
<columns>
<column label="GridFrom" />
<column width="32px" />
</columns>
<template name="model">
<row>
<cell>
<label value="${each.descr}"
unless="${each.comboValue}" />
<combobox hflex="1" model="@load(vm.comboData)"
if="${each.comboValue}">
<template name="model">
<comboitem label="@load(each)" />
</template>
</combobox>
</cell>
<cell>
<toolbarbutton label="+" sclass="s-tbbtn"
onClick="@command('doAddTo', data=each)" />
</cell>
</row>
</template>
</grid>
<grid model="@load(vm.toData)" width="300px" height="150px"
style="margin-left: 50px; margin-top: 20px">
<columns>
<column label="GridTo" />
<column width="32px" />
</columns>
<template name="model">
<row>
<label value="${each.descr}" />
<toolbarbutton label="-"
onClick="@command('doAddFrom', data=each)" />
</row>
</template>
</grid>
</window>
</zk>
Asked: 2013-02-12 16:55:41 +0800
Seen: 71 times
Last updated: Mar 06 '13