You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Martin Dietze <di...@fh-wedel.de> on 2007/05/31 11:19:32 UTC

T5: select using a wrapped enum

Hi,

 I created a selectmodel based on a enum wrapped by a generic
wrapper and using a generic value encoder.

By this I intend to simplify creating select inputs consisting of
something like "please select" and "----" followed by the enum's
entries which are the only valid inputs for the select.

The code seems to work well, I the select options are created
properly and show up in the form, also selected values are 
delivered after submit. However when rendering the result page
the previously submitted option is not selected.

I wonder whether my code is not OK or do I have to insert some
code on my own to get the last choice selected in the result
page?

Cheers,

Martin

<----------------------- snip ------------------------->

Here is my code:

The selectmodel:

|  public final class SalutationSelectModel extends AbstractSelectModel {
|  private final Messages _msgs;
|
|  public SalutationSelectModel(final Messages msgs) {
|    _msgs = msgs;
|  }
|
|  public List<OptionGroupModel> getOptionGroups() {
|    return null;
|  }
|  public List<OptionModel> getOptions() {
|    final List<OptionModel> result = new ArrayList<OptionModel>();
|
|    // Add "please select..." entry and disabled "------"...
|    result.add(new OptionModelImpl(_msgs.get("select_pleaseSelect"),
|      false, null, new String[0]));
|    result.add(new OptionModelImpl(_msgs.get( "select_separator"),
|      true, new CommonSelectView<Salutation>(null), new String[0]));
|
|    for(Salutation salut : Salutation.values()) {
|      result.add(new OptionModelImpl(_msgs.get("salutation_" + salut.name()),
|      false, new CommonSelectView<Salutation>(salut), new String[0]));
|    }
|
|    return result;
|  }
|}

The enum:

| public enum Salutation {
|   MR,
|   MRS;
| }

The generic enum wrapper:

| public class CommonSelectView<M> {
|   private final M _model;
|   public CommonSelectView(M model) {
|     _model = model;
|   }
|   public M getModel() {
|     return _model;
|   }
| }

The generic value encoder lets me differenciate between
invalid inputs (like "please select") and disabled ones so
that I do not get more than one selected="selected" when
the page is displayed for the first time:

| ValueEncoder<M extends Enum<M>> implements ValueEncoder<CommonSelectView<M>> {
|     
|   private Class<M> _cls;
|   public CommonValueEncoder(Class<M> cls) {
|     _cls = cls;
|   }
|     
|   public String toClient(CommonSelectView<M> value) {
|     if (value == null) {
|       return "null";
|     } else if (value.getModel() == null) {
|         return "disabled";
|     }
|     return value.getModel().name();
|   }
| 
|   public CommonSelectView<M> toValue(String clientValue) {
|     if ("null".equals( clientValue) || "disabled".equals(clientValue)) {
|       return null;
|     }
|     M m = Enum.valueOf(_cls, clientValue);
|     return new CommonSelectView<M>(m);
|   }
| }

All this is used in this page class:

| public class CreatePartner {
|   @Inject
|   private Messages _messages;
|   @Component
|   private Form _form;
|   @Persist
|   private CommonSelectView<Salutation> _contactSalutation;
|     
|   private static ValueEncoder<CommonSelectView<Salutation>>
|     _salutationValueEncoder = new CommonValueEncoder<Salutation>(Salutation.class);
|   private SelectModel _salutationModel;
|     
|   public CreatePartner() {
|     _salutationModel = new SalutationSelectModel( _messages );
|   }
| 
|   @OnEvent(value="submit")
|   public void submit() {
|     _form.recordError("Submit received: "
|       + (_contactSalutation != null? _contactSalutation.getModel() : "null"));
|   }
| 
|   public SelectModel getSalutationModel() {
|     return _salutationModel;
|   }
| 
|   public ValueEncoder<CommonSelectView<Salutation>> getSalutationValueEncoder() {
|     return _salutationValueEncoder;
|   }
|     
| 
|   public CommonSelectView<Salutation> getContactSalutation() {
|     return _contactSalutation;
|   }
| 
|   public void setContactSalutation(CommonSelectView<Salutation> contactSalutation) {
|     _contactSalutation = contactSalutation;
|   }
| 
| }

Finally, in the form I have this entry for the select:

| <select name="salutation" id="salutation" tabindex="10"
|   t:type="select"
|   t:id="salutation"
|   t:encoder="salutationValueEncoder"
|   t:model="salutationModel"
|   t:validate="required"
|   t:value="contactSalutation"
|   >
|   <option selected="selected">bitte wählen...</option>
|   <option disabled="disabled">---------------</option>
|   <option>Herr</option>
|   <option>Frau</option>
| </select>

-- 
----------- / http://herbert.the-little-red-haired-girl.org / -------------
=+= 
* Free Speech Online!!! Support the Blue Ribbon Campaign! *

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


Re: T5: select using a wrapped enum

Posted by Howard Lewis Ship <hl...@gmail.com>.
I meant OptionGroups for the non-selectable labels.  Make the HTML browser
do the work for you.  It actually looks nice, with the items indented
beneath the matching labels.  The indentation means you probably don't need
the row of dashes.

On 5/31/07, Martin Dietze <di...@fh-wedel.de> wrote:
>
> On Thu, May 31, 2007, Howard Lewis Ship wrote:
>
> > Have you considered using OptionGroups as the labels?
>
> To me it seemed that if I have to create a number of selects
> with similar structure, just plugging in the appropriate enum
> might actually be an elegant solution.
>
> Do you seen anything wrong with the way I implemented this?
>
> Cheers,
>
> Martin
>
> --
> ----------- / http://herbert.the-little-red-haired-girl.org /
> -------------
> =+=
> - Are you attempting to tell me my duty, sir?
> - No. Just having fun trying to guess what they are.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>


-- 
Howard M. Lewis Ship
TWD Consulting, Inc.
Independent J2EE / Open-Source Java Consultant
Creator and PMC Chair, Apache Tapestry
Creator, Apache HiveMind

Professional Tapestry training, mentoring, support
and project work.  http://howardlewisship.com

Re: T5: select using a wrapped enum

Posted by Martin Dietze <di...@fh-wedel.de>.
On Thu, May 31, 2007, Howard Lewis Ship wrote:

> Have you considered using OptionGroups as the labels?

To me it seemed that if I have to create a number of selects
with similar structure, just plugging in the appropriate enum
might actually be an elegant solution. 

Do you seen anything wrong with the way I implemented this?

Cheers,

Martin

-- 
----------- / http://herbert.the-little-red-haired-girl.org / -------------
=+= 
- Are you attempting to tell me my duty, sir?
- No. Just having fun trying to guess what they are.

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


Re: T5: select using a wrapped enum

Posted by Howard Lewis Ship <hl...@gmail.com>.
Have you considered using OptionGroups as the labels?

On 5/31/07, Martin Dietze <di...@fh-wedel.de> wrote:
>
> Hi,
>
> I created a selectmodel based on a enum wrapped by a generic
> wrapper and using a generic value encoder.
>
> By this I intend to simplify creating select inputs consisting of
> something like "please select" and "----" followed by the enum's
> entries which are the only valid inputs for the select.
>
> The code seems to work well, I the select options are created
> properly and show up in the form, also selected values are
> delivered after submit. However when rendering the result page
> the previously submitted option is not selected.
>
> I wonder whether my code is not OK or do I have to insert some
> code on my own to get the last choice selected in the result
> page?
>
> Cheers,
>
> Martin
>
> <----------------------- snip ------------------------->
>
> Here is my code:
>
> The selectmodel:
>
> |  public final class SalutationSelectModel extends AbstractSelectModel {
> |  private final Messages _msgs;
> |
> |  public SalutationSelectModel(final Messages msgs) {
> |    _msgs = msgs;
> |  }
> |
> |  public List<OptionGroupModel> getOptionGroups() {
> |    return null;
> |  }
> |  public List<OptionModel> getOptions() {
> |    final List<OptionModel> result = new ArrayList<OptionModel>();
> |
> |    // Add "please select..." entry and disabled "------"...
> |    result.add(new OptionModelImpl(_msgs.get("select_pleaseSelect"),
> |      false, null, new String[0]));
> |    result.add(new OptionModelImpl(_msgs.get( "select_separator"),
> |      true, new CommonSelectView<Salutation>(null), new String[0]));
> |
> |    for(Salutation salut : Salutation.values()) {
> |      result.add(new OptionModelImpl(_msgs.get("salutation_" + salut.name
> ()),
> |      false, new CommonSelectView<Salutation>(salut), new String[0]));
> |    }
> |
> |    return result;
> |  }
> |}
>
> The enum:
>
> | public enum Salutation {
> |   MR,
> |   MRS;
> | }
>
> The generic enum wrapper:
>
> | public class CommonSelectView<M> {
> |   private final M _model;
> |   public CommonSelectView(M model) {
> |     _model = model;
> |   }
> |   public M getModel() {
> |     return _model;
> |   }
> | }
>
> The generic value encoder lets me differenciate between
> invalid inputs (like "please select") and disabled ones so
> that I do not get more than one selected="selected" when
> the page is displayed for the first time:
>
> | ValueEncoder<M extends Enum<M>> implements
> ValueEncoder<CommonSelectView<M>> {
> |
> |   private Class<M> _cls;
> |   public CommonValueEncoder(Class<M> cls) {
> |     _cls = cls;
> |   }
> |
> |   public String toClient(CommonSelectView<M> value) {
> |     if (value == null) {
> |       return "null";
> |     } else if (value.getModel() == null) {
> |         return "disabled";
> |     }
> |     return value.getModel().name();
> |   }
> |
> |   public CommonSelectView<M> toValue(String clientValue) {
> |     if ("null".equals( clientValue) || "disabled".equals(clientValue)) {
> |       return null;
> |     }
> |     M m = Enum.valueOf(_cls, clientValue);
> |     return new CommonSelectView<M>(m);
> |   }
> | }
>
> All this is used in this page class:
>
> | public class CreatePartner {
> |   @Inject
> |   private Messages _messages;
> |   @Component
> |   private Form _form;
> |   @Persist
> |   private CommonSelectView<Salutation> _contactSalutation;
> |
> |   private static ValueEncoder<CommonSelectView<Salutation>>
> |     _salutationValueEncoder = new CommonValueEncoder<Salutation>(
> Salutation.class);
> |   private SelectModel _salutationModel;
> |
> |   public CreatePartner() {
> |     _salutationModel = new SalutationSelectModel( _messages );
> |   }
> |
> |   @OnEvent(value="submit")
> |   public void submit() {
> |     _form.recordError("Submit received: "
> |       + (_contactSalutation != null? _contactSalutation.getModel() :
> "null"));
> |   }
> |
> |   public SelectModel getSalutationModel() {
> |     return _salutationModel;
> |   }
> |
> |   public ValueEncoder<CommonSelectView<Salutation>>
> getSalutationValueEncoder() {
> |     return _salutationValueEncoder;
> |   }
> |
> |
> |   public CommonSelectView<Salutation> getContactSalutation() {
> |     return _contactSalutation;
> |   }
> |
> |   public void setContactSalutation(CommonSelectView<Salutation>
> contactSalutation) {
> |     _contactSalutation = contactSalutation;
> |   }
> |
> | }
>
> Finally, in the form I have this entry for the select:
>
> | <select name="salutation" id="salutation" tabindex="10"
> |   t:type="select"
> |   t:id="salutation"
> |   t:encoder="salutationValueEncoder"
> |   t:model="salutationModel"
> |   t:validate="required"
> |   t:value="contactSalutation"
> |   >
> |   <option selected="selected">bitte wählen...</option>
> |   <option disabled="disabled">---------------</option>
> |   <option>Herr</option>
> |   <option>Frau</option>
> | </select>
>
> --
> ----------- / http://herbert.the-little-red-haired-girl.org /
> -------------
> =+=
> * Free Speech Online!!! Support the Blue Ribbon Campaign! *
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>


-- 
Howard M. Lewis Ship
TWD Consulting, Inc.
Independent J2EE / Open-Source Java Consultant
Creator and PMC Chair, Apache Tapestry
Creator, Apache HiveMind

Professional Tapestry training, mentoring, support
and project work.  http://howardlewisship.com