Wicket - How do I load / update reusable components correctly?

  • I have a java class:

    public Task {
    
        private int id;
        private Company sender;
        private Company receiver;
    
        //Getter and Setter
        ...
    }
    
          

    As you can see, I have 2 other custom classes in the task class. And the company has, for example, an address and a directory.

  • I have a CompanyPanel to be reused on a page. Here's the code on the panel.

    public class CompanyPanel extends Panel {
    
        protected List<Company> companies;
    
        public CompanyPanel(String id, IModel<Company> model) {
    
        super(id,new CompoundPropertyModel<Company>(model));
        companies = new ArrayList<Company>();
    
        Company company_1 = new Company();
            //Setting default predefined values for the company, so I can select it from the dropdown and to set fields automatically
    
        company_1.setFtpAdress("adress1.com");
        company_1.setFtpDir("/MusterDir/");
        companies.add(company_1);
    
        //SAME for another company
                ...
        companies.add(comany_2);
                ...
    
        final DropDownChoice<Company> companyList = new DropDownChoice<Company>("companies", model,
            new LoadableDetachableModel<List<Company>>() {
        @Override
        protected List<Company> load() { 
            return companies;
        }
        }){
            protected boolean wantOnSelectionChangedNotifications() {
            return true;
            }
        };
        add(companyList);
    
        final TextField<String> ftpAdress = new TextField<String>("ftpAdress");
        ftpAdress.setOutputMarkupId(true);
        add(ftpAdress);
    
        final TextField<String> ftpDir = new TextField<String>("ftpDir");
        ftpDir.setOutputMarkupId(true);
        add(ftpDir);
    
         //added Ajax to dropdown to update textfields automatically, based on selection of dropdown
        companyList.add(new AjaxFormComponentUpdatingBehavior("onchange")
        {
        @Override
        protected void onUpdate(AjaxRequestTarget target)
        {
            target.add(ftpAdress);
            target.add(ftpDir);
        }
        });
      }
    }
    
          

  • On the page, I am using reusable CompanyPanels.

    ...
    CompanyPanel senderPanel = new CompanyPanel("senderPanel", new PropertyModel(task,"sender"));
    senderPanel.setOutputMarkupId(true);
    form.add(senderPanel);
    
    CompanyPanel receiverPanel = new CompanyPanel("receiverPanel", new PropertyModel(task,"receiver"));
    receiverPanel.setOutputMarkupId(true);
    form.add(receiverPanel);
    ...
    
          

  • When I submit the form, I do:

    public void onSubmit(AjaxRequestTarget target, Form<?> form) {
    
        //doSomething
        target.add(senderPanel);
        target.add(receiverPanel);
    
    }
    
          

Problem: The company panel is not overwritten. And I do not know why.

Workflow:

  • I choose a company from the dropdown list
  • TextFields (which are inside companyPanel) will be set correctly based on the dropdown
  • I am modifying textField (which is company owned)
  • I am submitting a form
  • Change company from the drop-down list
  • I'll go back to the first company -> PROBLEM: the modified textboxes still display the modified text inside. It has not been reset to its defaults.

Any help is greatly appreciated.

+3


source to share


2 answers


They will of course reflect the changed values. You create a list of companies in the CompanyPanel constructor. When you change company data, the object changes within this list.

A quick way to fix this is to replace the CompanyPanel with a new CompanyPanel instance in the onSubmit method. This will recreate the list of companies with your default values. You will, of course, lose the changed values.

Another possible solution is to move the company listing creation into the loadabledetachable model:



final DropDownChoice<Company> companyList = new DropDownChoice<Company>("companies", model,
    new LoadableDetachableModel<List<Company>>() {
@Override
protected List<Company> load() { 
    List<Company>companies = new ArrayList<Company>();

    Company company_1 = new Company();
    //Setting default predefined values for the company, so I can select it from the dropdown and to set fields automatically

    company_1.setFtpAdress("adress1.com");
    company_1.setFtpDir("/MusterDir/");
    companies.add(company_1);

//SAME for another company
        ...
    companies.add(comany_2);
        ...

    return companies;
}

      

Thus, the list of companies is recreated for each query with default values.

Make sure you implement the correct equals () and hashCode () method in the company, although the correct selected item is shown for the DropDownChoice, because in this case the object in your model and the objects in the list will never be ==.

+3


source


You need to provide more code. If you post correctly so that the model changes try:



senderPanel.modelChanged();
receiverPanel.modelChanged();
target.add(senderPanel);
target.add(receiverPanel);

      

-1


source







All Articles