Muhammad Kholid B
Muhammad Kholid B

Reputation: 477

Button to Show a Window from Listbox Row

I want to create a button that can show a window to show details of elements in listbox when it's clicked. the listbox itsetf was created from a list of JSONObject like this:

<listbox id="userListbox">
<listhead>
    <listheader laber="Action"></listheader>
    <listheader label="Id"></listheader>
    <listheader label="Name"></listheader>
    <listheader label="Address"></listheader>
    <listheader label="Phone"></listheader>
</listhead>
<listitem forEach="${userController.list}">
    <listcell>
        <button label="Detail"  id="detailButton"></button>
    </listcell>
    <listcell label="${each.id}" ></listcell>
    <listcell label="${each.name}" ></listcell>
    <listcell label="${each.address}" ></listcell>
    <listcell label="${each.phone}" ></listcell>
</listitem>
</listbox>

for every row (listcell) there is always a button to show the details. but when I load the page, it failed to show the list with error message:

Not unique in ID space < Window cP8Q0#userWindow>: detailButton.

any idea to show a window when the button clicked? here is the code when button is clicked:

@Listen("onClick = #detailButton")
public void showModal(Event event) {
    Component comp = Executions.createComponents("/widgets/window/modal_dialog/employee_dialog.zul", null, null);

    if(comp instanceof Window) {
        ((Window)comp).doModal();
    }
}

thank you for your help.

Upvotes: 0

Views: 2062

Answers (2)

simbo1905
simbo1905

Reputation: 6832

The problem is that if you click on different buttons you are running the createComponents again and again. Your employee_dialog.zul is only safe to include into the page once as it has IDs in it; if you do the operation twice you are creating a second set of components with the same ID and the IDs should be unique within a given idSpace (see the ZK developer guide for the theory).

There are other issues here: why create the components twice? Why not keep one and only one set around, showing and hiding them based on button clicks. That is more efficient.

Look at Button to Show a Window from Listbox Row which shows that you can:

<zk>
    <!-- hidden -->
    <window id="wnd" title="My Modal" visible="false" width="300px">
        <button label="close" onClick="wnd.visible = false"/>
    </window>
    <!-- click button to pop the hidden window! -->
    <button label="do it" onClick="wnd.doModal()"/>
</zk>

So you can use a

<include src="/widgets/window/modal_dialog/employee_dialog.zul">

to pull the model dialog into the bottom of the main page once and only once. Then in the code you can set the data into it and do

win1.doModal(); 

where win1 is the modal window defined in the fragment. You have to tell the model window what to display before you pop it but that is not hard. Use desktopScope.put( "myName", this) to have the controller/view-model of the dialog box register itself in a location where the controller/view-model in the main window can find it and talk to it to pass it the data to render.

Two other tips.

  1. Hide your fragments as /WEB-INF/zul/employee_dialog.zul as anything under WEB-INF cannot be directly accessed by a browser for better security.
  2. Try not to put any zul into your java. That is mixing behaviour with presentation. Sometimes it is unavoidable but always try first to keep the zul in the zul then interact with it via java IDs only (much like my suggestion). It is not always possible but separation of logic from layout is a core design pattern.

Simon

Upvotes: 1

ten2net
ten2net

Reputation: 16

<button label="Detail" />
@Listen("onClick = listbox listitem listcell button")

Upvotes: 0

Related Questions