javazkzul

dynamic radio button from java to zul zk


Hello :) iam bootcamp java still learn more about java and framework zk

anyone know how to create dynamic radio button such as data from database but now i'm not use it.

this is my source code for test

radiobutton.zul

<?page title="new page title" contentType="text/html;charset=UTF-8"?>
<zk>
<window title="Customer" border="normal" apply="org.zkoss.bind.BindComposer"
    viewModel="@id('vm') @init('vmd.RadioButton')">
     <cell> 
        <vlayout> 
            <radiogroup id="radiogroup">
            </radiogroup>
        </vlayout> 
    </cell>
</window>
</zk>


RadioButton.java

public class RadioButton {

    public Radiogroup getRadiogroup() {
        return radiogroup;
    }

    public void setRadiogroup(Radiogroup radiogroup) {
        this.radiogroup = radiogroup;
    }

    private Radiogroup radiogroup = new Radiogroup();

    @Init
    public void load() {
        ArrayList<String> columnEntries = new ArrayList<String>();
        columnEntries.add("a");
        columnEntries.add("b");

        for (String entry : columnEntries) {
            radiogroup.appendItem(entry, entry);
        }
        radiogroup.setVisible(true);
    }
}

And Result from that code is no radio button and no error :*( please help me..


Solution

  • According to ZK component lifecycle, init method is called before component rendering. So you have to set the value after compose (@AfterCompose). You can also wire your component. Example :

    Viewmodel :

    package your.package;
    
    import org.zkoss.bind.annotation.AfterCompose;
    import org.zkoss.bind.annotation.ContextParam;
    import org.zkoss.bind.annotation.ContextType;
    import org.zkoss.zk.ui.Component;
    import org.zkoss.zk.ui.select.Selectors;
    import org.zkoss.zk.ui.select.annotation.Wire;
    import org.zkoss.zul.Radiogroup;
    
    public class RadioButton {
    
        @Wire
        private Radiogroup radiogroup;
    
        @AfterCompose
        public void init(@ContextParam(ContextType.VIEW) Component view) {
            Selectors.wireComponents(view, this, false);
            radiogroup.appendItem("Test 1", "test1");
            radiogroup.appendItem("Test 2", "test2");
        }
    }
    

    View :

    <vlayout apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('your.package.RadioButton')">
        <radiogroup id="radiogroup"/>
    </vlayout>
    

    You can also bind a list from your viewmodel.

    Example :

    Viewmodel :

    private List<String> optionList;
    private String selectedOption;
    
    public String getSelectedOption() {
       return selectedOption;
    }
    public void setSelectedOption(String selectedOption) { 
       this.selectedOption = selectedOption;
    }
    public List<String> getOptionList() {
       return optionList;
    }
    public void setOptionList(List<String> optionList) {
       this.optionList = optionList;
    }
    
    @Init
    public void init() {
        List<String> entries = new ArrayList<String>();
        entries.add("a");
        entries.add("b");
        setOptionList(entries);
    }
    

    View :

    <vlayout apply="org.zkoss.bind.BindComposer" viewModel="@id('vmd') @init('your.package.yourViewModel')">
       <radiogroup selectedItem="@bind(vmd.selectedOption)" model="@load(vmd.optionList)">
          <template name="model">
             <radio label="@load(each)" value="@load(each)"/>
          </template>
       </radiogroup>
    </vlayout>
    

    UPDATE : As stated by Malte Hartwig in the comments, this way is preferred when using MVVM (component wiring is discouraged, see http://books.zkoss.org/zk-mvvm-book/8.0/advanced/wire_components.html).


    There are several other ways to do it, for example using a Composer.