1

Problems with visible/invisible grids using flex

asked 2013-05-13 10:51:17 +0800

coleriv gravatar image coleriv
37 2

updated 2013-05-13 10:54:09 +0800

Hi everybody, I've two grids in a container. Each grid must be flexible, such as the container. I need to show only one grid at a time, because they show different kind of data, and I've thought to use the "visible" attribute to get it.

When I load the page, the first grid is 100% wide even if it has no elements to show: ok. Then I switch to second grid, that has no elements to show and it too is 100% wide: ok. Now I switch again to the first one, and it's 50% wide: not ok.

Here is some sample code.

flex_grid.zul

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <hlayout apply="org.zkoss.bind.BindComposer"
        viewModel="@id('vm') @init('eu.dedalus.pst.esercizio.FlexGridVM')"
         vflex="1">
        <button label="Switch grid" onClick="@command('doSwitchGrid')" />
        <grid hflex="1" vflex="1" emptyMessage="No elements in first grid"
            visible="@load(vm.firstGridVisible)">
            <columns>
                <column label="Name" hflex="1" />
                <column label="Surname" hflex="1" />
                <column label="Birthday" hflex="min" />
                <column label="City" hflex="min" />
                <column label="Note" hflex="2" />
            </columns>
        </grid>
        <grid hflex="1" vflex="1" emptyMessage="No elements in second grid"
            visible="@load(not vm.firstGridVisible)">
            <columns>
                <column label="Note" hflex="2" />
                <column label="City" hflex="min" />
                <column label="Birthday" hflex="min" />
                <column label="Surname" hflex="1" />
                <column label="Name" hflex="1" />
            </columns>
        </grid>
    </hlayout>
</zk>

FlexGridVM

public class FlexGridVM {
    private boolean firstGridVisible;

    @Init
    public void init() {
        firstGridVisible = true;
    }

    public boolean isFirstGridVisible() {
        return firstGridVisible;
    }

    public void setFirstGridVisible(boolean firstGridVisible) {
        this.firstGridVisible = firstGridVisible;
    }

    @Command
    @NotifyChange("firstGridVisible")
    public void doSwitchGrid() {
        firstGridVisible = !firstGridVisible;
    }
}

The sample is really clear I hope.

If you set a fixed width to the <hlayout>, the behaviour is the same.

If you use the <hbox>, surprisingly you will get 3 differents behaviour.

  1. If you set a fixed width, i.e. hflex="1000px", or width="100%", the behaviour is the expected one
  2. If you set hflex="1", the behaviour is the same of <hlayout>
  3. If you set neither width nor hflex, each time you switch the visibility, the first grid width increases each time of the half of the previous free space (?!)

Now, I could solve my problem using <hbox width="100%"> but I'd prefer to use <hlayout>: is there a way to obtain the same result using it?
<hlayout> and <hbox> are supposed to behave identically in this context?
Is the <hbox> behaviour correct, or there's a bug (obviously case 3 is a bug)?

Thanx for your help,
Roberto

delete flag offensive retag edit

3 Answers

Sort by ยป oldest newest most voted
1

answered 2013-05-20 09:11:21 +0800

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

updated 2013-05-20 09:11:39 +0800

The problem is mixing flex with hlayout, it happens as follows:

  • command triggered and vm update the visible attribute
  • the first grid is updated at first and then becomes visible
  • calculate width and height based on the flex settings

    !! but note, the second grid still visible at this moment

  • the visible attribute of second grid is updated then the second grid becomes invisible

then you see the first grid with wrong size

This is why it happened and only first grid has problem

what you can do is, if you want to let multiple components share one block and display only one of a time, use a div to wrap all the components with original flex settings then use width="100%"/height="100%" to replace the flex settings of those components.

e.g.,

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <hlayout apply="org.zkoss.bind.BindComposer"
        viewModel="@id('vm') @init('eu.dedalus.pst.esercizio.FlexGridVM')"
         vflex="1">
        <button label="Switch grid" onClick="@command('doSwitchGrid')" />
        <div hflex="1" vflex="1">
            <grid height="100%" width="100%" emptyMessage="No elements in first grid"
                visible="@load(vm.firstGridVisible)">
                <columns>
                    <column label="Name" hflex="1" />
                    <column label="Surname" hflex="1" />
                    <column label="Birthday" hflex="min" />
                    <column label="City" hflex="min" />
                    <column label="Note" hflex="2" />
                </columns>
            </grid>
            <grid height="100%" width="100%" emptyMessage="No elements in second grid"
                visible="@load(not vm.firstGridVisible)">
                <columns>
                    <column label="Note" hflex="2" />
                    <column label="City" hflex="min" />
                    <column label="Birthday" hflex="min" />
                    <column label="Surname" hflex="1" />
                    <column label="Name" hflex="1" />
                </columns>
            </grid>
        </div>
    </hlayout>
</zk>
link publish delete flag offensive edit
1

answered 2013-05-13 11:22:49 +0800

gganassin gravatar image gganassin flag of Luxembourg
540 6
http://www.hybris.com/

Hello! i tried your code with Chrome and ZK 6.5.2 and it works fine: grids are always gaining the 100% of space: which version/browser are you using? Giovanni

link publish delete flag offensive edit
1

answered 2013-05-16 08:53:53 +0800

nsharma gravatar image nsharma flag of India
917 1 11

The reason for such behavior : When the Zul is rendered and visibilty of some component is false,its object is not loaded.But for once its loaded,the object remains in DOM(Data object model) until its made as null,

so when both the grids are loaded,and you make one of them visible:false ,its object still remains in DOM,and occupies the half space.

The things you have to do is to make the components object as null.

And also it not only for grid,this happens for any component.

reply if it works.

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-05-13 10:51:17 +0800

Seen: 122 times

Last updated: May 20 '13

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