Author: ivaynberg
Date: Tue May 18 20:18:21 2010
New Revision: 945862

URL: http://svn.apache.org/viewvc?rev=945862&view=rev
Log:
WICKET-2853 ListMultipleChoice/CheckBoxMultipleChoice do not retain selected 
but disabled items
Issue: WICKET-2853

Added:
    
wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest$TestPage.html
   (with props)
    
wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest.java
   (with props)
Modified:
    
wicket/branches/wicket-1.4.x/wicket/src/main/java/org/apache/wicket/markup/html/form/ListMultipleChoice.java

Modified: 
wicket/branches/wicket-1.4.x/wicket/src/main/java/org/apache/wicket/markup/html/form/ListMultipleChoice.java
URL: 
http://svn.apache.org/viewvc/wicket/branches/wicket-1.4.x/wicket/src/main/java/org/apache/wicket/markup/html/form/ListMultipleChoice.java?rev=945862&r1=945861&r2=945862&view=diff
==============================================================================
--- 
wicket/branches/wicket-1.4.x/wicket/src/main/java/org/apache/wicket/markup/html/form/ListMultipleChoice.java
 (original)
+++ 
wicket/branches/wicket-1.4.x/wicket/src/main/java/org/apache/wicket/markup/html/form/ListMultipleChoice.java
 Tue May 18 20:18:21 2010
@@ -21,6 +21,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.StringTokenizer;
 
+import org.apache.wicket.MetaDataKey;
 import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.model.IModel;
@@ -46,6 +47,12 @@ public class ListMultipleChoice<T> exten
 {
        private static final long serialVersionUID = 1L;
 
+       /** Meta key for the retain disabled flag */
+       MetaDataKey<Boolean> RETAIN_DISABLED_META_KEY = new 
MetaDataKey<Boolean>()
+       {
+               private static final long serialVersionUID = 1L;
+       };
+
        /** Log. */
        private static final Logger log = 
LoggerFactory.getLogger(ListMultipleChoice.class);
 
@@ -261,7 +268,9 @@ public class ListMultipleChoice<T> exten
                else
                {
                        // TODO 1.3: check if its safe to return 
Collections.EMPTY_LIST here
-                       return new ArrayList<T>();
+                       ArrayList<T> result = new ArrayList<T>();
+                       addRetainedDisabled(result);
+                       return result;
                }
        }
 
@@ -297,10 +306,46 @@ public class ListMultipleChoice<T> exten
                                }
                        }
                }
+
+               addRetainedDisabled(selectedValues);
+
                return selectedValues;
 
        }
 
+       private void addRetainedDisabled(ArrayList<T> selectedValues)
+       {
+               if (isRetainDisabledSelected())
+               {
+                       Collection<T> unchangedModel = getModelObject();
+                       String selected;
+                       {
+                               StringBuilder builder = new StringBuilder();
+                               for (T t : unchangedModel)
+                               {
+                                       builder.append(t);
+                                       builder.append(";");
+                               }
+                               selected = builder.toString();
+                       }
+                       List<? extends T> choices = getChoices();
+                       for (int i = 0; i < choices.size(); i++)
+                       {
+                               final T choice = choices.get(i);
+                               if (isDisabled(choice, i, selected))
+                               {
+                                       if (unchangedModel.contains(choice))
+                                       {
+                                               if 
(!selectedValues.contains(choice))
+                                               {
+                                                       
selectedValues.add(choice);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
        /**
         * If the model object exists, it is assumed to be a Collection, and it 
is modified in-place.
         * Then {...@link Model#setObject(Object)} is called with the same 
instance: it allows the Model to
@@ -345,4 +390,37 @@ public class ListMultipleChoice<T> exten
                        setDefaultModelObject(selectedValues);
                }
        }
+
+       /**
+        * If true, choices that were selected in the model but disabled in 
rendering will be retained
+        * in the model after a form submit. Example: Choices are [1, 2, 3, 4]. 
Model collection is [2,
+        * 4]. In rendering, choices 2 and 3 are disabled ({...@link 
#isDisabled(Object, int, String)}).
+        * That means that four checkboxes are rendered, checkboxes 2 and 4 are 
checked, but 2 and 3 are
+        * not clickable. User checks 1 and unchecks 4. If this flag is off, 
the model will be updated
+        * to [1]. This is because the browser does not re-submit a disabled 
checked checkbox: it only
+        * submits [1]. Therefore Wicket will only see the [1] and update the 
model accordingly. If you
+        * set this flag to true, Wicket will check the model before updating 
to find choices that were
+        * selected but disabled. These choices will then be retained, leading 
to a new model value of
+        * [1, 2] as (probably) expected by the user. Note that this will lead 
to additional calls to
+        * {...@link #isDisabled(Object, int, String)}.
+        * 
+        * @return flag
+        */
+       public boolean isRetainDisabledSelected()
+       {
+               Boolean flag = getMetaData(RETAIN_DISABLED_META_KEY);
+               return (flag != null && flag);
+       }
+
+       /**
+        * @param retain
+        *            flag
+        * @return this
+        * @see #isRetainDisabledSelected()
+        */
+       public ListMultipleChoice<T> setRetainDisabledSelected(boolean retain)
+       {
+               setMetaData(RETAIN_DISABLED_META_KEY, (retain) ? true : null);
+               return this;
+       }
 }
\ No newline at end of file

Added: 
wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest$TestPage.html
URL: 
http://svn.apache.org/viewvc/wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest%24TestPage.html?rev=945862&view=auto
==============================================================================
--- 
wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest$TestPage.html
 (added)
+++ 
wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest$TestPage.html
 Tue May 18 20:18:21 2010
@@ -0,0 +1,11 @@
+<html 
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"; >
+    <head>  
+        <title>Wicket Quickstart Archetype Homepage</title>
+    </head>
+    <body>
+        <form wicket:id="form">
+        <div wicket:id="choices"></div>
+        <div wicket:id="choices2"></div>
+        </form>
+    </body>
+</html>

Propchange: 
wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest$TestPage.html
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest.java
URL: 
http://svn.apache.org/viewvc/wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest.java?rev=945862&view=auto
==============================================================================
--- 
wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest.java
 (added)
+++ 
wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest.java
 Tue May 18 20:18:21 2010
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.wicket.markup.html.form;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import junit.framework.TestCase;
+
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.util.tester.FormTester;
+import org.apache.wicket.util.tester.WicketTester;
+
+/**
+ * Test for the retainDisabledSelected flag on ListMultipleChoice.
+ */
+public class DisabledItemRetainingCheckBoxTest extends TestCase
+{
+       private WicketTester tester;
+
+       @Override
+       public void setUp()
+       {
+               tester = new WicketTester();
+       }
+
+       public void testRenderMyPage()
+       {
+               TestPage page = (TestPage)tester.startPage(TestPage.class);
+               tester.assertRenderedPage(TestPage.class);
+               tester.debugComponentTrees();
+               assertTrue(page.selection.contains(1));
+               assertTrue(page.selection.contains(2));
+               assertEquals(2, page.selection.size());
+       }
+
+       public void testRetainDisabledSelected_On() throws Exception
+       {
+               TestPage page = (TestPage)tester.startPage(TestPage.class);
+               FormTester form = tester.newFormTester("form");
+               form.selectMultiple("choices", new int[] { 0 }, true);
+               form.submit();
+               assertTrue(page.selection.contains(0));
+               assertTrue(page.selection.contains(1));
+               assertEquals(2, page.selection.size());
+       }
+
+       public void testRetainDisabledSelected_Off() throws Exception
+       {
+               TestPage page = (TestPage)tester.startPage(TestPage.class);
+               FormTester form = tester.newFormTester("form");
+               form.selectMultiple("choices2", new int[] { 0 }, true);
+               form.submit();
+               assertTrue(page.selection2.contains(0));
+               assertFalse(page.selection2.contains(1));
+               assertEquals(1, page.selection2.size());
+       }
+
+       public void testRetainDisabledSelected_NoSelection() throws Exception
+       {
+               TestPage page = (TestPage)tester.startPage(TestPage.class);
+               FormTester form = tester.newFormTester("form");
+               form.selectMultiple("choices", new int[] { }, true);
+               form.submit();
+               assertTrue(page.selection.contains(1));
+               assertEquals(1, page.selection.size());
+       }
+
+       public void testRetainDisabledSelected_Off_NoSelection() throws 
Exception
+       {
+               TestPage page = (TestPage)tester.startPage(TestPage.class);
+               FormTester form = tester.newFormTester("form");
+               form.selectMultiple("choices2", new int[] { }, true);
+               form.submit();
+               assertEquals(0, page.selection2.size());
+       }
+
+       public static class TestPage extends WebPage
+       {
+
+               private static final long serialVersionUID = 1L;
+
+               public Collection<Integer> selection = new 
ArrayList<Integer>(Arrays.asList(1, 2));
+               public Collection<Integer> selection2 = new 
ArrayList<Integer>(Arrays.asList(1, 2));
+
+               public TestPage(final PageParameters parameters)
+               {
+
+                       Form<TestPage> form = new Form<TestPage>("form");
+                       add(form);
+                       form.add(new CheckBoxMultipleChoice<Integer>("choices",
+                               new PropertyModel<Collection<Integer>>(this, 
"selection"), Arrays.asList(0, 1, 2))
+                       {
+                               @Override
+                               protected boolean isDisabled(Integer object, 
int index, String selected)
+                               {
+                                       return index == 1;
+                               }
+
+                       }.setRetainDisabledSelected(true));
+                       form.add(new CheckBoxMultipleChoice<Integer>("choices2",
+                               new PropertyModel<Collection<Integer>>(this, 
"selection2"), Arrays.asList(0, 1, 2))
+                       {
+                               @Override
+                               protected boolean isDisabled(Integer object, 
int index, String selected)
+                               {
+                                       return index == 1;
+                               }
+
+
+                       });
+               }
+       }
+}

Propchange: 
wicket/branches/wicket-1.4.x/wicket/src/test/java/org/apache/wicket/markup/html/form/DisabledItemRetainingCheckBoxTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain


Reply via email to