org.apache.tapestry5.corelib.components

## Class Select

- java.lang.Object
- - org.apache.tapestry5.corelib.base.AbstractField
  - - org.apache.tapestry5.corelib.components.Select

- All Implemented Interfaces:
    ClientElement, Field

      @Events(value={"validate","valueChanged when \'zone\' parameter is bound"})
      public class Select
      extends AbstractField

  Select an item from a list of values, using an [X]HTML <select> element on the client side. Any validation decorations will go around the entire <select> element. A core part of this component is the `ValueEncoder` (the encoder parameter) that is used to convert between server-side values and unique client-side strings. In some cases, a `ValueEncoder` can be generated automatically from the type of the value parameter. The `ValueEncoderSource` service provides an encoder in these situations; it can be overridden by binding the encoder parameter, or extended by contributing a `ValueEncoderFactory` into the service's configuration.

  Component Parameters
  Name | Type | Flags | Default | Default Prefix
  --- | --- | --- | --- | ---
  blankLabel | String |  |  | literal
  The label to use for the blank option, if rendered. If not specified, the container's message catalog is searched for a key, `id-blanklabel`.
  blankOption | org.apache.tapestry5.corelib.data.BlankOption |  | auto | literal
  Controls whether an additional blank option is provided. The blank option precedes all other options and is never selected. The value for the blank option is always the empty string, the label may be the blank string; the label is from the blankLabel parameter (and is often also the empty string).
  clientId | String |  |  | literal
  Used to explicitly set the client-side id of the element for this component. Normally this is not bound (or null) and org.apache.tapestry5.services.javascript.JavaScriptSupport#allocateClientId(org.apache.tapestry5.ComponentResources) is used to generate a unique client-id based on the component's id. In some cases, when creating client-side behaviors, it is useful to explicitly set a unique id for an element using this parameter. Certain values, such as "submit", "method", "reset", etc., will cause client-side conflicts and are not allowed; using such will cause a runtime exception.
  context | Object | Since 5.4 |  | prop
  The context for the "valueChanged" event triggered by this component (optional parameter). This list of values will be converted into strings and included in the URI. The strings will be coerced back to whatever their values are and made available to event handler methods. The first parameter of the context passed to "valueChanged" event handlers will still be the selected value chosen by the user, so the context passed through this parameter will be added from the second position on.
  encoder | org.apache.tapestry5.ValueEncoder |  |  | prop
  A ValueEncoder used to convert the server-side object provided by the "value" parameter into a unique client-side string (typically an ID) and back. Note: this parameter may be OMITTED if Tapestry is configured to provide a ValueEncoder automatically for the type of property bound to the "value" parameter.
  ensureClientIdUnique | boolean | Since 5.4 |  | prop
  A rarely used option that indicates that the actual client id should start with the clientId parameter (if non-null) but should still pass that Id through org.apache.tapestry5.services.javascript.JavaScriptSupport#allocateClientId(String) to generate the final id. An example of this are the components used inside a org.apache.tapestry5.corelib.components.BeanEditor which will specify a clientId (based on the property name) but still require that it be unique. Defaults to false.
  model | org.apache.tapestry5.SelectModel | Required, Not Null |  | prop
  The model used to identify the option groups and options to be presented to the user. This can be generated automatically for Enum types.
  raw | boolean | Since 5.4 | false | prop
  If true, then the provided org.apache.tapestry5.SelectModel labels will be written raw (no escaping of embedded HTML entities); it becomes the callers responsibility to escape any such entities.
  secure | org.apache.tapestry5.corelib.data.SecureOption | Since 5.4 | symbol:tapestry.components.validate_with_model | literal
  Controls whether the submitted value is validated to be one of the values in the org.apache.tapestry5.SelectModel. If "never", then no such validation is performed, theoretically allowing a selection to be made that was not presented to the user. Note that an "always" value here requires the SelectModel to still exist (or be created again) when the form is submitted, whereas a "never" value does not. Defaults to "auto", which causes the validation to occur only if the SelectModel is present (not null) when the form is submitted.
  validate | org.apache.tapestry5.FieldValidator |  |  | validate
  Performs input validation on the value supplied by the user in the form submission.
  value | Object | Required |  | prop
  The value to read or update.
  zone | String | Since 5.2.0 |  | literal
  Binding the zone parameter will cause any change of Select's value to be handled as an Ajax request that updates the indicated zone. The component will trigger the event org.apache.tapestry5.EventConstants#VALUE_CHANGED to inform its container that Select's value has changed.

  Component Events
  Name | Description
  --- | ---
  validate |
  valueChanged | when 'zone' parameter is bound

  ### Simple Example

    A simple example, selecting one of three strings:

    ### SelectColor.tml

        <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
            <body>
                <h1>Select Color</h1>

                <t:form>

                    <t:label for="color"/>:
                    <t:select t:id="color" model="literal:Red,Green,Blue"/>

                    <br/>

                    <input type="submit" value="Continue"/>
                </t:form>

            </body>
        </html>

    When the model parameter is a string, it is split apart at the commas. When the model parameter is a List of Strings, each element is considered a selection option.

    When using this approach, you'll commonly put the list into the message catalog, and reference it using a "message:" binding.

    Here the label displayed to the user is the same as the value used to update the property, but that doesn't have to be the case. By specifying a value and a label, we can control the server side value without changing how the UI appears to the user:

                    <t:select t:id="color" model="literal:FF0000=Red,00FF00=Green,0000FF=Blue"/>

    ### SelectColor.java

        public class SelectColor
        {
          @Validate("required")
          public String color;

        }

    Placing the @Validate annotation on the field supplies the default validation for this field, here it indicates that color is required. This prevents the Select component from including a blank option for the field (though this behavior too can be overridden). Without the @Validate, it would be possible for the user to select a blank value, and null would be assigned to the color property of SelectColor. This might be appropriate for a search form, but not for an edit form.

  ### Enum Example

    Working with Enums is, amazingly, even easier (and more so than with the Radio component).

    Most of this example is the same as for the Radio component, except that we're using a single Select component instead of multiple Radio components:

    ### CardType.java

        public enum CardType
        {
            MASTER_CARD, VISA, AMERICAN_EXPRESS, DINERS_CLUB, DISCOVER
        }

    ### Payment.tml (partial)

    In the Radio example, we used a Label and a Radio component for each enum value. With Select we use a single Label and a single Select component:

            <t:label for="type"/>:
            <t:select t:id="type"/>

    Here again, Tapestry is binding the value parameter to the type property, based on the component's id. In addition, because the property type of the property in question is an enum, a SelectModel is automatically generated.

    ### Payment.java (partial)

        public class Payment
        {
            . . .

            @Property
            @Persist
            @Validate("required")
            private CardType type;

            . . .
        }

    ### Payment.properties

    Once again, we need to slightly customize Tapestry's guess at the label for the enum value DINERS_CLUB. In the Radio example, we overrode the label for the dinersClubcomponent. Here there is just the Select component, but we still have an option: override how the DINERS_CLUB enum value is displayed:

        DINERS_CLUB=Diner's Club

    Tapestry looks inside a component's message catalog for entries before "humanizing" the name. In the very rare event that there's a naming conflict, you may qualify the enum value with its class name:

        CardType.DINERS_CLUB=Diner's Club

    And, of course, all of this is case insensitive. The use of case here helps to identify how the values are to be used.

  ### Chaining of Select components

    There is often a requirement for chaining Select components. When a value of a Select component is changed another Select should become visible. Let's consider the following example: you create an online shop for a car seller. A make is modeled as enumeration CarMaker.

    ### CarMaker.java

        public enum CarMaker
        {
            MERCEDES, AUDI, BMW;
        }

    ### SelectZoneDemo.tml

    The Select component 'carMaker' of the page SelectZoneDemo shows all available car makers. When a user selects a car maker, another Select component for selecting available models of the make should appear. This can be accomplished with the zone parameter of the 'carMaker' Select component. When the zone parameter is bound, every change of the Select's value causes an Ajax request, firing the valueChanged event. In this example, a corresponding event handler method, onValueChanged, populates the model used by the second Select component.

        <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
           <t:form>
              <p>
                 <t:errors />
              </p>
              <p>
                 <t:select t:id="carMaker" validate="required"
                           zone="modelZone" />
              </p>

              <t:zone t:id="modelZone" id="modelZone">
                 <t:if test="carMaker">
                   <p>
                      <t:select t:id="carModel" model="availableModels" validate="required"/>
                   </p>
                 </t:if>
              </t:zone>

              <p>
                 <t:submit value="literal:Submit" />
              </p>
           </t:form>

        </html>

    ### SelectZoneDemo.java

    The event handler method for the event valuechanged is used to provide the available car models of the currently selected car maker. The new Select's value is passed as context.

        public class SelectZoneDemo
        {

           @Inject
           private Messages messages;

           @Property
           @Persist
           private CarMaker carMaker;

           @Property
           @Persist
           private String carModel;

           @InjectComponent
           private Zone modelZone;

           @Property
           @Persist
           private List<String> availableModels;

            public Object onValueChanged(CarMaker maker)
            {
               availableModels = findAvailableModels(maker);

               return modelZone.getBody();
            }

            public List<String> findAvailableModels(final CarMaker maker)
            {
              switch (maker)
              {
                 case AUDI:
                    return Arrays.asList("A4", "A6", "A8");
                 case BMW:
                    return Arrays.asList("3 Series", "5 Series", "7 Series");
                 case MERCEDES:
                    return Arrays.asList("C-Class", "E-Class", "S-Class");
                 default:
                    return Arrays.asList();
               }
            }
        }

    The Select component is very smart for enum types; it can automatically create a SelectModel for a given Enum, and a default ValueEncoder. Likewise, it can turn an array or List into a SelectModel automatically. This streamlines the use of the Select in many situations ... but because the model and encode parameters are still present, allows you to override its behavior when needed.

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static String` | `CHANGE_EVENT`

    - ### Fields inherited from class org.apache.tapestry5.corelib.base.AbstractField

      `cssClass, decorator, defaultProvider, disabled, environment, javaScriptSupport, label, resources, validationTracker`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `Select()`

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `boolean` | `isRequired()` Returns false; most components do not support declarative validation.
    `protected void` | `processSubmission(String controlName)` Method implemented by subclasses to actually do the work of processing the submission of the form.
    `protected Object` | `toValue(String submittedValue)`

    - ### Methods inherited from class org.apache.tapestry5.corelib.base.AbstractField

      `decorateInsideField, getClientId, getControlName, getLabel, isDisabled, putPropertyNameIntoBeanValidationContext, removePropertyNameFromBeanValidationContext, setDecorator, setFormSupport`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### CHANGE_EVENT

          public static final String CHANGE_EVENT

      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### Select

          public Select()

  - ### Method Detail

    - #### processSubmission

          protected void processSubmission(String controlName)

      Description copied from class: `AbstractField`
      Method implemented by subclasses to actually do the work of processing the submission of the form. The element's controlName property will already have been set. This method is only invoked if the field is not `disabled`.
      Specified by:
        `processSubmission` in class `AbstractField`
      Parameters:
        `controlName` - the control name of the rendered element (used to find the correct parameter in the request)

    - #### toValue

          protected Object toValue(String submittedValue)
                            throws ValidationException

      Throws:
        `ValidationException`

    - #### isRequired

          public boolean isRequired()

      Description copied from class: `AbstractField`
      Returns false; most components do not support declarative validation.
      Specified by:
        `isRequired` in interface `Field`
      Overrides:
        `isRequired` in class `AbstractField`
      Returns:
        true if a non-blank value is required for the field

5.6.4 - Copyright © 2003-2021 The Apache Software Foundation.