Search code examples
listviewwicketwicket-1.6

Wicket - How to use ListView in custom form component?


I'm trying to implement a custom form component which contains a ListView.

My Custom Form Component:

public class NotificationDataListPanel extends FormComponentPanel {

    private ListView<NotificationDataBean> listView = null;

    public NotificationDataListPanel(String id) {
        this(id, null);
    }

    public NotificationDataListPanel(String id, List list) {
        super(id);

        listView = new ListView<NotificationDataBean>("listView") {
            @Override
            protected void populateItem(final ListItem<NotificationDataBean> item) {
                final NotificationDataPanel dataPanel = new NotificationDataPanel("dataPanel", new Model<NotificationDataBean>() {
                    @Override
                    public NotificationDataBean getObject() {
                        return item.getModel().getObject();
                    }

                    @Override
                    public void setObject(final NotificationDataBean value) {
                        item.setModelObject(value);
                    }
                });
                item.add(dataPanel);
            }
        };
        add(listView);

        add(new AjaxLink("addNewNDPanel") {
            @Override
            public void onClick(AjaxRequestTarget target) {
                List<NotificationDataBean> modelObject = listView.getModelObject();
                if (modelObject == null) {
                    modelObject = new ArrayList<NotificationDataBean>();
                }
                modelObject.add(new NotificationDataBean());
                listView.setModelObject(modelObject);

                target.add(this);
            }
        });
    }

    @Override
    protected void onBeforeRender() {
        super.onBeforeRender();
        List<NotificationDataBean> modelObject = (List<NotificationDataBean>) getModelObject();
        if (modelObject != null && !modelObject.isEmpty()) {
            listView.setModelObject(modelObject);
        } else {
            listView.setModel(new Model());
        }
    }

    @Override
    protected void convertInput() {
        List<NotificationDataBean> modelObject = listView.getModelObject();

        setConvertedInput(modelObject);
        updateModel();
    }
}

NotificationDataPanel works great in forms on its own and on the other hand I could use it in ListView in forms (not in separated form component).

Works fine:

    final Form form = new Form("form", new CompoundPropertyModel(testFormBean));

    final ListView<NotificationDataBean> strs = new ListView<NotificationDataBean>("notiL") {
        @Override
        protected void populateItem(final ListItem<NotificationDataBean> item) {
            final NotificationDataPanel quxField = new NotificationDataPanel("str", new Model<NotificationDataBean>() {
                @Override
                public NotificationDataBean getObject() {
                    return item.getModel().getObject();
                }

                @Override
                public void setObject(final NotificationDataBean value) {
                    item.setModelObject(value);
                }
            });
            item.add(quxField);
        }
    };
    form.add(strs);

But when I tried to use it in ListView in separated form component I got this exception.

Last cause: No get method defined for class: class TestFormBean expression: listView

NOT OK

    final Form form = new Form("form", new CompoundPropertyModel(testFormBean));
    form.add(new NotificationDataListPanel("notiL"));

And TestFormBean class:

class TestFormBean implements Serializable {
    List<NotificationDataBean> notiL;
}

The word, listView in exception refers to ListView id in NotificationDataListPanel.

Thanks in advance for any tips how to fix this and please accept my apologies for my bad English.


Solution

  • You're not giving a model to your ListView, so it will search for one up in the component hierarchy. CompountPropertyModel serves models to child components, and it uses their id to find a property on their model.

    You probably just want to do:

    new ListView<NotificationDataBean>("listView", list);