You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2008/03/06 03:45:21 UTC

svn commit: r634133 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry/corelib/components/ main/java/org/apache/tapestry/corelib/data/ main/java/org/apache/tapestry/services/ main/java/org/apache/tapestry/util/ test/app1/ t...

Author: hlship
Date: Wed Mar  5 18:45:19 2008
New Revision: 634133

URL: http://svn.apache.org/viewvc?rev=634133&view=rev
Log:
TAPESTRY-2214: Select component should provide control over a blank option for optional selects

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/BlankOption.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/blank_label.txt
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/util/EnumValueEncoder.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/SimpleForm.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/SelectTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/SimpleForm.properties

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java?rev=634133&r1=634132&r2=634133&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java Wed Mar  5 18:45:19 2008
@@ -20,9 +20,11 @@
 import org.apache.tapestry.annotations.Mixin;
 import org.apache.tapestry.annotations.Parameter;
 import org.apache.tapestry.corelib.base.AbstractField;
+import org.apache.tapestry.corelib.data.BlankOption;
 import org.apache.tapestry.corelib.mixins.RenderDisabled;
 import org.apache.tapestry.internal.TapestryInternalUtils;
 import org.apache.tapestry.internal.util.SelectModelRenderer;
+import org.apache.tapestry.ioc.Messages;
 import org.apache.tapestry.ioc.annotations.Inject;
 import org.apache.tapestry.services.*;
 import org.apache.tapestry.util.EnumSelectModel;
@@ -82,6 +84,21 @@
     @Parameter(required = true)
     private SelectModel _model;
 
+    /**
+     * 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).
+     */
+    @Parameter(value = "auto", defaultPrefix = TapestryConstants.LITERAL_BINDING_PREFIX)
+    private BlankOption _blankOption;
+
+    /**
+     * The label to use for the blank option, if rendered.  If not specified, the container's message catalog is
+     * searched for a key, <code><em>id</em>-blanklabel</code>.
+     */
+    @Parameter(defaultPrefix = TapestryConstants.LITERAL_BINDING_PREFIX)
+    private String _blankLabel;
+
     @Inject
     private Request _request;
 
@@ -151,10 +168,7 @@
 
         _resources.renderInformalParameters(writer);
 
-        // Disabled via mixin
-
-        // Figure out
-
+        // Disabled is via a mixin
     }
 
     @SuppressWarnings("unchecked")
@@ -195,6 +209,20 @@
         return createDefaultParameterBinding("value");
     }
 
+    Object defaultBlankLabel()
+    {
+        Messages containerMessages = _resources.getContainerMessages();
+
+        String key = _resources.getId() + "-blanklabel";
+
+        if (containerMessages.contains(key)) return containerMessages.get(key);
+
+        return null;
+    }
+
+    /**
+     * Renders the options, including the blank option.
+     */
     @BeforeRenderTemplate
     void options(MarkupWriter writer)
     {
@@ -206,16 +234,46 @@
 
         if (_selectedClientValue == null) _selectedClientValue = _value == null ? null : _encoder.toClient(_value);
 
+        if (showBlankOption())
+        {
+            writer.element("option", "value", "");
+            writer.write(_blankLabel);
+            writer.end();
+        }
+
+
         SelectModelVisitor renderer = new Renderer(writer);
 
         _model.visit(renderer);
     }
 
+    @Override
+    public boolean isRequired()
+    {
+        return _validate.isRequired();
+    }
+
+    private boolean showBlankOption()
+    {
+        switch (_blankOption)
+        {
+            case ALWAYS:
+                return true;
+            case NEVER:
+                return false;
+
+            default:
+
+                return !isRequired();
+        }
+    }
+
     // For testing.
 
     void setModel(SelectModel model)
     {
         _model = model;
+        _blankOption = BlankOption.NEVER;
     }
 
     void setValue(Object value)
@@ -233,9 +291,11 @@
         _tracker = tracker;
     }
 
-    @Override
-    public boolean isRequired()
+    void setBlankOption(BlankOption option, String label)
     {
-        return _validate.isRequired();
+        _blankOption = option;
+        _blankLabel = label;
     }
+
+
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/BlankOption.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/BlankOption.java?rev=634133&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/BlankOption.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/BlankOption.java Wed Mar  5 18:45:19 2008
@@ -0,0 +1,38 @@
+// Copyright 2008 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.
+
+package org.apache.tapestry.corelib.data;
+
+/**
+ * Used with the {@link org.apache.tapestry.corelib.components.Select} component to control whether an initial blank
+ * option is supplied.  Determines the optionality of the undelrying property from the Select's {@linkplain
+ * org.apache.tapestry.FieldValidator#isRequired() validate parameter}
+ */
+public enum BlankOption
+{
+    /**
+     * Always include the blank option, even if the underlying property is required.
+     */
+    ALWAYS,
+
+    /**
+     * Never include the blank option, even if the underlying property is optional.
+     */
+    NEVER,
+
+    /**
+     * The default: include the blank option if the underlying property is optional.
+     */
+    AUTO;
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=634133&r1=634132&r2=634133&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java Wed Mar  5 18:45:19 2008
@@ -17,6 +17,7 @@
 import org.apache.tapestry.*;
 import org.apache.tapestry.annotations.*;
 import org.apache.tapestry.beaneditor.Validate;
+import org.apache.tapestry.corelib.data.BlankOption;
 import org.apache.tapestry.corelib.data.GridPagerPosition;
 import org.apache.tapestry.corelib.data.InsertPosition;
 import org.apache.tapestry.grid.GridDataSource;
@@ -582,9 +583,9 @@
      * Adds coercions: <ul> <li>String to {@link org.apache.tapestry.SelectModel} <li>String to {@link
      * org.apache.tapestry.corelib.data.InsertPosition} <li>Map to {@link org.apache.tapestry.SelectModel}
      * <li>Collection to {@link GridDataSource} <li>null to {@link org.apache.tapestry.grid.GridDataSource} <li>String
-     * to {@link org.apache.tapestry.corelib.data.GridPagerPosition} <li>List to {@link SelectModel} <li>{@link
-     * org.apache.tapestry.runtime.ComponentResourcesAware} (typically, a component) to {@link
-     * org.apache.tapestry.ComponentResources} </ul>
+     * to {@link org.apache.tapestry.corelib.data.GridPagerPosition} <li>List to {@link org.apache.tapestry.SelectModel}
+     * <li>{@link org.apache.tapestry.runtime.ComponentResourcesAware} (typically, a component) to {@link
+     * org.apache.tapestry.ComponentResources} <li>String to {@link org.apache.tapestry.corelib.data.BlankOption} </ul>
      */
     public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration)
     {
@@ -627,6 +628,8 @@
             StringToEnumCoercion.create(GridPagerPosition.class));
 
         add(configuration, String.class, InsertPosition.class, StringToEnumCoercion.create(InsertPosition.class));
+
+        add(configuration, String.class, BlankOption.class, StringToEnumCoercion.create(BlankOption.class));
 
         add(configuration, List.class, SelectModel.class, new Coercion<List, SelectModel>()
         {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/util/EnumValueEncoder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/util/EnumValueEncoder.java?rev=634133&r1=634132&r2=634133&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/util/EnumValueEncoder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/util/EnumValueEncoder.java Wed Mar  5 18:45:19 2008
@@ -16,6 +16,7 @@
 
 import org.apache.tapestry.ValueEncoder;
 import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
 
 /**
  * A value encoder that can be used for aribrary Enum types. The enum name is stored as the client side value.
@@ -41,7 +42,7 @@
     @SuppressWarnings("unchecked")
     public E toValue(String clientValue)
     {
-        if (clientValue == null) return null;
+        if (InternalUtils.isBlank(clientValue)) return null;
 
         return Enum.valueOf(_enumType, clientValue);
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/SimpleForm.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/SimpleForm.tml?rev=634133&r1=634132&r2=634133&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/SimpleForm.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/SimpleForm.tml Wed Mar  5 18:45:19 2008
@@ -6,7 +6,10 @@
         start to Tapestry 5 form support.
     </p>
 
-    <t:form>
+    <t:form clientvalidation="false">
+
+        <t:errors/>
+        
         <input t:type="Checkbox" t:id="disabled"/>
         <t:label for="disabled"/>
         <br/>

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/SelectTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/SelectTest.java?rev=634133&r1=634132&r2=634133&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/SelectTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/SelectTest.java Wed Mar  5 18:45:19 2008
@@ -15,6 +15,7 @@
 package org.apache.tapestry.corelib.components;
 
 import org.apache.tapestry.*;
+import org.apache.tapestry.corelib.data.BlankOption;
 import org.apache.tapestry.dom.XMLMarkupModel;
 import org.apache.tapestry.internal.OptionGroupModelImpl;
 import org.apache.tapestry.internal.OptionModelImpl;
@@ -118,6 +119,40 @@
     }
 
     @Test
+    public void just_options_with_blank_label_enabled() throws Exception
+    {
+        ValidationTracker tracker = mockValidationTracker();
+
+        List<OptionModel> options = TapestryInternalUtils
+                .toOptionModels("fred=Fred Flintstone,barney=Barney Rubble");
+
+        Select select = new Select();
+
+        train_getInput(tracker, select, null);
+
+        replay();
+
+
+        select.setModel(new SelectModelImpl(null, options));
+        select.setValueEncoder(new StringValueEncoder());
+        select.setValue("barney");
+        select.setValidationTracker(tracker);
+        select.setBlankOption(BlankOption.ALWAYS, "Make a selection");
+
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+
+        writer.element("select");
+
+        select.options(writer);
+
+        writer.end();
+
+        assertEquals(writer.toString(), read("blank_label.txt"));
+
+        verify();
+    }
+
+    @Test
     public void current_selection_from_validation_tracker() throws Exception
     {
         ValidationTracker tracker = mockValidationTracker();
@@ -343,4 +378,5 @@
 
         verify();
     }
+
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=634133&r1=634132&r2=634133&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Wed Mar  5 18:45:19 2008
@@ -391,8 +391,12 @@
         assertFieldValue("email", "");
         assertFieldValue("message", "");
         assertFieldValue("operatingSystem", "osx");
-        assertFieldValue("department", "ACCOUNTING");
+        assertFieldValue("department", "");
         assertFieldValue("urgent", "on");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("department: []");
 
         type("email", "foo@bar.baz");
         type("message", "Message for you, sir!");

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/blank_label.txt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/blank_label.txt?rev=634133&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/blank_label.txt (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/blank_label.txt Wed Mar  5 18:45:19 2008
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<select><option value="">Make a selection</option><option value="fred">Fred Flintstone</option><option selected="selected" value="barney">Barney Rubble</option></select>
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/SimpleForm.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/SimpleForm.properties?rev=634133&r1=634132&r2=634133&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/SimpleForm.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/SimpleForm.properties Wed Mar  5 18:45:19 2008
@@ -1,4 +1,4 @@
-# Copyright 2007 The Apache Software Foundation
+# Copyright 2007, 2008 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.
@@ -13,6 +13,8 @@
 # limitations under the License.
 
 urgent-label=Urgent Processing Requested
+
+operatingSystem-blanklabel=Select ...
 os-values=\
   winnt=Windows NT, \
   winxp=Windows XP, \
@@ -20,6 +22,8 @@
   os9=Mac OS 9, \
   osx=Mac OS X, \
   linux=Linux
+
+department-blanklabel=Select...
   
 # Correct some of the labels for the drop down list
 SALES_AND_MARKETING=Sales/Marketing