I've created a simpler version, this is as simple as I could make it
without requiring changes to select component.

http://wiki.apache.org/tapestry/Tapestry5HowtoSelectWithObjects

I belive that having objects in the list is a common case enough
so simplifying a task like this should be a goal later on in development....


Davor Hrg


On 9/5/07, Marcelo lotif <[EMAIL PROTECTED]> wrote:
>
> ok! thanks! works fine, i will update the wiki
>
> 2007/8/31, Davor Hrg <[EMAIL PROTECTED]>:
> >
> > If you like digging into tapestry I suggest you start
> > by removing beanutils dependancy and adding:
> >     @Inject
> >     private PropertyAccess propertyAccess;
> >
> > into SelectObject.java
> > after that use propertyAccess instead of beanutils...
> > ....
> >
> > I'm currently building a version that doesn't need
> > SelectObject component, but uses normal select component.
> > The code is more complicated than it should be, so I suppose
> > I might post an enhancement ticket for the Select component.
>
>
> for sure, this solution is way more complicated than it should be, but
> tapestry limit us too much in this point(as it does in the DatePicker
> too)... i hope there will be some better solution on the next release.
>
> ...
> > if you like to start with working code ...
> > here's the changed version that works for me ...
> >
> >
> >
> >
> >
> -------------------------------------------------------------------------------------------------------------------------------------------
> > package test.tapestry;
> >
> >
> > import java.lang.reflect.InvocationTargetException;
> > import java.util.ArrayList;
> > import java.util.List;
> >
> > import org.apache.tapestry.OptionGroupModel;
> > import org.apache.tapestry.OptionModel;
> > import org.apache.tapestry.internal.OptionModelImpl;
> > import org.apache.tapestry.ioc.services.PropertyAccess;
> > import org.apache.tapestry.ioc.services.PropertyAdapter;
> > import org.apache.tapestry.util.AbstractSelectModel;
> >
> > /**
> > * @author jued
> > *
> > * @param <T>
> > */
> > public class GenericSelectionModel<T> extends AbstractSelectModel {
> >
> >         private String labelField;
> >
> >         private List<T> list;
> >
> >         private final PropertyAccess adapter;
> >
> >         public GenericSelectionModel(List<T> list, String labelField,
> > PropertyAccess adapter) {
> >                 this.labelField = labelField;
> >                 this.list = list;
> >                 this.adapter = adapter;
> >         }
> >
> >         public List<OptionGroupModel> getOptionGroups() {
> >                 return null;
> >         }
> >
> >         public List<OptionModel> getOptions() {
> >                 List<OptionModel> optionModelList = new
> > ArrayList<OptionModel>();
> >                 for (T obj : list) {
> >                         if (labelField == null) {
> >                                 optionModelList.add(new
> > OptionModelImpl(obj
> > + "", false, obj, new String[0]));
> >                         } else {
> >                                 optionModelList.add(new OptionModelImpl(
> >                                                 adapter.get(obj,
> > labelField)+"", false, obj, new String[0]));
> >                         }
> >                 }
> >                 return optionModelList;
> >         }
> > }
> >
> >
> -------------------------------------------------------------------------------------------------------------------------------------------
> >
> >
> >
> >
> -------------------------------------------------------------------------------------------------------------------------------------------
> > package test.tapestry;
> >
> > import java.lang.reflect.InvocationTargetException;
> > import java.util.List;
> >
> > import org.apache.tapestry.ValueEncoder;
> > import org.apache.tapestry.ioc.services.PropertyAccess;
> > import org.apache.tapestry.ioc.services.PropertyAdapter;
> >
> > public class GenericValueEncoder<T> implements ValueEncoder<T> {
> >
> >         private List<T> list;
> >         private final PropertyAccess access;
> >         private final String fieldName;
> >
> >         public GenericValueEncoder(List<T> list, String fieldName,
> > PropertyAccess propertyAccess) {
> >                 this.list = list;
> >                 this.fieldName = fieldName;
> >                 this.access = propertyAccess;
> >         }
> >
> >         public String toClient(T obj) {
> >                 if (fieldName == null) {
> >                         return obj + "";
> >                 } else {
> >                         return access.get(obj,fieldName)+"";
> >                 }
> >         }
> >
> >         public T toValue(String string) {
> >                 for (T obj : list) {
> >                         if (fieldName == null) {
> >                                 if ((obj + "").equals(string)) {
> >                                         return obj;
> >                                 }
> >                         } else {
> >                                 if (access.get(obj,
> > fieldName).equals(string)) {
> >                                         return obj;
> >                                 }
> >                         }
> >                 }
> >                 return null;
> >         }
> > }
> >
> >
> -------------------------------------------------------------------------------------------------------------------------------------------
> >
> >
> >
> >
> >
> -------------------------------------------------------------------------------------------------------------------------------------------
> > package test.tapestry.components;
> >
> > import java.util.List;
> > import java.util.Locale;
> >
> > import org.apache.tapestry.Binding;
> > import org.apache.tapestry.ComponentResources;
> > import org.apache.tapestry.FieldValidator;
> > import org.apache.tapestry.MarkupWriter;
> > import org.apache.tapestry.OptionModel;
> > import org.apache.tapestry.SelectModel;
> > import org.apache.tapestry.SelectModelVisitor;
> > import org.apache.tapestry.ValidationException;
> > import org.apache.tapestry.ValidationTracker;
> > import org.apache.tapestry.ValueEncoder;
> > import org.apache.tapestry.annotations.BeforeRenderTemplate;
> > import org.apache.tapestry.annotations.Environmental;
> > import org.apache.tapestry.annotations.Inject;
> > import org.apache.tapestry.annotations.Parameter;
> > import org.apache.tapestry.corelib.base.AbstractField;
> > import org.apache.tapestry.internal.util.SelectModelRenderer;
> > import org.apache.tapestry.ioc.services.PropertyAccess;
> > import org.apache.tapestry.services.FieldValidatorDefaultSource;
> > import org.apache.tapestry.services.FormSupport;
> > import org.apache.tapestry.services.Request;
> > import org.apache.tapestry.services.ValueEncoderFactory;
> > import org.apache.tapestry.services.ValueEncoderSource;
> > import org.apache.tapestry.util.EnumSelectModel;
> >
> > import test.tapestry.GenericSelectionModel;
> > import test.tapestry.GenericValueEncoder;
> >
> > /**
> > * Select an item from a list of values, using an [X]HTML &lt;select&gt;
> > element on the client side.
> > * An validation decorations will go around the entire &lt;select&gt;
> > element.
> > * <p>
> > * A core part of this component is the [EMAIL PROTECTED] ValueEncoder} (the 
> > encoder
> > parameter) that is used to
> > * convert between server-side values and client-side strings. In many
> > cases, a [EMAIL PROTECTED] ValueEncoder}
> > * can be generated automatically from the type of the value parameter.
> The
> > * [EMAIL PROTECTED] ValueEncoderSource} service provides an encoder in these
> > situations; it can be overriden
> > * by binding the encoder parameter, or extended by contributing a [EMAIL 
> > PROTECTED]
> > ValueEncoderFactory} into
> > * the service's configuration.
> > */
> > public final class SelectObject extends AbstractField
> > {
> >     private class Renderer extends SelectModelRenderer
> >     {
> >
> >         public Renderer(MarkupWriter writer)
> >         {
> >             super(writer, _encoder);
> >         }
> >
> >         @Override
> >         protected boolean isOptionSelected(OptionModel optionModel)
> >         {
> >             Object value = optionModel.getValue();
> >
> >             return value == _value || (value != null && value.equals
> > (_value));
> >         }
> >     }
> >
> >     @Inject
> >     private FieldValidatorDefaultSource _fieldValidatorDefaultSource;
> >
> >     @Inject
> >     private Locale _locale;
> >
> >     @Inject
> >     private PropertyAccess propertyAccess;
> >
> >     @Parameter(required = true)
> >     private List<Object> _list;
> >
> >     @Parameter
> >     private String _labelField = null;
> >
> >     // Maybe this should default to property "<componentId>Model"?
> >     /**
> >      * The model used to identify the option groups and options to be
> > presented to the user. This
> >      * can be generated automatically for Enum types.
> >      */
> > //    @Parameter(required = true)
> > //    private SelectModel _model;
> >
> >     private GenericSelectionModel<Object> _model;
> >
> >     /**
> >      * Allows a specific implementation of [EMAIL PROTECTED] ValueEncoder} 
> > to be
> > supplied. This is used to
> >      * create client-side string values for the different options.
> >      *
> >      * @see ValueEncoderSource
> >      */
> > //    @Parameter
> > //    private ValueEncoder _encoder;
> >
> >     private GenericValueEncoder<Object> _encoder;
> >
> >     @Inject
> >     private Request _request;
> >
> >     @Inject
> >     private ComponentResources _resources;
> >
> >     @Environmental
> >     private ValidationTracker _tracker;
> >
> >     /** Performs input validation on the value supplied by the user in
> the
> > form submission. */
> >     @Parameter(defaultPrefix = "validate")
> >     @SuppressWarnings("unchecked")
> >     private FieldValidator<Object> _validate = NOOP_VALIDATOR;
> >
> >     /** The value to read or update. */
> >     @Parameter(required = true, principal = true)
> >     private Object _value;
> >
> >     @Inject
> >     private ValueEncoderSource _valueEncoderSource;
> >
> >     @Override
> >     protected void processSubmission(FormSupport formSupport, String
> > elementName)
> >     {
> >         _encoder = new GenericValueEncoder<Object>(_list, _labelField,
> > propertyAccess);
> >
> >         String primaryKey = _request.getParameter(elementName);
> >
> >         Object selectedValue = _encoder.toValue(primaryKey);
> >
> >         try
> >         {
> >             _validate.validate(selectedValue);
> >
> >             _value = selectedValue;
> >         }
> >         catch (ValidationException ex)
> >         {
> >             _tracker.recordError(this, ex.getMessage());
> >             return;
> >         }
> >     }
> >
> >     void afterRender(MarkupWriter writer)
> >     {
> >         writer.end();
> >     }
> >
> >     void beginRender(MarkupWriter writer)
> >     {
> >         writer.element("select", "name", getElementName(), "id",
> > getClientId());
> >         _encoder = new GenericValueEncoder<Object>(_list, _labelField,
> > propertyAccess);
> >         _model = new GenericSelectionModel<Object>(_list, _labelField,
> > propertyAccess);
> >         // Disabled, informals via mixins
> >     }
> >
> >     @SuppressWarnings("unchecked")
> >     ValueEncoder defaultEncoder()
> >     {
> >         return _valueEncoderSource.createEncoder("value", _resources);
> >     }
> >
> >     @SuppressWarnings("unchecked")
> >     SelectModel defaultModel()
> >     {
> >         Class valueType = _resources.getBoundType("value");
> >
> >         if (valueType == null) return null;
> >
> >         if (Enum.class.isAssignableFrom(valueType))
> >             return new EnumSelectModel(valueType,
> > _resources.getContainerMessages());
> >
> >         return null;
> >     }
> >
> >     /**
> >      * Computes a default value for the "validate" parameter using
> >      * [EMAIL PROTECTED] FieldValidatorDefaultSource}.
> >      */
> >     FieldValidator defaultValidate()
> >     {
> >         Class type = _resources.getBoundType("value");
> >
> >         if (type == null) return null;
> >
> >         return _fieldValidatorDefaultSource.createDefaultValidator(
> >                 this,
> >                 _resources.getId(),
> >                 _resources.getContainerMessages(),
> >                 _locale,
> >                 type,
> >                 _resources.getAnnotationProvider("value"));
> >     }
> >
> >     Binding defaultValue()
> >     {
> >         return createDefaultParameterBinding("value");
> >     }
> >
> >     @BeforeRenderTemplate
> >     void options(MarkupWriter writer)
> >     {
> >         SelectModelVisitor renderer = new Renderer(writer);
> >
> >         _model.visit(renderer);
> >     }
> >
> >     // For testing.
> >
> >     void setModel(GenericSelectionModel model)
> >     {
> >         _model = model;
> >     }
> >
> >     void setValue(Object value)
> >     {
> >         _value = value;
> >     }
> >
> >     void setValueEncoder(GenericValueEncoder encoder)
> >     {
> >         _encoder = encoder;
> >     }
> > }
> >
> >
> -------------------------------------------------------------------------------------------------------------------------------------------
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > On 8/29/07, Marcelo lotif <[EMAIL PROTECTED]> wrote:
> > >
> > > Hi Davor,
> > > Can you send it to me?
> > >
> > > 2007/8/29, Davor Hrg <[EMAIL PROTECTED]>:
> > > >
> > > > thnx,
> > > > very nice example,
> > > >
> > > > I've liked it and modified it to use Tapestry builtin service:
> > > > PropertyAccess
> > > > instead of beanutils. If you like I can update the wiki..
> > > >
> > > > Davor Hrg
> > > >
> > > > On 8/28/07, Marcelo lotif <[EMAIL PROTECTED]> wrote:
> > > > >
> > > > > http://wiki.apache.org/tapestry/Tapestry5SelectObject
> > > > >
> > > > > --
> > > > > Atenciosamente,
> > > > > Marcelo Lotif
> > > > >
> > > >
> > >
> > >
> > >
> > > --
> > > Atenciosamente,
> > > Marcelo Lotif
> > >
> >
>
>
>
> --
> Atenciosamente,
> Marcelo Lotif
>

Reply via email to