mvvmzkzul

zk grid several columns in the same row


I´m addressing a issue with zk grid that I don´t know how to solve.

I explain my problem:

I need to create a grid that shows a list of questions/answer, the different approach of that grid is that I need to show two pairs question/answer in the same row.

The next screenshot show how the grid has to work; i.e. the desired aspect:

enter image description here

I tried to do that using a template row:

    <template name="model"
                                        var="modeloIzquierda">
                                        <row>
                                                <label
                                                    class="${modeloIzquierda.procedencia}"
                                                    value="@bind(modeloIzquierda.pregunta)" width="50px"
                                                    if='${!modeloIzquierda.par}' />
                                                <textbox
                                                    style="border:none;"
                                                    value="@bind(modeloIzquierda.respuesta)"
                                                    onChanging="@command('respuestaOnChange', idPregunta=modeloIzquierda.idPregunta , respuesta=event.value)"
                                                    class="textboxcadm ${modeloIzquierda.procedencia}"
                                                    if='${modeloIzquierda.tipoPregunta eq "T" and !modeloIzquierda.par}' width="100%" />
                                                <combobox
                                                    value="@bind(modeloIzquierda.respuesta)"
                                                    onChanging="@command('respuestaOnChange', idPregunta=modeloIzquierda.idPregunta , respuesta=event.value)"
                                                    class="${modeloIzquierda.procedencia}"
                                                    if='${modeloIzquierda.tipoPregunta eq "E" and !modeloIzquierda.par}'
                                                    width="90px">
                                                    <comboitem
                                                        label="A" />
                                                    <comboitem
                                                        label="B" />
                                                    <comboitem
                                                        label="C" />
                                                </combobox>
                                                <checkbox
                                                    checked="@bind(modeloIzquierda.respuesta)"
                                                    onCheck="@command('respuestaOnChange',  idPregunta=modeloIzquierda.idPregunta , respuesta=self.checked)"
                                                    if='${modeloIzquierda.tipoPregunta eq "F" and !modeloIzquierda.par}'>
                                                </checkbox>
                                                <label 
                                                    class="${modeloIzquierda.procedencia}"
                                                    value="@bind(modeloIzquierda.pregunta)" width="50px" 
                                                    if='${modeloIzquierda.par}' />
                                                <textbox
                                                    style="border:none;"
                                                    value="@bind(modeloIzquierda.respuesta)"
                                                    onChanging="@command('respuestaOnChange', idPregunta=modeloIzquierda.idPregunta , respuesta=event.value)"
                                                    class="textboxcadm ${modeloIzquierda.procedencia}"
                                                    if='${modeloIzquierda.tipoPregunta eq "T" and modeloIzquierda.par}' width="100%" />
                                                <combobox
                                                    value="@bind(modeloIzquierda.respuesta)"
                                                    onChanging="@command('respuestaOnChange', idPregunta=modeloIzquierda.idPregunta , respuesta=event.value)"
                                                    class="${modeloIzquierda.procedencia}"
                                                    if='${modeloIzquierda.tipoPregunta eq "E" and modeloIzquierda.par}'
                                                    width="90px">
                                                    <comboitem
                                                        label="A" />
                                                    <comboitem
                                                        label="B" />
                                                    <comboitem
                                                        label="C" />
                                                </combobox>
                                                <checkbox
                                                    checked="@bind(modeloIzquierda.respuesta)"
                                                    onCheck="@command('respuestaOnChange',  idPregunta=modeloIzquierda.idPregunta , respuesta=self.checked)"
                                                    if='${modeloIzquierda.tipoPregunta eq "F" and modeloIzquierda.par}'>
                                                </checkbox>
                                        </row>
                                    </template>

The 'par' property indicates if the element (label, combobox, textbox or checkbox) has to appear in the left or right side of the grid.

But unfortunately this code is not working how I need. The result of my code (i.e actual aspect):

enter image description here

As you can see, independently of what label, textbox, combobox or checkbox is being shown the grid uses a new row for every one.

I´ve no idea how to deal with this issue. I´d appreciate any help, whatever solution will be welcome.


Solution

  • Sometimes it's just to difficult (or impossible) to write it in the zul.

    Here is an example how you can achieve such thing with a rowRenderer :

    MyEnum.java :

    public enum MyEnum {
        A(true),
        B(false),
        C(true),
        D(false),
        E(false);
    
        private boolean par;
    
        private MyEnum(boolean par) {
            this.par = par;
        }
    
        public boolean isPar() {
            return par;
        }
    }
    

    test.zul :

    <?xml version="1.0" encoding="UTF-8"?>
    <window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('be.mil.web.TestVM')" >
        <grid model="@init(vm.model)" rowRenderer="be.mil.web.MyRowRenderer"/>
    </window>
    

    TestVM.java :

    public class TestVM {
        public ListModel getModel() {
            return new ListModelList(MyEnum.values());
        }
    }
    

    MyRowRenderer.java :

    public class MyRowRenderer implements RowRenderer<MyEnum>{
    
        @Override
        public void render(Row row, MyEnum t, int i) throws Exception {
            if (t.isPar()) {
                row.appendChild(new Label(String.valueOf(t)));
            } else {
                row.getPreviousSibling().appendChild(new Label(String.valueOf(t)));
                row.getParent().removeChild(row);
            }
        }
    
    }
    

    And with a fiddle so you can test it directly out.