You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Olivier Croisier <ol...@gmail.com> on 2011/01/20 12:45:09 UTC

FormComponentPanel and CompoundPropertyModels

Hi,

After searching unsuccessfully through the ML archive, I come here to seek
some advice on FormComponentPanels (FCP).

What I want to do is build a small, reusable form component that lets me
edit an Address (address, zipCode, city, country).
I know  that FCP are usually used as a bridge between an external model and
a set of individual components ; but in my case, the internal and external
models are the same.

Below is my current code (adapted from Wicket In Action) ; as you can see,
it is very verbose and redundant.


public class AddressField extends FormComponentPanel<Address> {
>
>     private Address address = new Address();
>     private TextField<String> address1;
>     private TextField<String> address2;
>     private TextField<String> zipCode;
>     private TextField<String> city;
>     private CountryCodeDropDownChoice countryCode;
>
>     public AddressField(String id) {
>         super(id);
>     }
>
>     public AddressField(String id, IModel<Address> model) {
>         super(id, model);
>     }
>
>     // Constructor block
>     {
>         add(address1 = new TextField<String>("address1", new
> PropertyModel<String>(address,"address1")));
>         add(address2 = new TextField<String>("address2", new
> PropertyModel<String>(address, "address2")));
>         add(zipCode = new TextField<String>("zipCode", new
> PropertyModel<String>(address, "zipCode")));
>         add(city = new TextField<String>("city", new
> PropertyModel<String>(address, "city")));
>         add((countryCode = new CountryCodeDropDownChoice("countryCode", new
> PropertyModel<String>(address, "countryCode"))).setRequired(true));
>     }
>
>     @Override
>     protected void onBeforeRender() {
>         Address modelAddress = getModelObject();
>         if (modelAddress != null) {
>             address.setAddress1(modelAddress.getAddress1());
>             address.setAddress2(modelAddress.getAddress2());
>             address.setZipCode(modelAddress.getZipCode());
>             address.setCity(modelAddress.getCity());
>             address.setCountryCode(modelAddress.getCountryCode());
>         }
>         if (address.getCountryCode() == null) {
>             address.setCountryCode(CountryUtils.CODE_FRANCE);
>         }
>         super.onBeforeRender();
>     }
>
>     @Override
>     protected void convertInput() {
>         address.setAddress1(address1.getConvertedInput());
>         address.setAddress2(address2.getConvertedInput());
>         address.setZipCode(zipCode.getConvertedInput());
>         address.setCity(city.getConvertedInput());
>         address.setCountryCode(countryCode.getConvertedInput());
>         setConvertedInput(address);
>     }
> }
>


What I would like to achieve is something like this, using a
CompoundPropertyModel :

public class AddressField extends FormComponentPanel<Address> {
>
>     public AddressField(String id) {
>         this(id, null);
>     }
>
>     public AddressField(String id, IModel<Address> model) {
>         super(id, new *CompoundPropertyModel*<Address>(model));
>     }
>
>     // Constructor block
>     {
>         add(new TextField<String>("address1"));
>         add(new TextField<String>("address2"));
>         add(new TextField<String>("zipCode"));
>         add(new TextField<String>("city"));
>         add(new
> CountryCodeDropDownChoice("countryCode").setRequired(true));
>     }
> }
>


But I cannot figure out how to make it work properly (sometimes Wicket tells
me that it cannot find a getter, sometimes that it cannot bind to a null
model...). I must have missed something obvious ?
Thank you for you help !

Olivier

Re: FormComponentPanel and CompoundPropertyModels

Posted by Olivier Croisier <ol...@gmail.com>.
When I use the second solution I gave above, the data I enter in the form is
not saved to the model, and I don't understand why...
I also tried to override convertInput() - still does not work

    protected void convertInput() {
>         setConvertedInput(getModelObject());
>     }
>



For info, here is how the AddressField is used :

private class CompanyForm extends Form<Company> {
>
>     public CompanyForm(String wicketId, IModel<Company> model) {
>         super(wicketId, new CompoundPropertyModel<Company>(model));
>         add(new TextField<String>("name"));
>         add(new AddressField("address"));
>         ...
>     }
> }
>

With :

public class Company {
>     private Address address = new Address();
> }
>
> public class Address {
>     private String address1;
>     private String address2;
>     private String zipCode;
>     private String city;
>     private String countryCode;
> }
>

Re: FormComponentPanel and CompoundPropertyModels

Posted by Jan Ferko <ju...@gmail.com>.
Hi,

id of your TextFields should match name of property in Address model.

something like that..

public class Address {
     private String address1;
     private String address2;
     private String city;

     //getters
     public String getAddress1(){}

     ...
}

Jan Ferko

On 01/20/2011 12:45 PM, Olivier Croisier wrote:
> Hi,
>
> After searching unsuccessfully through the ML archive, I come here to seek
> some advice on FormComponentPanels (FCP).
>
> What I want to do is build a small, reusable form component that lets me
> edit an Address (address, zipCode, city, country).
> I know  that FCP are usually used as a bridge between an external model and
> a set of individual components ; but in my case, the internal and external
> models are the same.
>
> Below is my current code (adapted from Wicket In Action) ; as you can see,
> it is very verbose and redundant.
>
>
> public class AddressField extends FormComponentPanel<Address>  {
>>      private Address address = new Address();
>>      private TextField<String>  address1;
>>      private TextField<String>  address2;
>>      private TextField<String>  zipCode;
>>      private TextField<String>  city;
>>      private CountryCodeDropDownChoice countryCode;
>>
>>      public AddressField(String id) {
>>          super(id);
>>      }
>>
>>      public AddressField(String id, IModel<Address>  model) {
>>          super(id, model);
>>      }
>>
>>      // Constructor block
>>      {
>>          add(address1 = new TextField<String>("address1", new
>> PropertyModel<String>(address,"address1")));
>>          add(address2 = new TextField<String>("address2", new
>> PropertyModel<String>(address, "address2")));
>>          add(zipCode = new TextField<String>("zipCode", new
>> PropertyModel<String>(address, "zipCode")));
>>          add(city = new TextField<String>("city", new
>> PropertyModel<String>(address, "city")));
>>          add((countryCode = new CountryCodeDropDownChoice("countryCode", new
>> PropertyModel<String>(address, "countryCode"))).setRequired(true));
>>      }
>>
>>      @Override
>>      protected void onBeforeRender() {
>>          Address modelAddress = getModelObject();
>>          if (modelAddress != null) {
>>              address.setAddress1(modelAddress.getAddress1());
>>              address.setAddress2(modelAddress.getAddress2());
>>              address.setZipCode(modelAddress.getZipCode());
>>              address.setCity(modelAddress.getCity());
>>              address.setCountryCode(modelAddress.getCountryCode());
>>          }
>>          if (address.getCountryCode() == null) {
>>              address.setCountryCode(CountryUtils.CODE_FRANCE);
>>          }
>>          super.onBeforeRender();
>>      }
>>
>>      @Override
>>      protected void convertInput() {
>>          address.setAddress1(address1.getConvertedInput());
>>          address.setAddress2(address2.getConvertedInput());
>>          address.setZipCode(zipCode.getConvertedInput());
>>          address.setCity(city.getConvertedInput());
>>          address.setCountryCode(countryCode.getConvertedInput());
>>          setConvertedInput(address);
>>      }
>> }
>>
>
> What I would like to achieve is something like this, using a
> CompoundPropertyModel :
>
> public class AddressField extends FormComponentPanel<Address>  {
>>      public AddressField(String id) {
>>          this(id, null);
>>      }
>>
>>      public AddressField(String id, IModel<Address>  model) {
>>          super(id, new *CompoundPropertyModel*<Address>(model));
>>      }
>>
>>      // Constructor block
>>      {
>>          add(new TextField<String>("address1"));
>>          add(new TextField<String>("address2"));
>>          add(new TextField<String>("zipCode"));
>>          add(new TextField<String>("city"));
>>          add(new
>> CountryCodeDropDownChoice("countryCode").setRequired(true));
>>      }
>> }
>>
>
> But I cannot figure out how to make it work properly (sometimes Wicket tells
> me that it cannot find a getter, sometimes that it cannot bind to a null
> model...). I must have missed something obvious ?
> Thank you for you help !
>
> Olivier
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org