Package org.apache.tapestry5.corelib.components

## Class Palette

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

- All Implemented Interfaces:
    `ClientElement`, `Field`

      @Import(stylesheet="Palette.css")
      public class Palette
      extends AbstractField

  Multiple selection component. Generates a UI consisting of two <select> elements configured for multiple selection; the one on the left is the list of "available" elements, the one on the right is "selected". Elements can be moved between the lists by clicking a button, or double clicking an option (and eventually, via drag and drop). The items in the available list are kept ordered as per `SelectModel` order. When items are moved from the selected list to the available list, they items are inserted back into their proper positions. The Palette may operate in normal or re-orderable mode, controlled by the reorder parameter. In normal mode, the items in the selected list are kept in the same "natural" order as the items in the available list. In re-order mode, items moved to the selected list are simply added to the bottom of the list. In addition, two extra buttons appear to move items up and down within the selected list. Much of the look and feel is driven by CSS, the default Tapestry CSS is used to set up the columns, etc. By default, the <select> element's widths are 200px, and it is common to override this to a specific value:

       <style>
         DIV.palette SELECT { width: 300px; }
       </style>

  You'll want to ensure that both <select> in each column is the same width, otherwise the display will update poorly as options are moved from one column to the other. Option groups within the `SelectModel` will be rendered, but are not supported by many browsers, and are not fully handled on the client side. For an alternative component that can be used for similar purposes, see `Checklist`. Starting in 5.4, the selected parameter may be any kind of collection, but is typically a List if the Palette is configured for re-ordering, and a Set if order does not matter (though it is common to use a List in the latter case as well). Also, starting in 5.4, the Palette is compatible with the `Required` validator (on both client and server-side), and triggers new events that allows the application to veto a proposed changed to the selection (see the `t5/core/events` module).
  See Also:
    `Form`, `Select`

  Component Parameters
  Name | Type | Flags | Default | Default Prefix
  --- | --- | --- | --- | ---
  availableLabel | org.apache.tapestry5.Block | Required, Not Null | message:core-palette-available-label | literal
  Allows the title text for the available column (on the left) to be modified. As this is a Block, it can contain conditionals and components. The default is the text "Available".
  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.
  deselect | org.apache.tapestry5.Asset |  |  | prop
  The image to use for the deselect button (the default is a left pointing arrow).
  encoder | org.apache.tapestry5.ValueEncoder | Required, Not Null |  | prop
  A ValueEncoder used to convert server-side objects (provided from the "source" parameter) into unique client-side strings (typically IDs) and back. Note: this component does NOT support ValueEncoders configured to be provided automatically by Tapestry.
  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
  Model used to define the values and labels used when rendering.
  moveDown | org.apache.tapestry5.Asset |  |  | prop
  The image to use for the move down button (the default is a downward pointing arrow).
  moveUp | org.apache.tapestry5.Asset |  |  | prop
  The image to use for the move up button (the default is an upward pointing arrow).
  reorder | boolean |  | false | prop
  If true, then additional buttons are provided on the client-side to allow for re-ordering of the values. This is only useful when the selected parameter is bound to a `List`, rather than a `Set` or other unordered collection.
  select | org.apache.tapestry5.Asset |  |  | prop
  The image to use for the select button (the default is a right pointing arrow).
  selected | java.util.Collection | Required, Not Null |  | prop
  The list of selected values from the org.apache.tapestry5.SelectModel. This will be updated when the form is submitted. If the value for the parameter is null, a new list will be created, otherwise the existing list will be cleared. If unbound, defaults to a property of the container matching this component's id. Prior to Tapestry 5.4, this allowed null, and a list would be created when the form was submitted. Starting with 5.4, the selected list may not be null, and it need not be a list (it may be, for example, a set).
  selectedLabel | org.apache.tapestry5.Block | Required, Not Null | message:core-palette-selected-label | literal
  Allows the title text for the selected column (on the right) to be modified. As this is a Block, it can contain conditionals and components. The default is the text "Available".
  size | int |  | symbol:tapestry.components.palette_rows_size | prop
  Number of rows to display.
  validate | org.apache.tapestry5.FieldValidator | Since 5.2.0 |  | validate
  The object that will perform input validation. The validate binding prefix is generally used to provide this object in a declarative fashion.

  ### Examples

    For this example, we'll implement a page from an e-commerce order wizard; the page collects information about special handling for the order:

    This single screen shot doesn't capture the full richness of the user experience provided by the Palette component. The buttons enable and disable themselves based on what's selected. You can move items by double clicking, and you can move multiple items by selecting them and and then clicking the button.

    This is a far better experience than using

    ### SpecialHandling.java

        public enum SpecialHandling
        {
            EXPRESS_SERVICE, GIFT_WRAP, GIFT_BASKET, CUSTOM_ENGRAVING, SHIPPING_INSURANCE,
            EXTENDED_WARRANTY
        }

    In this contrived example, the possible types of special handling are defined using an enum. It's more likely, in the real world, that this would be defined in terms of a database entity.

    ### OrderHandling.tml

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

                <t:form>

                    <t:palette t:id="handling" encoder="encoder" model="model"/>

                    <br/>

                    <input type="submit" value="Continue"/>

                </t:form>

            </body>
        </html>

    Here we are able to omit the selected parameter (the list of selected items) because the Palette component's id matches a property of the page.

    The model parameter will define the available options that can be selected. The encoder parameter will define how to translate server side values (the enum values) into client side strings and back.

    ### OrderHandling.java

        public class OrderHandling
        {
            @Property
            @Persist
            private List<SpecialHandling> handling;

            @Inject
            private Messages messages;

        	@Inject
            private TypeCoercer typeCoercer;

            @Property
            private final ValueEncoder<SpecialHandling> encoder = new EnumValueEncoder(typeCoercer, SpecialHandling.class);

            @Property
            private final SelectModel model = new EnumSelectModel(SpecialHandling.class, messages);
        }

    Tapestry has built-in public classes that help convert enum types into value encoders and select models.

    Injecting a Messages object gives a component access to its own message catalog.

    The Palette component will read the handling property when rendering (it's ok for it to be null). When the form is submitted, it will create a new List and update the handling property.

  ### Notes

    The Palette can also be used to order, not just select, items, by binding the reorder parameter to true. In that case, additional buttons are added that allow selected items to be moved up or down the list.

    The Palette can be further customized through a mix of CSS and by replacing the images used for its various buttons.

- - ### Field Summary

    Fields
    Modifier and Type | Field | Description
    --- | --- | ---
    `Renderable` | `mainRenderer` |

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

      `cssClass, decorator, defaultProvider, disabled, environment, fieldValidationSupport, formSupport, javaScriptSupport, label, request, resources, validationTracker`

  - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---
    `Palette()` |

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `String` | `getDisabledValue()` |
    `String` | `getInitialJSON()` |
    `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.

    - ### 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

    - #### mainRenderer

          public final Renderable mainRenderer

  - ### Constructor Detail

    - #### Palette

          public Palette()

  - ### Method Detail

    - #### getInitialJSON

          public String getInitialJSON()

    - #### 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)

    - #### 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

    - #### getDisabledValue

          public String getDisabledValue()