001 // Copyright 2004, 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry.form; 016 017 import org.apache.tapestry.IMarkupWriter; 018 import org.apache.tapestry.IRequestCycle; 019 import org.apache.tapestry.Tapestry; 020 import org.apache.tapestry.valid.ValidatorException; 021 022 /** 023 * A component used to render a drop-down list of options that the user may select. [ <a 024 * href="../../../../../ComponentReference/PropertySelection.html">Component Reference </a>] 025 * <p> 026 * Earlier versions of PropertySelection (through release 2.2) were more flexible, they included a 027 * <b>renderer </b> property that controlled how the selection was rendered. Ultimately, this proved 028 * of little value and this portion of functionality was deprecated in 2.3 and will be removed in 029 * 2.3. 030 * <p> 031 * Typically, the values available to be selected are defined using an 032 * {@link java.lang.Enum}. A PropertySelection is dependent on an 033 * {@link IPropertySelectionModel} to provide the list of possible values. 034 * <p> 035 * Often, this is used to select a particular {@link java.lang.Enum} to assign to 036 * a property; the {@link org.apache.tapestry.form.EnumPropertySelectionModel} class simplifies this. 037 * <p> 038 * Often, a drop-down list will contain an initial option that serves both as a label and to represent 039 * that nothing is selected. This can behavior can easily be achieved by decorating an existing 040 * {@link IPropertySelectionModel} with a {@link LabeledPropertySelectionModel}. 041 * <p> 042 * 043 */ 044 public abstract class PropertySelection extends AbstractFormComponent implements ValidatableField 045 { 046 /** 047 * @see org.apache.tapestry.form.AbstractFormComponent#renderFormComponent(org.apache.tapestry.IMarkupWriter, org.apache.tapestry.IRequestCycle) 048 */ 049 protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle) 050 { 051 renderDelegatePrefix(writer, cycle); 052 053 writer.begin("select"); 054 writer.attribute("name", getName()); 055 056 if (isDisabled()) 057 writer.attribute("disabled", "disabled"); 058 059 renderIdAttribute(writer, cycle); 060 061 renderDelegateAttributes(writer, cycle); 062 063 getValidatableFieldSupport().renderContributions(this, writer, cycle); 064 065 // Apply informal attributes. 066 renderInformalParameters(writer, cycle); 067 068 writer.println(); 069 070 IPropertySelectionModel model = getModel(); 071 072 if (model == null) 073 throw Tapestry.createRequiredParameterException(this, "model"); 074 075 getOptionRenderer().renderOptions(writer, cycle, model, getValue()); 076 077 writer.end(); // <select> 078 079 renderDelegateSuffix(writer, cycle); 080 } 081 082 /** 083 * @see org.apache.tapestry.form.AbstractFormComponent#rewindFormComponent(org.apache.tapestry.IMarkupWriter, org.apache.tapestry.IRequestCycle) 084 */ 085 protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle) 086 { 087 String value = cycle.getParameter(getName()); 088 089 Object object = getModel().translateValue(value); 090 091 try 092 { 093 getValidatableFieldSupport().validate(this, writer, cycle, object); 094 095 setValue(object); 096 } 097 catch (ValidatorException e) 098 { 099 getForm().getDelegate().record(e); 100 } 101 } 102 103 public abstract IPropertySelectionModel getModel(); 104 105 /** @since 2.2 * */ 106 public abstract Object getValue(); 107 108 /** @since 2.2 * */ 109 public abstract void setValue(Object value); 110 111 /** Responsible for rendering individual options. */ 112 public abstract IOptionRenderer getOptionRenderer(); 113 114 /** 115 * Injected. 116 */ 117 public abstract ValidatableFieldSupport getValidatableFieldSupport(); 118 119 /** 120 * @see org.apache.tapestry.form.AbstractFormComponent#isRequired() 121 */ 122 public boolean isRequired() 123 { 124 return getValidatableFieldSupport().isRequired(this); 125 } 126 }