| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| Copyright 2007 The Apache Software Foundation |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| <document> |
| <properties> |
| <title>PropertySelection</title> |
| </properties> |
| <body> |
| |
| <section name="PropertySelection"> |
| |
| <p> |
| Creates form elements that allow a property of an object to be set from a drop-down |
| list. |
| </p> |
| <p> |
| Uses a |
| <a href="../../apidocs/org/apache/tapestry/form/IPropertySelectionModel.html">IPropertySelectionModel</a> |
| to map between Java values that will be assigned, and textual labels that will |
| appear in the HTML response. |
| </p> |
| <p> |
| A useful property selection model is available ( |
| <a href="../../apidocs/org/apache/tapestry/form/StringPropertySelectionModel.html">StringPropertySelectionModel</a> |
| , or |
| <a href="../../apidocs/org/apache/tapestry/form/BeanPropertySelectionModel.html">BeanPropertySelectionModel</a>). |
| You can also create your own model, as illustrated in the examples below. |
| </p> |
| <p> |
| Note that complex value Objects need to properly implement the <code>Object.equals()</code> |
| method if the correct initial item is to be displayed. |
| </p> |
| |
| <p> |
| Informal parameters are applied to the <code><select></code> tag. To have greater control |
| over the <code><option></code> tags, you must use the <a href="select.html">Select</a> and |
| <a href="option.html">Option</a> components. |
| </p> |
| |
| <p> |
| <strong> |
| See also: |
| <a href="../../apidocs/org/apache/tapestry/form/PropertySelection.html">org.apache.tapestry.form.PropertySelection</a> |
| , |
| <a href="select.html">Select</a> |
| , |
| <a href="option.html">Option</a> |
| , |
| <a href="radio.html">Radio</a> |
| , |
| <a href="radiogroup.html">RadioGroup</a> |
| , |
| <a href="form.html">Form</a> |
| , |
| <a href="../general/script.html">Script</a> |
| </strong> |
| |
| </p> |
| |
| <section name="Parameters"> |
| <table> |
| <tr> |
| <th>Name</th> |
| <th>Type</th> |
| <th>Required</th> |
| <th>Default</th> |
| <th>Description</th> |
| </tr> |
| <tr> |
| <td>value</td> |
| <td>Object</td> |
| <td>yes</td> |
| <td> </td> |
| <td> |
| The property to set. During rendering, this property is read, and sets |
| the default value of the selection (if it is null, no element is |
| selected). When the form is submitted, this property is updated based on |
| the new selection. |
| </td> |
| </tr> |
| <tr> |
| <td>model</td> |
| <td> |
| <a href="../../apidocs/org/apache/tapestry/form/IPropertySelectionModel.html"> |
| IPropertySelectionModel |
| </a> |
| </td> |
| <td>yes</td> |
| <td> </td> |
| <td> |
| The model provides a list of possible labels, and matches those labels |
| against possible values that can be assigned back to the property. |
| </td> |
| |
| </tr> |
| <tr> |
| <td>optionRenderer</td> |
| <td> |
| <a href="../../apidocs/org/apache/tapestry/form/IOptionRenderer.html"> |
| IOptionRenderer |
| </a> |
| </td> |
| <td>yes</td> |
| <td> |
| <a href="../../apidocs/org/apache/tapestry/form/DefaultOptionRenderer.html"> |
| DefaultOptionRenderer |
| </a> |
| </td> |
| <td> |
| Object used to render the <code><option>Label</option></code> elements |
| within the enclosing <code><select></code> tags. The default implementation currently |
| handles only writing out the <code>disabled/selected</code> attributes corresponding the methods |
| implemented by |
| <a href="../../apidocs/org/apache/tapestry/form/IPropertySelectionModel.html"> |
| IPropertySelectionModel |
| </a>. |
| <br /><br /> |
| It is possible to implement more advanced display semantics of your options list by implementing a custom |
| <a href="../../apidocs/org/apache/tapestry/form/IOptionRenderer.html"> |
| IOptionRenderer |
| </a> of your own. Things like <code>optgroup</code> and various indentation strategies are typically good |
| candidates for implementing custom renderers. |
| </td> |
| |
| </tr> |
| <tr> |
| <td>disabled</td> |
| <td>boolean</td> |
| <td>no</td> |
| <td>false</td> |
| <td> |
| Controls whether the <code><select></code> is active or not. A disabled |
| PropertySelection does not update its value parameter. Corresponds to |
| the "disabled" HTML attribute. |
| </td> |
| </tr> |
| <tr> |
| <td>displayName</td> |
| <td>String</td> |
| <td>no</td> |
| <td> </td> |
| <td> |
| |
| The user-presentable name for the component, which will be used by a |
| <a href="fieldlabel">FieldLabel</a> |
| connected to the component. |
| </td> |
| </tr> |
| <tr> |
| <td>validators</td> |
| <td> |
| Array or collection of |
| <a href="../../apidocs/org/apache/tapestry/form/validator/Validator.html"> |
| Validator |
| </a> |
| </td> |
| <td>no</td> |
| <td> </td> |
| <td> |
| The validators to apply to the component. Something along the lines of: |
| <code>validators:required</code> .<br/><br/> |
| |
| <strong>See also:</strong> <a href="../../usersguide/validation.html">Validation</a> |
| </td> |
| </tr> |
| </table> |
| |
| <p> |
| Body: |
| <strong>removed</strong> |
| </p> |
| |
| <p> |
| Informal parameters: |
| <strong>allowed</strong> |
| </p> |
| |
| <p> |
| Reserved parameters: |
| <em>name</em> |
| </p> |
| |
| </section> |
| |
| <section name="Examples"> |
| <subsection name="Example 1"> |
| <p> |
| The PropertySelection component provides Gender selection drop down list |
| using a |
| <a href="../../apidocs/org/apache/tapestry/form/StringPropertySelectionModel.html"> |
| StringPropertySelectionModel |
| </a> |
| </p> |
| |
| <source xml:space="preserve"><![CDATA[ |
| <form jwcid="@Form" listener="listener:formSubmit"> |
| Gender: <select jwcid="@PropertySelection" model="ognl:@com.myexample.DetailsPage@GENDER_MODEL" value="ognl:gender"></select> |
| <input type="submit"/> |
| </form> |
| ]]></source> |
| |
| <source xml:space="preserve"> |
| public abstract class DetailsPage extends BasePage { |
| public static final IPropertySelectionModel GENDER_MODEL = |
| new StringPropertySelectionModel(new String[] { "Unspecified", "Female", "Male" }); |
| |
| public abstract String getGender(); |
| |
| public void formSubmit(IRequestCycle cycle) { |
| // Process form submission |
| String genderSelection = getGender(); |
| ... |
| } |
| } |
| </source> |
| </subsection> |
| |
| <subsection name="Example 2 : Custom IOptionRenderer"> |
| <p> |
| The <code>optionRenderer</code> parameter allows you complete control over the display of your options list with custom |
| renderer implementations. The following example shows a sample custom renderer implementation for generating a google style |
| drop down actions list. <em>(similar to the gmail drop down actions list)</em> |
| </p> |
| |
| <p> |
| The resulting option list would look something like: |
| </p> |
| |
| <select name="sampleOptions"> |
| <option value="-1" style="color: rgb(119, 119, 119);">choose..</option> |
| <option value="0" style="padding-left:1em;">Dogs</option> |
| <option value="1" style="padding-left:1em;">Elephants</option> |
| <option value="2" style="padding-left:1em;">Mongoose</option> |
| <option value="3" style="padding-left:1em;">Angry Chipmunks</option> |
| </select> |
| |
| <source xml:space="preserve"><![CDATA[ |
| /** |
| * Implementation of {@link IOptionRenderer} that pretty prints options |
| * that aren't disabled with padded whitespace at the beginning. |
| */ |
| public class FormattedOptionRenderer implements IOptionRenderer { |
| |
| // Provided for efficiency / convenience |
| public static final IOptionRenderer DEFAULT_INSTANCE = new FormattedOptionRenderer(); |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void renderOptions(IMarkupWriter writer, IRequestCycle cycle, IPropertySelectionModel model, Object selected) { |
| int count = model.getOptionCount(); |
| |
| for (int i = 0; i < count; i++) |
| { |
| Object option = model.getOption(i); |
| |
| writer.begin("option"); |
| writer.attribute("value", model.getValue(i)); |
| |
| if (isEqual(option, selected, model)) |
| writer.attribute("selected", "selected"); |
| |
| if (model.isDisabled(i)) |
| writer.attribute("style", "color: rgb(119, 119, 119);"); |
| |
| if (i > 0) |
| writer.printRaw(" "); |
| |
| writer.print(model.getLabel(i)); |
| |
| writer.end(); |
| writer.println(); |
| } |
| } |
| |
| protected boolean isEqual(Object left, Object right, IPropertySelectionModel model) { |
| |
| if (List.class.isInstance(right) && IPrimaryKeyConverter.class.isInstance(model)) |
| { |
| List values = (List) right; |
| IPrimaryKeyConverter converter = (IPrimaryKeyConverter) model; |
| |
| if (left == null) |
| return false; |
| |
| for (Object option : values) |
| if (converter.getPrimaryKey(option).equals(converter.getPrimaryKey(left))) |
| return true; |
| |
| return false; |
| } |
| |
| // Both null, or same object, then are equal |
| |
| if (left == right) |
| return true; |
| |
| // If one is null, the other isn't, then not equal. |
| |
| if (left == null || right == null) |
| return false; |
| |
| // Both non-null; use standard comparison. |
| |
| return left.equals(right); |
| } |
| } |
| ]]></source> |
| </subsection> |
| |
| <subsection name="Example 3"> |
| |
| <p> |
| Provides list of clothing items for the user to select. When the user |
| selects a cloting item from the list the description the label and price is |
| automatically updated. The list of clothing items would typically be loaded |
| from a database. |
| </p> |
| |
| <p>PurchasePage.html</p> |
| |
| <source xml:space="preserve"><![CDATA[ |
| <body jwcid="@Body"> |
| <form jwcid="@Form" listener="listener:formSubmit"> |
| <label jwcid="@FieldLabel" field="component:itemSelection">Selection</label> |
| <select jwcid="itemSelection@PropertySelection" |
| model="ognl:itemSelectionModel" |
| value="ognl:clothingItem" |
| onchange="javascript:this.form.events.refresh();" |
| displayName="Choose an item"></select> |
| <input type="submit" value="Show me this item"/> |
| <span jwcid="@Conditional" condition="ognl:clothingItem!=null"> |
| <p>Description: <span jwcid="@Insert" value="ognl:clothingItem.description"/></p> |
| <p>Label: <span jwcid="@Insert" value="ognl:clothingItem.label"/></p> |
| <p>Price: $<span jwcid="@Insert" value="ognl:clothingItem.price"/></p> |
| </span> |
| </form> |
| </body> |
| ]]></source> |
| |
| <p>PurchasePage.java</p> |
| <source xml:space="preserve"> |
| public abstract class PurchasePage extends BasePage implements PageDetachListener { |
| |
| private ItemSelectionModel model = null; |
| |
| public abstract Item getClothingItem(); |
| public abstract void setClothingItem(Item value); |
| |
| public ItemSelectionModel getItemSelectionModel() { |
| if (model == null) { |
| List items = new ArrayList(); |
| items.add(new Item(1, "Dress", "Cotton full length Summer dress", "CountryClub", "89.95")); |
| items.add(new Item(2, "Jacket", "Gorgeous jacket", "CountryClub", "119.95")); |
| model = new ItemSelectionModel(items); |
| } |
| return model; |
| } |
| |
| public void formSubmit() { |
| // Process form submission |
| |
| } |
| |
| public void pageDetached(PageEvent pageEvent) { |
| model = null; |
| } |
| |
| } |
| </source> |
| |
| <p>Item.java</p> |
| <source xml:space="preserve"> |
| public class Item implements Serializable { |
| private int id; |
| private String name; |
| private String description; |
| private String label; |
| private String price; |
| |
| public Item(int id, String name, String desc, String label, String price) { |
| this.id = id; |
| this.name = name; |
| this.description = desc; |
| this.label = label; |
| this.price = price; |
| } |
| |
| public int getId() { return id; } |
| |
| public String getName() { return name; } |
| |
| public String getDescription() { return description; } |
| |
| public String getLabel() { return label; } |
| |
| public String getPrice() { return price; } |
| } |
| </source> |
| |
| <p>ItemSelectionModel.java</p> |
| <source xml:space="preserve"> |
| public class ItemSelectionModel implements IPropertySelectionModel, Serializable { |
| private List itemList; |
| |
| public ItemSelectionModel(List itemList) { |
| this.itemList = itemList; |
| } |
| |
| public int getOptionCount() { return itemList.size(); } |
| |
| public Object getOption(int index) { |
| return itemList.get(index); |
| } |
| |
| public String getLabel(int index) { |
| return ((Item) itemList.get(index)).getName(); |
| } |
| |
| public String getValue(int index) { return Integer.toString(index); } |
| |
| public Object translateValue(String value) { |
| return getOption(Integer.parseInt(value)); |
| } |
| } |
| </source> |
| </subsection> |
| </section> |
| |
| </section> |
| |
| </body> |
| </document> |