H. Saxena
H. Saxena

Reputation: 345

Wicket: Dynamically populate RadioGroup outside page constructor

I have a page that displays some radio options based on a List that I receive from the previous page. Concretely- First Page --> Submit button pressed --> List generated --> This Page --> Populate Radio Group (using List View)

The problem is that all pages are initialized at the start of the application. Therefore, If I populate my radio group in the constructor, I get a blank page (Since the List is empty).

Also, If I initialize my radio group or list view outside the constructor, I receive "wicket id not found" errors (because wicket doesn't find the wicket:id in the class upon its initialization).

Here is my HTML code:

<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
    <head>
    </head>
    <body>
        <wicket:panel>
            <form wicket:id="selectionPageForm">
                <table width="100%" cellpadding="5" class="datapass">
                    <tr>
                        <td>
                            <div wicket:id="selectGroup">
                                <span wicket:id="selectRepetor">
                                     <input type="radio" class="radioAlign" wicket:id="selection" checked="checked"/> 
                                    <label  class="check" style="float:none;" wicket:id="name">[bankName]</label>
                                </span>
                            </div>  
                        </td>
                    </tr>
                </table>
                <div wicket:id="feedback"></div>
            </form>
            <hr>
        </wicket:panel>
    </body>
</html>

And here is my Java page: The dataPassRegister is just a POJO containing the ArrayList of String

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.Radio;
import org.apache.wicket.markup.html.form.RadioGroup;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.Model;
import com.googlecode.wicket.jquery.ui.panel.JQueryFeedbackPanel;
import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;


public class SelectionPage extends AbstractFormDialog<DataPassRegister>{

    private final Form<DataPassRegister> form;
    private final FeedbackPanel feedback;
    protected final DialogButton btnSubmit = new DialogButton("Submit");
    protected final DialogButton btnCancel = new DialogButton(LBL_CANCEL);
    private ArrayList<String> nameList = new ArrayList(); 

    public SelectionPage(String id, String title, DataPassRegister dataPassRegister) {

        super(id, title, true);
        this.form = new Form<DataPassRegister>("selectionPageForm");

        final RadioGroup selectGroup = new RadioGroup("selectGroup");

        if(dataPassRegister.getNameList() != null){
            nameList = dataPassRegister.getNameList();
            System.out.println("In selection - In if condition - List : " + nameList.toString());
        }

        final ListView selectRepetor = new ListView("selectRepetor", nameList)
            {
            @Override
            protected void populateItem(final ListItem item)
            {
                final Radio radio = new Radio("selection", new Model(item.getModelObject().toString()));
                final Label label = new Label("name", new Model(item.getModelObject().toString()));
                item.add(radio);
                item.add(label);
            }
        };
        selectGroup.add(selectRepetor);

        this.feedback = new JQueryFeedbackPanel("feedback");

        this.form.add(selectGroup);
        this.form.add(this.feedback);
        this.add(this.form);
    }

    @Override
    public Form<?> getForm() {
        return this.form;
    }

    @Override
    public void setModelObject(DataPassRegister dataPassRegister)
    {
        this.setDefaultModel(new CompoundPropertyModel<DataPassRegister>(dataPassRegister));
    }

    @Override
    protected List<DialogButton> getButtons()
    {
        return Arrays.asList(this.btnSubmit, this.btnCancel);
    }

    @Override
    protected DialogButton getSubmitButton() {
        return this.btnSubmit;
    }

    @Override
    protected void onError(AjaxRequestTarget target) {
        target.add(this.feedback);
    }

    @Override
    protected void onSubmit(AjaxRequestTarget target) {

    }
}

How can I populate the radio group outside the constructor or under a condition (list not null) without causing wicket:id errors ? Please help. Any advice is most welcome.

Upvotes: 1

Views: 1809

Answers (2)

H. Saxena
H. Saxena

Reputation: 345

I finally got it working (with a lot of help from a friend).. I made the SelectionPage a Panel within the first page.. i.e. SelectionPage extends Panel

I created this function within it to re-populate the radio group based on the new list..

public void reloadList(DataPassRegister dataPassRegister) {

    this.form.remove("selectGroup");
    final RadioGroup selectGroup = new RadioGroup("selectGroup");

    selectGroup.setOutputMarkupId(true);
    selectGroup.setOutputMarkupPlaceholderTag(true);
    add(selectGroup);
    this.form.add(selectGroup);

    final ListView selectRepetor = new ListView("selectRepetor", dataPassRegister.getNameList())
        {
        @Override
        protected void populateItem(final ListItem item)
        {
            final Radio radio = new Radio("selection", new Model(item.getModelObject().toString()));
            final Label label = new Label("name", new Model(item.getModelObject().toString()));
            radio.setOutputMarkupId(true);
            radio.setOutputMarkupPlaceholderTag(true);
            item.add(radio);
            item.add(label);
            item.setOutputMarkupId(true);
            radio.add(new AjaxEventBehavior("onclick")
            {
                @Override
                protected void onEvent(AjaxRequestTarget target)
                {
                }
            });
        }
    };
    selectRepetor.setOutputMarkupId(true);
    selectRepetor.setOutputMarkupPlaceholderTag(true);
    selectGroup.add(selectRepetor);
}

Then on the first page, I added the following lines where I initialized the panel..

selectionPage.setOutputMarkupId(true);
selectionPage.setOutputMarkupPlaceholderTag(true);

This made sure that the panel will be mutable later on. Then finally, when I'm ready to populate the panel with a new list, I call the above function. i.e.

selectionPage.reloadList(dataPassRegister);
target.add(selectionPage);                  

feedback.error("");
target.add(feedback);

This allowed the panel to re-populate the radio group. However, as of now I have to add the feedback panel to ensure that the dialog doesn't close upon pressing submit.

Upvotes: 0

Mihir
Mihir

Reputation: 270

Updated with Code snippet

Page Mounted in App init() method - so 'instance' created

mountPage("radioOptionPage", TestTargetPage.class);

First Page - Java

    private void addFormComponent(Form<Void> form) {

    final FeedbackPanel panel = new FeedbackPanel("statusbarpanel");
    panel.setOutputMarkupId(true);
    form.add(panel);

    AjaxFallbackButton button = new AjaxFallbackButton("submitbtn", form) {
        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {

            PageParameters parameters = new PageParameters();
            for(int i = 0; i < 3; i++){
                String random = RandomStringUtils.random(4, true, true);
                parameters.add(random, random);
            }
            setResponsePage(TestTargetPage.class, parameters);
        }
    };
    form.add(button);
}

First Page - Markup

<body>
<form wicket:id="imageForm">
    <div wicket:id="statusbarpanel"></div>
    <input type="submit" wicket:id="submitbtn" value="Click Me !!!"/>

</form>
</body>

Second Page - Java

public class TestTargetPage extends WebPage {

private FormModel model = new FormModel();

public TestTargetPage(PageParameters parameters) {

    List<String> options = new ArrayList<String>();

    if (parameters != null){
        List<INamedParameters.NamedPair> allNamed = parameters.getAllNamed();
        for (INamedParameters.NamedPair pair : allNamed){
            options.add(pair.getValue());
        }

        model.setObject(options);
    }

    Form<Void> form = new Form<Void>("targetForm");
    RadioChoice<String> radiOptions = addRadioGroups("radio");
    form.add(radiOptions);

    add(form);
}

private RadioChoice<String> addRadioGroups(String wicketId) {
    List<String> radioOptions = model.getObject();
    RadioChoice<String> radioChoice =  new RadioChoice<String>(wicketId, radioOptions);

    radioChoice.setOutputMarkupId(true);

    return radioChoice;
}}

Second Page - Markup

<body>
<h1>Wicket RadioChoice Example</h1>

<form wicket:id="targetForm">
    <p>
        <label>Radio options :</label>
        <br />
        <span wicket:id="radio"></span>
    </p>
    <input type="submit" value="Display" />
</form>

</body>

If I am understanding correctly, all you want is radio group dynamically set on page load. In that case, you could have model object set for page, have that model object populated from previous page and set as default model object in target page from source page, and then redirect to that target page.

With default model object set for page, you should be able to set radio buttons as you want. The values for radio buttons would be from page's default model object.

Upvotes: 1

Related Questions