2007/9/5, Davor Hrg <[EMAIL PROTECTED]>: > > 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 a saw and found it interesting, good solution 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.... i hope so :) 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 > <select> > > > element on the client side. > > > * An validation decorations will go around the entire <select> > > > 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 > > > -- Atenciosamente, Marcelo Lotif