You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by dr...@apache.org on 2011/06/16 22:49:21 UTC

svn commit: r1136668 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/corelib/components/ main/resources/org/apache/tapestry5/ main/resources/org/apache/tapestry5/corelib/components/ test/app1/ test/java/org/apache/tapes...

Author: drobiazko
Date: Thu Jun 16 20:49:21 2011
New Revision: 1136668

URL: http://svn.apache.org/viewvc?rev=1136668&view=rev
Log:
TAP5-1550: Provide a multiple selection component that renders check boxes for available selection options

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Checklist.java   (with props)
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Checklist.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ChecklistDemo.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ChecklistDemo.java   (with props)
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/default.css
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Checklist.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Checklist.java?rev=1136668&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Checklist.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Checklist.java Thu Jun 16 20:49:21 2011
@@ -0,0 +1,190 @@
+package org.apache.tapestry5.corelib.components;
+
+import org.apache.tapestry5.*;
+import org.apache.tapestry5.annotations.Environmental;
+import org.apache.tapestry5.annotations.Parameter;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.corelib.base.AbstractField;
+import org.apache.tapestry5.dom.Element;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.services.ComponentDefaultProvider;
+import org.apache.tapestry5.services.Request;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+public class Checklist extends AbstractField
+{
+
+    /**
+     * Model used to define the values and labels used when rendering the
+     * checklist.
+     */
+    @Parameter(required = true)
+    private SelectModel model;
+
+    /**
+     * The list of selected values from the
+     * {@link 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.
+     */
+    @Parameter(required = true, autoconnect = true)
+    private List<Object> selected;
+
+    /**
+     * Encoder used to translate between server-side objects and client-side
+     * strings.
+     */
+    @Parameter(required = true, allowNull = false)
+    private ValueEncoder<Object> encoder;
+
+    /**
+     * The object that will perform input validation. The validate binding prefix is generally used to provide
+     * this object in a declarative fashion.
+     */
+    @Parameter(defaultPrefix = BindingConstants.VALIDATE)
+    @SuppressWarnings("unchecked")
+    private FieldValidator<Object> validate;
+
+    @Inject
+    private Request request;
+
+    @Inject
+    private FieldValidationSupport fieldValidationSupport;
+
+    @Environmental
+    private ValidationTracker tracker;
+
+    @Inject
+    private ComponentResources componentResources;
+
+    @Inject
+    private ComponentDefaultProvider defaultProvider;
+
+    @Property
+    private List<Renderable> availableOptions;
+
+    private MarkupWriter markupWriter;
+
+    private final class RenderRadio implements Renderable
+    {
+        private final OptionModel model;
+
+        private RenderRadio(final OptionModel model)
+        {
+            this.model = model;
+        }
+
+        public void render(MarkupWriter writer)
+        {
+            writer.element("label");
+            writer.write(model.getLabel());
+            writer.end();
+
+            final String clientValue = encoder.toClient(model.getValue());
+
+            final Element checkbox = writer.element("input", "type", "checkbox", "name", getControlName(), "value", clientValue);
+
+            if (getSelected().contains(model.getValue()))
+            {
+                checkbox.attribute("checked", "checked");
+            }
+            writer.end();
+        }
+    }
+
+    void setupRender(final MarkupWriter writer)
+    {
+        markupWriter = writer;
+
+        availableOptions = CollectionFactory.newList();
+
+        final SelectModelVisitor visitor = new SelectModelVisitor()
+        {
+            public void beginOptionGroup(final OptionGroupModel groupModel)
+            {
+            }
+
+            public void option(final OptionModel optionModel)
+            {
+                availableOptions.add(new RenderRadio(optionModel));
+            }
+
+            public void endOptionGroup(final OptionGroupModel groupModel)
+            {
+            }
+
+        };
+
+        model.visit(visitor);
+    }
+
+    @Override
+    protected void processSubmission(final String elementName)
+    {
+
+        final String[] parameters = request.getParameters(elementName);
+
+        List<Object> selected = this.selected;
+
+        if (selected == null)
+        {
+            selected = CollectionFactory.newList();
+        } else
+        {
+            selected.clear();
+        }
+
+        if (parameters != null)
+        {
+            for (final String value : parameters)
+            {
+                final Object objectValue = encoder.toValue(value);
+
+                selected.add(objectValue);
+            }
+
+        }
+
+        try
+        {
+            this.fieldValidationSupport.validate(selected, this.componentResources, this.validate);
+
+            this.selected = selected;
+        } catch (final ValidationException e)
+        {
+            this.tracker.recordError(this, e.getMessage());
+        }
+    }
+
+    Set<Object> getSelected()
+    {
+        if (selected == null)
+        {
+            return Collections.emptySet();
+        }
+
+        return CollectionFactory.newSet(selected);
+    }
+
+    /**
+     * Computes a default value for the "validate" parameter using
+     * {@link org.apache.tapestry5.services.FieldValidatorDefaultSource}.
+     */
+
+    Binding defaultValidate()
+    {
+        return this.defaultProvider.defaultValidatorBinding("selected", this.componentResources);
+    }
+
+    @Override
+    public boolean isRequired()
+    {
+        return validate.isRequired();
+    }
+}
+

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Checklist.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Checklist.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Checklist.tml?rev=1136668&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Checklist.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Checklist.tml Thu Jun 16 20:49:21 2011
@@ -0,0 +1,5 @@
+<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+    <div t:type="loop" source="availableOptions" value="var:currentOption" class="t-checklist-row">
+           <t:delegate to="var:currentOption"/>
+    </div>
+</t:container>
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/default.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/default.css?rev=1136668&r1=1136667&r2=1136668&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/default.css (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/default.css Thu Jun 16 20:49:21 2011
@@ -205,6 +205,20 @@ DIV.t-beaneditor-row LABEL {
     vertical-align: middle;
 }
 
+DIV.t-checklist-row {
+    padding: 4px 0px 2px 0px;
+}
+
+DIV.t-checklist-row LABEL {
+    width: 150px;
+    display: block;
+    float: left;
+    text-align: right;
+    clear: left;
+    padding-right: 3px;
+    vertical-align: middle;
+}
+
 INPUT.t-number {
     text-align: right;
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ChecklistDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ChecklistDemo.tml?rev=1136668&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ChecklistDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ChecklistDemo.tml Thu Jun 16 20:49:21 2011
@@ -0,0 +1,20 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
+	<t:form clientValidation="false">
+		<p>
+			<t:errors />
+		</p>
+		<p>
+			<t:label for="selected" />
+			:
+			<t:checklist t:id="selected" validate="required" model="literal:Red,Green,Blue" encoder="encoder" label="Color"/>
+
+		</p>
+
+		<p>
+			<t:submit value="literal:Submit" />
+		</p>
+	</t:form>
+
+	<p>Selected colors: ${sorted}</p>
+
+</t:border>
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java?rev=1136668&r1=1136667&r2=1136668&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java Thu Jun 16 20:49:21 2011
@@ -937,4 +937,32 @@ public class FormTests extends TapestryC
         assertTextPresent("Password: ab");
         assertTextPresent("Password2: xyz");
     }
+
+        @Test
+    public void checklist_select() throws Exception
+    {
+        openLinks("Checklist Demo");
+
+        clickAndWait(SUBMIT);
+        assertTextPresent("You must provide a value for Color.");
+
+        check("//input[@value='Green']");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("Selected colors: [Green]");
+
+        check("//input[@value='Red']");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("Selected colors: [Green, Red]");
+
+        check("//input[@value='Blue']");
+        uncheck("//input[@value='Green']");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("Selected colors: [Blue, Red]");
+    }
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ChecklistDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ChecklistDemo.java?rev=1136668&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ChecklistDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ChecklistDemo.java Thu Jun 16 20:49:21 2011
@@ -0,0 +1,34 @@
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.ValueEncoder;
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.internal.services.StringValueEncoder;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+
+import java.util.Collections;
+import java.util.List;
+
+public class ChecklistDemo
+{
+    @Property
+    @Persist
+    private List<String> selected;
+
+    public ValueEncoder getEncoder()
+    {
+        return new StringValueEncoder();
+    }
+
+    public List<String> getSorted()
+    {
+        if(selected == null)
+            return null;
+
+        final List<String> result = CollectionFactory.newList(selected);
+
+        Collections.sort(result);
+
+        return result;
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ChecklistDemo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java?rev=1136668&r1=1136667&r2=1136668&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java Thu Jun 16 20:49:21 2011
@@ -472,7 +472,10 @@ public class Index
                     new Item("AtInjectDemo", "@javax.inject.Inject Demo", "Using @javax.inject.Inject for injection"),
 
                     new Item("LinkQueryParameters", "Link Query Parameters Demo",
-                            "Providing Query Parameters directly to link components as a map of key=parameter name, value=parameter values")
+                            "Providing Query Parameters directly to link components as a map of key=parameter name, value=parameter values") ,
+
+                    new Item("ChecklistDemo", "Checklist Demo",
+                            "Use Checklist component")
 
             );