0

Managing focus in grid that has input field in rows

asked 2013-02-12 16:55:41 +0800

coleriv gravatar image coleriv
37 2

updated 2013-02-13 08:13:55 +0800

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>
delete flag offensive retag edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2013-03-05 10:26:57 +0800

benbai gravatar image benbai
2228 6
http://www.zkoss.org

updated 2013-03-06 02:51:57 +0800

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>
link publish delete flag offensive edit
Your answer
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
1 follower

RSS

Stats

Asked: 2013-02-12 16:55:41 +0800

Seen: 71 times

Last updated: Mar 06 '13

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