Getting selected ListBox values on button Click | ZK

7.9k views Asked by At

I am very new to ZK framework and trying to customize few things and have struck at one point which I am not sure how to achieve that.

I have a predefined section where I need to show 2 drop down and a button and need to persist those drop down values on button click event. This is how It has been define in Spring file

<bean id="mybean" parent="parentBean" class="WidgetRenderer">
   <property name="detailRenderer">
            <bean class="DetailsListRenderer" parent="abstractWidgetDetailRenderer"/>
   </property>
</bean>

Here mybean is being used to show main section and I am adding my drop down using this bean while button are being added to detailRenderer.

Save button is bind to onClick event, but I am not sure how I can fetch values from my custom drop down? I am aware about binding those Dropdown with onClick event but they have to be in same class.

Can any one suggest me how I can fetch values of those drop down.I am creating down down with following code

Listbox listbox = new Listbox();
listbox.appendItem("item1", "item1");
listbox.appendItem("item2", "item2");

This is my button code in another class

protected void createUpdateStatusButton(Widget widget,Div container)
 {
   Button button = new Button(LabelUtils.getLabel(widget, buttonLabelName, new Object[0]));
   button.setParent(container);
    button.addEventListener("onClick", new EventListener()
    {
      public void onEvent(Event event)throws Exception
       {
             MyClass.this.handleSaveStatusEvent(widget, event);
          }
    });
  }
2

There are 2 answers

4
Sean Connolly On

You may want to listen to the onSelect (I prefer to use Events.ON_SELECT rather than writing the strings) which is more specific to when the Listbox selection changes.

Either way, the key is to get the information you want from the Event passed to your EventListener, rather than going back to your Listbox itself. The basic Event usually carries useful information on getTarget and getData but using more specific events (SelectEvent in this case) will give you access to more relevant info.

button.addEventListener(Events.ON_SELECT, new EventListener<SelectEvent<Listitem, MyDataObject>() {
    public void onEvent(SelectEvent<Listitem, MyDataObject> event) {
        // Now you can access the details of the selection event..
        List<Listitem> selectedItems = event.getSelectedItems();
        List<MyDataObject> selectedObjects = event.getSelectedObjects();
    }
});

You can find out what events are available for different ZK widgets in their Component Reference documentation.

2
Sean Connolly On

If I understand the question (I don't think I did in my previous response) you want to gather information from the page (eg: Listbox selection state) when the user clicks a button. Your problem being that you are using disparate classes to compose the page and so don't have access to the various ZK Components when the button is clicked.

(Ignoring the multiple class issue for a minute)
From a high level, there are sort of two camps in the ZK community. The newer MVVM approach suggests the view should push the relevant state to the back end as the user interacts with the front end. This way, the back end never needs to ask for the client state, and when the button is clicked, the values/state are on the server ready to be used.

The other camp binds the client to the server such that the back end always has access to the client Components and when the button is clicked, the values/state can easily be retrieved by interacting with the components.

Another approach is more like what I was talking about in my previous answer, to not bind the back end to the client at all but to rely on event data as much as possible. I favor this approach where it is sufficient.

Now, you're free to choose your favored approach and ZK has lots of documentation on how to work in either of these camps. The question then is where is the client state stored on the server (either pushed there by the client in MVVM or bound there in MVC). I don't think that's a question that can be solved here, that's a software engineering challenge. I personally suggest you take on standard ZK patterns so as not to but heads with the framework. If you really want to go your route, you can grab a reference to the Listbox on the fly like so:

public class Foo {

    public static final String LISTBOX_ID = "myListbox";

    public void renderListbox(Component parent, MyItem items) {
        Listbox listbox = new Listbox();
        listbox.setId(LISTBOX_ID);
        listbox.setParent(parent);
        for (MyItem item : items) {
            listbox.appendItem(item.getName(), item);
        }
    }

}

public class Bar {

    @Listen(Events.ON_CLICK + " = #saveButton")
    public void saveButtonClicked(Event event) {
        Component saveButton = event.getTarget();
        Listbox listbox = (Listbox) saveButton.getFellow(Foo.LISTBOX_ID);
        Set<Listitem> selection = listbox.getSelectedItems();
        // do something
}