Author: hlship
Date: Fri May 25 19:23:00 2007
New Revision: 541848

URL: http://svn.apache.org/viewvc?view=rev&rev=541848
Log:
TAPESTRY-1373: Recreate T4's Palette component for T5
Keep options sorted in the available list, and in the selected list (unless 
reorder is enabled).

Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/palette.js
    
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/PaletteDemo.html
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/ProgrammingLanguage.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PaletteDemo.java

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java?view=diff&rev=541848&r1=541847&r2=541848
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
 Fri May 25 19:23:00 2007
@@ -49,9 +49,21 @@
  * right is "selected". Elements can be moved between the lists by clicking a 
button, or double
  * clicking an option (and eventually, via drag and drop).
  * <p>
+ * The items in the available list are kept ordered as per [EMAIL PROTECTED] 
SelectModel} order. When items are
+ * moved from the selected list to the available list, they items are inserted 
back into their
+ * proper positions.
+ * <p>
+ * The Palette may operate in normal or re-orderable mode, controlled by the 
reorder parameter.
+ * <p>
+ * In normal mode, the items in the selected list are kept in the same 
"natural" order as the items
+ * in the available list.
+ * <p>
+ * In re-order mode, items moved to the selected list are simply added to the 
bottom of the list. In addition,
+ * two extra buttons appear to move items up and down within the selected list.
+ * <p>
  * Much of the look and feel is driven by CSS, the default Tapestry CSS is 
used to set up the
  * columns, etc. By default, the &lt;select&gt; element's widths are driven by 
the length of the
- * longest &lt;option&gt;, and it is common to override this:
+ * longest &lt;option&gt;, and it is common to override this to a fixed value:
  * 
  * <pre>
  * &lt;style&gt;
@@ -60,6 +72,10 @@
  * </pre>
  * 
  * <p>
+ * This ensures that the two columns are the same width, and that the column 
widths don't change
+ * as items move back and forth.
+ * 
+ * <p>
  * Option groups within the [EMAIL PROTECTED] SelectModel} will be rendered, 
but are not supported by the many
  * browsers, and are not fully handled on the client side.
  */
@@ -338,11 +354,24 @@
             sep = ";";
         }
 
+        StringBuilder naturalOrder = new StringBuilder();
+        sep = "";
+        for (String value : _naturalOrder)
+        {
+            naturalOrder.append(sep);
+            naturalOrder.append(value);
+            sep = ";";
+        }
+
         String clientId = getClientId();
 
         _renderSupport.addScriptLink(_paletteLibrary);
 
-        _renderSupport.addScript("new Tapestry.Palette('%s', %s);", clientId, 
_reorder);
+        _renderSupport.addScript(
+                "new Tapestry.Palette('%s', %s, '%s');",
+                clientId,
+                _reorder,
+                naturalOrder);
 
         writer.element(
                 "input",
@@ -357,17 +386,22 @@
         writer.end();
     }
 
+    /** Prevent the body from rendering. */
     boolean beforeRenderBody()
     {
         return false;
     }
 
+    /** The natural order of elements, in terms of their client ids. */
+    private List<String> _naturalOrder;
+
     @SuppressWarnings("unchecked")
     void setupRender(MarkupWriter writer)
     {
         _valueToOptionModel = newMap();
         _availableOptions = newList();
         _selectedOptions = newList();
+        _naturalOrder = newList();
         _renderer = new SelectModelRenderer(writer, _encoder);
 
         final Set selectedSet = newSet(getSelected());
@@ -390,6 +424,10 @@
 
                 boolean isSelected = selectedSet.contains(value);
 
+                String clientValue = toClient(value);
+
+                _naturalOrder.add(clientValue);
+
                 if (isSelected)
                 {
                     _selectedOptions.add(optionModel);
@@ -409,6 +447,11 @@
     int getSize()
     {
         return _size;
+    }
+
+    String toClient(Object value)
+    {
+        return _encoder.toClient(value);
     }
 
     List<Object> getSelected()

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/palette.js
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/palette.js?view=diff&rev=541848&r1=541847&r2=541848
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/palette.js
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/palette.js
 Fri May 25 19:23:00 2007
@@ -2,7 +2,7 @@
 
 Tapestry.Palette.prototype = {
 
-  initialize : function(id, reorder) {
+  initialize : function(id, reorder, naturalOrder) {
     this.reorder = reorder;
     // The SELECT elements
 
@@ -23,6 +23,10 @@
            this.down = $(id + ":down");
          }
          
+         this.valueToOrderIndex = {};
+         
+         naturalOrder.split(this.sep).each(function (value, i) { 
this.valueToOrderIndex[value] = i; }.bind(this));
+    
          this.bindEvents();   
   },  
 
@@ -83,23 +87,23 @@
   },
   
   selectClicked : function(event) {
-     this.transferOptions(this.avail, this.selected);
+     this.transferOptions(this.avail, this.selected, this.reorder);
   },
   
   deselectClicked : function(event) {
-     this.transferOptions(this.selected, this.avail);
+     this.transferOptions(this.selected, this.avail, false);
   }, 
   
-  transferOptions : function (from, to) {
-    
+  transferOptions : function (from, to, atEnd) {
+    // from: SELECT to move option(s) from (those that are selected)
+    // to: SELECT to add option(s) to
+    // atEnd : if true, add at end, otherwise by natural sort order
     var toOptions = $A(to.options);
-    var lastSelected = this.indexOfLastSelection(to);
-    var before = lastSelected < 0 ? null : 
toOptions[toOptions.indexOf(lastSelected) + 1];
-    
+     
     toOptions.each(function(option) { option.selected = false; });
         
     var movers = this.removeSelectedOptions(from);
-    this.moveOptions(movers, to, before);
+    this.moveOptions(movers, to, atEnd);
     
   },
   
@@ -116,8 +120,8 @@
 
     var before = pos < 0 ? this.selected.options[0] : 
this.selected.options[pos];
  
-    this.moveOptions(movers, this.selected, before);
-    
+    this.reorderSelected(movers, before);
+   
     Event.stop(event);
   },
   
@@ -136,22 +140,45 @@
     return movers;
   },
   
-  moveOptions : function(movers, to, before) {
-    movers.each(function(option) { to.add(option, before); }.bind(this));
+  moveOptions : function(movers, to, atEnd) {
+  
+    movers.each(function(option) { this.moveOption(option, to, atEnd); 
}.bind(this));
     
     this.updateHidden();  
     this.updateButtons();
   },
   
+  moveOption : function(option, to, atEnd) {
+    var before = null;
+    
+    if (!atEnd) {
+      var optionOrder = this.valueToOrderIndex[option.value]; 
+      var candidate = $A(to.options).find(function (o) {
+            return this.valueToOrderIndex[o.value] > optionOrder;
+            }.bind(this));
+      if (candidate) before = candidate;
+    }
+  
+    to.add(option, before);
+  },
+  
   moveDownClicked : function(event) {
     var lastSelected = $A(this.selected.options).reverse(true).find(function 
(option) { return option.selected; });
     var lastPos = lastSelected.index;
     var before = this.selected.options[lastPos + 2];
         
-    this.moveOptions(this.removeSelectedOptions(this.selected), this.selected, 
before);
+    // TODO: needs to be "reorder options"
+    this.reorderSelected(this.removeSelectedOptions(this.selected), before);
     
     Event.stop(event);
-  }
+  },
+  
+  reorderSelected : function(movers,  before) {
+    movers.each(function(option) { this.selected.add(option, before); 
}.bind(this));
+    
+    this.updateHidden();  
+    this.updateButtons();
+  },  
 };
 
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/PaletteDemo.html
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/PaletteDemo.html?view=diff&rev=541848&r1=541847&r2=541848
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/PaletteDemo.html 
(original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/PaletteDemo.html 
Fri May 25 19:23:00 2007
@@ -8,14 +8,23 @@
 
 
   <t:form>
+    <div>
+      <t:checkbox t:id="reorder" label="Enable Reorder"/>
+      <t:label for="reorder"/>
+    </div>
+
     <div class="t-beaneditor">
-      <t:palette t:id="languages" model="languageModel" reorder="true" 
encoder="languageEncoder"/>
+
+
+      <t:palette t:id="languages" model="languageModel" reorder="reorder" 
encoder="languageEncoder"/>
       <br/>
       <input type="submit"/>
     </div>
   </t:form>
+
+  <p> Selected Languages: ${languages} </p>
   
   <p>
-    Selected Languages: ${languages}
+    [ <t:actionlink t:id="reset">reset</t:actionlink> ]
   </p>
 </html>

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?view=diff&rev=541848&r1=541847&r2=541848
==============================================================================
--- 
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
 Fri May 25 19:23:00 2007
@@ -951,6 +951,7 @@
     {
         open(BASE_URL);
         clickAndWait("link=Palette Demo");
+        clickAndWait("link=reset");
 
         addSelection("languages:avail", "label=Haskell");
         addSelection("languages:avail", "label=Javascript");
@@ -972,19 +973,26 @@
         addSelection("languages:avail", "label=Ruby");
 
         click("languages:select");
+        
+        clickAndWait("//[EMAIL PROTECTED]'submit']");
+        
+        assertTextPresent("[ERLANG, HASKELL, JAVA, LISP, ML, PERL, PYTHON, 
RUBY]");
+  
+        check("reorder");
+        clickAndWait("//[EMAIL PROTECTED]'submit']");
+        
+        addSelection("languages", "label=Ruby");
 
-        removeSelection("languages", "label=Perl");
-        removeSelection("languages", "label=Erlang");
-        removeSelection("languages", "label=Java");
-        removeSelection("languages", "label=Lisp");
-        removeSelection("languages", "label=Ml");
-        removeSelection("languages", "label=Python");
-
-        for (int i = 0; i < 7; i++)
+        for (int i = 0; i < 6; i++)
             click("languages:up");
 
+        removeSelection("languages", "label=Ruby");
+        addSelection("languages", "label=Perl");
+
+        click("languages:down");
+        
         clickAndWait("//[EMAIL PROTECTED]'submit']");
 
-        assertTextPresent("Selected Languages: [RUBY, HASKELL, PERL, ERLANG, 
JAVA, LISP, ML, PYTHON]");
+        assertTextPresent("[ERLANG, RUBY, HASKELL, JAVA, LISP, ML, PYTHON, 
PERL]");
     }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/ProgrammingLanguage.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/ProgrammingLanguage.java?view=diff&rev=541848&r1=541847&r2=541848
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/ProgrammingLanguage.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/ProgrammingLanguage.java
 Fri May 25 19:23:00 2007
@@ -4,7 +4,7 @@
 // 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
+// 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,
@@ -16,5 +16,5 @@
 
 public enum ProgrammingLanguage
 {
-    ADA, ASSEMBLY, C, PERL, ERLANG, HASKELL, JAVA, JAVASCRIPT, LISP, ML, 
PYTHON, RUBY, SCALA, SCHEME
+    ADA, ASSEMBLY, C, ERLANG, HASKELL, JAVA, JAVASCRIPT, LISP, ML, PERL, 
PYTHON, RUBY, SCALA, SCHEME
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PaletteDemo.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PaletteDemo.java?view=diff&rev=541848&r1=541847&r2=541848
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PaletteDemo.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PaletteDemo.java
 Fri May 25 19:23:00 2007
@@ -33,6 +33,19 @@
     @Persist
     private List<ProgrammingLanguage> _languages;
 
+    @Persist
+    private boolean _reorder;
+
+    public boolean isReorder()
+    {
+        return _reorder;
+    }
+
+    public void setReorder(boolean reorder)
+    {
+        _reorder = reorder;
+    }
+
     public List<ProgrammingLanguage> getLanguages()
     {
         return _languages;
@@ -52,5 +65,11 @@
     public ValueEncoder getLanguageEncoder()
     {
         return new EnumValueEncoder(ProgrammingLanguage.class);
+    }
+
+    void onActionFromReset()
+    {
+        _reorder = false;
+        _languages = null;
     }
 }


Reply via email to