rohit12sh
rohit12sh

Reputation: 847

ZK: Custom Component with Listbox not binding SelectedItem

I am working on creating a new Custom Component and unable to bind a controller's property to the SelectedItem annotation property of my custom component. My idea is that any one who passes my Custom component SelectedItem annotation, I should be able to retrieve it in my component and assign it myself to the ListBox's SelectedItem property. This will give flexibility to the users of my component to not worry about the internals and the component will be re-usable.

Problem is that I am not able to get/set the Controller value in my custom component. I get NULL. Can someone please help me resolve this issue or point me to the right direction? Here is the code:

<bandbox id="filterDropdownBandBox" instant="true" readonly="false">
<bandpopup id="filterDropdownBandPopup" style="max-height:250px;overflow-x:hidden">
    <listbox id="listBox" hflex="1" rows="0" >
         <template name="model">
             <listitem>
                 <listcell label="${each.label}" />
             </listitem>
         </template>
     </listbox>
</bandpopup>

public class FilterDropdown extends Div implements IdSpace {

@Wire
private Listbox listBox;
@Wire
private Bandpopup filterDropdownBandPopup;
@Wire
private Bandbox filterDropdownBandBox;

private ListModelList<GenericNameValuePair> lbModel;

public FilterDropdown() {
    Executions.createComponents("/filterDropdown.zul", this, null);
    Selectors.wireComponents(this, this, false);
    Selectors.wireEventListeners(this, this);
}
public void setSelectedItem(Listitem l) // getting NULL here
    {
        l.setParent(listBox);
        listBox.setSelectedItem(l);
    }
 public void saveSelection() {
     listBox.getSelectedItem();
 }

 public Listitem getSelectedItem() {
     return listBox.getSelectedItem();
 }
}

This is how I added this component to lang-addon.xml file

<component>
    <component-name>filter-dropdown</component-name>
    <extends>div</extends>
    <component-class>com.components.FilterDropdown</component-class>
    <annotation>
        <annotation-name>DDBIND</annotation-name>
        <property-name>selectedItem</property-name>
        <attribute>
            <attribute-name>ACCESS</attribute-name>
            <attribute-value>both</attribute-value>
        </attribute>
    </annotation>
</component>

And this is how I am using my custom component in other ZUL files

 <filter-dropdown id="filterProjDropdown" selectedItem="@DDBIND{XYZCtrl.bean.propbean.actualProp}"/>

Upvotes: 2

Views: 735

Answers (1)

chillworld
chillworld

Reputation: 4277

First of all, keep to the normal annotation like @load(), @save() or @bind()`.

Now, mine first suggestion is to throw your zul away.
Implement the AfterCompose interface in your component and add all the items there with a renderer.
It makes it easier for anyone to change that component and it will be more performent.

Secondly, use the correct annotation in your class :

@ComponentAnnotation({"selectedItem:@ZKBIND(ACCESS=both,SAVE_EVENT=onSelect)"}) 

Like this your lang-addon.xml should look like :

<component> 
     <component-name>filter-dropdown</component-name> 
     <extends>div</extends> 
     <component-class>com.components.FilterDropdown</component-class> 
</component> 

And as last :

You need to inform the binder that there was a change in the selectedItems :

Events.postEvent("onSelect", FilterDropdown.this, selectedItems);

You should handle this in an eventlistener attached to the bandbox.

If you want an advanced working component code including in how to export it to a separate jar, please check out mine github project.

Upvotes: 3

Related Questions