Alvaro Pedraza
Alvaro Pedraza

Reputation: 1292

ZK how to add grid based on user input

I'm working in a web application using ZK. I'm struggling with a window where I need to render a grid with as much rows as the user specifies. It should be something like:

<grid>
    <columns>
        <column width="150px"/>
        <column width="350px"/>
    </columns>
    <rows>
        <row>
            <cell>
                <label value="Rows to add"/>
            </cell>
            <cell>
                <textbox id="txt_rowamount"/>
            </cell>
        </row>
    </rows>
</grid>

<grid id="grid">
    <columns>
        <column width="100px" label="Field 1" align="center"/>
        <column width="100px" label="Field 2" align="center"/>
        <column width="100px" label="Field 3" align="center"/>
    </columns>

    <rows id="rows" forEach="${rowModelList}">
        <row>
            <cell>
                <textbox value="${each.field1}" />
            </cell>
            <cell>
                <textbox value="${each.field2}" />
            </cell>
            <cell>
                <textbox value="${each.field3}" />
            </cell>
        </row>
    </rows>
</grid>

<button id="btn_generate" label="Generate Rows"/>

So, if you type 4 in txt_rowamount a grid with 4 row components and 3 textbox components in each row. The textboxes should be empty and when I complete every textbox the user input should be binded to fieldN of every rowModel item, do I make myself clear?

I'm trying with something like this in the composer:

private ListModel<RowModel> rowModelList;

@Autowired
private Grid grid;

@Override
public void doAfterCompose(final Window component) throws Exception {
    super.doAfterCompose(component);

    rowModelList = new ListModelList<>();

    grid.setVisible(false);
}

public void onClick$btn_generate() {
    // TODO Add four empty elements to rowModelList

    grid.setVisible(true);
}

Being RowModel like

public class RowModel {

    private String field1;
    private String field2;
    private String field3;

    // ommited constructors, getters and setters

}

I believe that the approach should be MVVM instead of the current MVC but I don't know how to do this. Besides, I don't know if you can mix the approachs in the same application and what are the advantages and disadvantages of doing that.

I've seeing the ZK grid demos but all of them are using already populated objects to render the tables, so it's not useful to me.

If someone can give me a hand in this issue, it would be greatly appreciated. If you need more information on the code or the requirements for this problem, please comment it out.

Thanks in advance for your answers.

Upvotes: 0

Views: 389

Answers (1)

cor3000
cor3000

Reputation: 956

It seems there's a lot missing in your current attempt, so I'll try to fill the gaps. If impatient here a runnable example on zkfiddle.

Since you were talking about binding component attributes to model values I'd suggest using ZK's DataBinding which integrates nicely into the MVVM development pattern (sorry for the link, but that's not a one-liner).

In any case the example illustrates how to combine ZK features such as (ListModelList with templates, Property-/Command-Binding) into a simple dynamic UI.

As you can see in code, adding, (re)moving a row inside the model requires rudimentary operations (the grid will update its child-rows automatically):

rows.add(new RowModel(...));
rows.remove(row);

Since the ListModelList is assigned to the <grid> component via @init(vm.rows), the grid will listen to changes to the ListModel and add remove grid-rows accordingly. It uses the <template name="model" var="rowModel"> to render new rows when added to the model. The template variable rowModel variable represents the rowModel object. (more on that in our documentation)

I hope this information is not overwhelming ... if so please let me know.

BTW: the forEach-attribute you were trying to use previously is used for static ui composition (at zul parse time) where no dynamic control is required. For dynamic cases use ListModel(List) in combination with templates.

Robert

Upvotes: 1

Related Questions