Search code examples
javalistviewhtml-tablewicketmarkup

Wicket: Dynamically fill cells with custom content


I made a table using wicket ListViews to create the columns and the rows, code looks like this:

ErhebungMatrixPanel.java

public ErhebungMatrixPanel(String id) {
    super(id);
    this.add(matrixForm);
    matrixForm.add(new ListView<Zustaendigkeit>("columns", zustaendigkeiten){
        private static final long serialVersionUID = 1L;

        @Override
        protected void populateItem(ListItem<Zustaendigkeit> item) {
            final int index = item.getIndex();
            item.add(new Label("zustLabel", zustaendigkeiten.get(index).getName().toString()));
        }
    });

    matrixForm.add(rows = new ListView<Erhebung>("rows", erhebungen){
        private static final long serialVersionUID = 1L;

        @Override
        protected void populateItem(ListItem<Erhebung> item) {
            final IModel<Boolean> checked = Model.of(Boolean.FALSE);
            final int index = item.getIndex();
            item.add(new Label("erhebungLabel", erhebungen.get(index).getName()));

            item.add(new AjaxCheckBox("check", checked) {
                private static final long serialVersionUID = 1L;

                @Override
                protected void onUpdate(AjaxRequestTarget target) {
                    //TODO
                }
            });
        }
    });
}

In this table I want to put an AjaxCheckBox into every cell, to create something like an authorization matrix now the problem is, since the length of the List zustaendigkeiten most likely grow larger some time, that I can't insert a static amount of CheckBoxes. Right now only one column of the table is covered with CheckBoxes. The responding .html file looks like this:

<wicket:panel>
    <form wicket:id="matrixForm">
        <table class="matrix">
            <thead>
                <tr class="headers">
                    <th></th>
                    <span wicket:id="columns">
                        <th wicket:id="zustLabel"></th>
                    </span>
                </tr>
            </thead>
            <tbody>
                <tr wicket:id="rows">
                    <th wicket:id="erhebungLabel"></th>
                    <td><input wicket:id="check" type="checkbox" /></td>
                </tr>
            </tbody>
        </table>
    </form>
</wicket:panel>

Something like this:

<tbody>
<tr wicket:id="rows">
    <th wicket:id="erhebungLabel"></th>
    <td><input wicket:id="check" type="checkbox" /></td>
    <td><input wicket:id="check" type="checkbox" /></td>
    <td><input wicket:id="check" type="checkbox" /></td>                
</tr>
</tbody>

Would obviously not work because 1. It should be dynamical, but I gues JS could help out there, 2. Wicket would throw a MarkUp error.

Is there any newCellItem alike method I could use like there is in a DataTable?


Solution

  • Is something like this what you need?

    HTML:

    <form>
        <table>
            <tr>
                <th></th>
                <th wicket:id="headerList"><span wicket:id="name"></span></th>
            </tr>
            <tr wicket:id="rowList">
                <td wicket:id="name"></td>
                <td wicket:id="cellList">
                    <input type="checkbox" wicket:id="checkbox"/>
                </td>
            </tr>
        </table>
    </form>
    

    Java:

    add(new ListView<User>("headerList", new PropertyModel<>(this, "users")) {
        @Override
        protected void populateItem(ListItem<User> listItem) {
            listItem.add(new Label("name", new PropertyModel(listItem.getModelObject(), "name")));
        }
    });
    
    add(new ListView<String>("rowList", new PropertyModel<>(this, "roles")) {
    
        @Override
        protected void populateItem(ListItem<String> listItem) {
            final String role = listItem.getModelObject();
    
            listItem.add(new Label("name", role));
    
            listItem.add(new ListView<User>("cellList", new PropertyModel<>(TestPage.this, "users")) {
    
                @Override
                protected void populateItem(ListItem<User> listItem) {
                    final User user = listItem.getModelObject();
    
                    listItem.add(new AjaxCheckBox("checkbox", new IModel<Boolean>() {
    
                        @Override
                        public Boolean getObject() {
                            return user.getRoles().contains(role);
                        }
    
                        @Override
                        public void setObject(Boolean aBoolean) {
                            if (aBoolean) {
                                user.getRoles().add(role);
                            } else {
                                user.getRoles().remove(role);
                            }
                        }
    
                        @Override
                        public void detach() {
    
                        }
                    }) {
    
                        @Override
                        protected void onUpdate(AjaxRequestTarget ajaxRequestTarget) {
    
                        }
                    });
                }
            });
        }
    });