Wicket - How to reload/refresh reusable components correctly?

18,084

Of course they will display the modified values. You create a list of companies in the CompanyPanel constructor. When you modify a company's data, the object is modified inside that list.

A quick way to fix this would be to replace the CompanyPanel panel with a new instance of CompanyPanel in your onSubmit method. That would recreate the list of companies with your default values. You would of course lose the modified values.

Another possibly better fix is to move the companies list creation into the loadabledetachablemodel:

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;
}

This way the list of companies is recreated on every request with the default values.

Make sure you implement a proper equals() and hashCode() method in Company though for DropDownChoice to show the proper selected element though - because in this scenario the object in your model and the objects in the list may never be ==.

Share:
18,084

Related videos on Youtube

David Sonnenfeld
Author by

David Sonnenfeld

Updated on June 04, 2022

Comments

  • David Sonnenfeld
    David Sonnenfeld almost 2 years
    1. 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 a company has for example Adress and Directory.

    2. I have a CompanyPanel which will reusable be used on the Page. Here is some code from 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);
          }
          });
        }
      }
      
    3. In the Page I use reuseable 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);
      ...
      
    4. When I submit the form I do:

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

    The problem: The company panel is not being rerendered. And I don't really know why.

    Workflow:

    1. I select a company from the dropdown panel
    2. The TextFields(which are inside the companyPanel) will be set correctly, based on the dropdown
    3. I modify a textField (which belongs to a company)
    4. I submit the form
    5. I change the company from the dropdown list
    6. I change back to the first company -> PROBLEM: the modified textfields displays still the modified text inside. It was not reseted to the default values.

    Any help very appreciated.

    • Christoph Leiter
      Christoph Leiter about 11 years
      What do you do in CompanyPanel?
  • David Sonnenfeld
    David Sonnenfeld about 11 years
    Thank you. That worked! Btw, how do you know that kind of principles? Are you good at Wicket Models, or is it just java experience?
  • cserepj
    cserepj about 11 years
    I've been working with wicket since 2006 on several major projects. Grasping model concepts is part of the learning curve.