You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2021/07/05 05:47:50 UTC

[struts] 01/01: WW-5129 Supports dynamic attributes in second control

This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch WW-5129-dynamic-attributes
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 486926aa8a472f7b82ca9c8175c6eace717709f8
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Mon Jul 5 07:47:34 2021 +0200

    WW-5129 Supports dynamic attributes in second control
---
 .../resources/template/simple/doubleselect.ftl     |  5 ++-
 .../template/simple/dynamic-attributes.ftl         | 24 ++++++++---
 .../template/simple/inputtransferselect.ftl        |  8 ++--
 .../template/simple/optiontransferselect.ftl       |  3 ++
 ...ributes.ftl => prefixed-dynamic-attributes.ftl} | 18 +++++---
 core/src/main/resources/template/simple/select.ftl |  4 +-
 .../struts2/views/jsp/ui/DoubleSelectTest.java     | 17 ++++++--
 .../views/jsp/ui/InputTransferSelectTagTest.java   | 32 +++++++++++---
 .../views/jsp/ui/OptionTransferSelectTagTest.java  | 32 ++++++++++++++
 .../apache/struts2/views/jsp/ui/DoubleSelect-5.txt | 39 +++++++++++++++++
 .../struts2/views/jsp/ui/inputtransferselect-2.txt | 30 +++++++++++++
 .../views/jsp/ui/optiontransferselect-8.txt        | 50 ++++++++++++++++++++++
 12 files changed, 232 insertions(+), 30 deletions(-)

diff --git a/core/src/main/resources/template/simple/doubleselect.ftl b/core/src/main/resources/template/simple/doubleselect.ftl
index f1adf8f..e80ed40 100644
--- a/core/src/main/resources/template/simple/doubleselect.ftl
+++ b/core/src/main/resources/template/simple/doubleselect.ftl
@@ -18,6 +18,7 @@
  * under the License.
  */
 -->
+<#global dynamic_attributes_ignore = "second-"/>
 <#include "/${parameters.templateDir}/simple/select.ftl" />
 <#assign startCount = 0/>
 <#if parameters.headerKey?? && parameters.headerValue??>
@@ -60,6 +61,8 @@
 <#if parameters.doubleDisabled!false>
         disabled="disabled"<#rt/>
 </#if>
+<#include "/${parameters.templateDir}/${parameters.expandTheme}/prefixed-dynamic-attributes.ftl" />
+<@prefixedDynamicAttributes prefix="second-"/>
         >
 </select>
 <#if parameters.doubleMultiple!false>
@@ -190,4 +193,4 @@
             ${parameters.id}Temp.options[0].selected = true;
         }
     }
-</script>
\ No newline at end of file
+</script>
diff --git a/core/src/main/resources/template/simple/dynamic-attributes.ftl b/core/src/main/resources/template/simple/dynamic-attributes.ftl
index 95de4b7..c000e82 100644
--- a/core/src/main/resources/template/simple/dynamic-attributes.ftl
+++ b/core/src/main/resources/template/simple/dynamic-attributes.ftl
@@ -21,12 +21,24 @@
 <#if (parameters.dynamicAttributes?? && parameters.dynamicAttributes?size > 0)><#rt/>
 <#assign aKeys = parameters.dynamicAttributes.keySet()><#rt/>
 <#list aKeys as aKey><#rt/>
-  <#assign keyValue = parameters.dynamicAttributes.get(aKey)/>
-  <#if keyValue?is_string>
-      <#assign value = struts.translateVariables(keyValue)!keyValue/>
-  <#else>
-      <#assign value = keyValue?string/>
-  </#if>
+<#if dynamic_attributes_ignore??>
+<#if !aKey?starts_with(dynamic_attributes_ignore)>
+<#assign keyValue = parameters.dynamicAttributes.get(aKey)/>
+<#if keyValue?is_string>
+    <#assign value = struts.translateVariables(keyValue)!keyValue/>
+<#else>
+    <#assign value = keyValue?string/>
+</#if>
  ${aKey}="${value?html}"<#rt/>
+</#if>
+<#else>
+<#assign keyValue = parameters.dynamicAttributes.get(aKey)/>
+<#if keyValue?is_string>
+    <#assign value = struts.translateVariables(keyValue)!keyValue/>
+<#else>
+    <#assign value = keyValue?string/>
+</#if>
+ ${aKey}="${value?html}"<#rt/>
+</#if>
 </#list><#rt/>
 </#if><#rt/>
diff --git a/core/src/main/resources/template/simple/inputtransferselect.ftl b/core/src/main/resources/template/simple/inputtransferselect.ftl
index 0b14f51..e0bbe3c 100644
--- a/core/src/main/resources/template/simple/inputtransferselect.ftl
+++ b/core/src/main/resources/template/simple/inputtransferselect.ftl
@@ -29,7 +29,6 @@
 	<label for="leftTitle">${parameters.leftTitle}</label><br />
 </#if><#t/>
 
-
 <input type="text"<#rt/>
  name="${parameters.name!""?html}_input"<#rt/>
 <#if parameters.disabled!false>
@@ -55,6 +54,8 @@
 </#if>
 <#include "/${parameters.templateDir}/${parameters.expandTheme}/scripting-events.ftl" />
 <#include "/${parameters.templateDir}/${parameters.expandTheme}/common-attributes.ftl" />
+<#include "/${parameters.templateDir}/${parameters.expandTheme}/prefixed-dynamic-attributes.ftl" />
+<@prefixedDynamicAttributes prefix="input-"/>
 />
 
 
@@ -94,9 +95,10 @@
 <#if parameters.rightTitle?has_content><#t/>
 	<label for="rightTitle">${parameters.rightTitle}</label><br />
 </#if><#t/>
+<#global dynamic_attributes_ignore = "input-"/>
 <#include "/${parameters.templateDir}/simple/select.ftl" />
 <#if parameters.allowUpDown!true>
-<input type="button" 
+<input type="button"
 <#if parameters.headerKey?has_content>
 	onclick="moveOptionDown(document.getElementById('${parameters.id}'), 'key', '${parameters.headerKey}');"
 <#else>
@@ -106,7 +108,7 @@
 	value="${parameters.downLabel?html}"
 </#if>
 />
-<input type="button" 
+<input type="button"
 <#if parameters.headerKey?has_content>
 	onclick="moveOptionUp(document.getElementById('${parameters.id}'), 'key', '${parameters.headerKey}');"
 <#else>
diff --git a/core/src/main/resources/template/simple/optiontransferselect.ftl b/core/src/main/resources/template/simple/optiontransferselect.ftl
index 093ec22..d46ac65 100644
--- a/core/src/main/resources/template/simple/optiontransferselect.ftl
+++ b/core/src/main/resources/template/simple/optiontransferselect.ftl
@@ -28,6 +28,7 @@
 <#if parameters.leftTitle??><#t/>
 	<label for="leftTitle">${parameters.leftTitle}</label><br />
 </#if><#t/>
+<#global dynamic_attributes_ignore = "right-"/>
 <#include "/${parameters.templateDir}/simple/select.ftl" />
 <#if parameters.allowUpDownOnLeft!true>
 <input type="button"
@@ -247,6 +248,8 @@
     <#if parameters.doubleAccesskey??><#t/>
     accesskey="${parameters.doubleAccesskey?html}"
     </#if>
+	<#include "/${parameters.templateDir}/${parameters.expandTheme}/prefixed-dynamic-attributes.ftl" />
+	<@prefixedDynamicAttributes prefix="right-"/>
 >
 	<#if parameters.doubleHeaderKey?? && parameters.doubleHeaderValue??><#t/>
     <option value="${parameters.doubleHeaderKey?html}">${parameters.doubleHeaderValue?html}</option>
diff --git a/core/src/main/resources/template/simple/dynamic-attributes.ftl b/core/src/main/resources/template/simple/prefixed-dynamic-attributes.ftl
similarity index 75%
copy from core/src/main/resources/template/simple/dynamic-attributes.ftl
copy to core/src/main/resources/template/simple/prefixed-dynamic-attributes.ftl
index 95de4b7..68f2ea6 100644
--- a/core/src/main/resources/template/simple/dynamic-attributes.ftl
+++ b/core/src/main/resources/template/simple/prefixed-dynamic-attributes.ftl
@@ -18,15 +18,19 @@
  * under the License.
  */
 -->
+<#macro prefixedDynamicAttributes prefix>
 <#if (parameters.dynamicAttributes?? && parameters.dynamicAttributes?size > 0)><#rt/>
 <#assign aKeys = parameters.dynamicAttributes.keySet()><#rt/>
 <#list aKeys as aKey><#rt/>
-  <#assign keyValue = parameters.dynamicAttributes.get(aKey)/>
-  <#if keyValue?is_string>
-      <#assign value = struts.translateVariables(keyValue)!keyValue/>
-  <#else>
-      <#assign value = keyValue?string/>
-  </#if>
- ${aKey}="${value?html}"<#rt/>
+<#if aKey?starts_with(prefix)>
+<#assign keyValue = parameters.dynamicAttributes.get(aKey)/>
+<#if keyValue?is_string>
+    <#assign value = struts.translateVariables(keyValue)!keyValue/>
+<#else>
+    <#assign value = keyValue?string/>
+</#if>
+ ${aKey}="${value}"<#rt/>
+</#if>
 </#list><#rt/>
 </#if><#rt/>
+</#macro>
diff --git a/core/src/main/resources/template/simple/select.ftl b/core/src/main/resources/template/simple/select.ftl
index b0144ba..0e76058 100644
--- a/core/src/main/resources/template/simple/select.ftl
+++ b/core/src/main/resources/template/simple/select.ftl
@@ -68,7 +68,7 @@
             <#assign itemKeyStr = stack.findString('top')>
         </#if>
         <#if parameters.listValueKey??>
-          <#-- checks the valueStack for the 'valueKey.' The valueKey is then looked-up in the locale file for it's 
+          <#-- checks the valueStack for the 'valueKey.' The valueKey is then looked-up in the locale file for it's
              localized value.  This is then used as a label -->
           <#assign valueKey = stack.findString(parameters.listValueKey)!'' />
           <#if valueKey?has_content>
@@ -139,7 +139,7 @@
    <#if ( !parameters.id?? && !parameters.name??)>
      <input type="hidden" id="" name="" value="" <#rt/>
   </#if>
-  
+
 <#if parameters.disabled!false>
  disabled="disabled"<#rt/>
 </#if>
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java
index ff1a7d7..621fd4b 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java
@@ -87,13 +87,13 @@ public class DoubleSelectTest extends AbstractUITagTest {
         tag.setCssStyle("s1");
         tag.setDoubleCssClass("c2");
         tag.setDoubleCssStyle("s2");
-        
+
         tag.doStartTag();
         tag.doEndTag();
 
         verify(SelectTag.class.getResource("DoubleSelect-1.txt"));
     }
-    
+
     public void testOnchange() throws Exception {
         TestAction testAction = (TestAction) action;
 
@@ -151,7 +151,7 @@ public class DoubleSelectTest extends AbstractUITagTest {
         tag.setCssStyle("s1");
         tag.setDoubleCssClass("c2");
         tag.setDoubleCssStyle("s2");
-        
+
         tag.doStartTag();
         tag.doEndTag();
 
@@ -221,7 +221,7 @@ public class DoubleSelectTest extends AbstractUITagTest {
 
 
     }
-    
+
     public void testDoubleWithDotName() throws Exception {
         TestAction testAction = (TestAction) action;
 
@@ -285,6 +285,15 @@ public class DoubleSelectTest extends AbstractUITagTest {
         verifyGenericProperties(tag, "simple", new String[]{"value"});
     }
 
+    public void testGenericSimpleWithDynamicAttributes() throws Exception {
+        DoubleSelectTag tag = new DoubleSelectTag();
+        tag.setDynamicAttribute(null, "first-name", "firstName");
+        tag.setDynamicAttribute(null, "second-name", "secondName");
+        prepareTagGeneric(tag);
+        verifyGenericProperties(tag, "simple", new String[]{"value"});
+        verify(SelectTag.class.getResource("DoubleSelect-5.txt"));
+    }
+
     public void testGenericXhtml() throws Exception {
         DoubleSelectTag tag = new DoubleSelectTag();
         prepareTagGeneric(tag);
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java
index f2de3c0..53b3cc8 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java
@@ -18,19 +18,16 @@
  */
 package org.apache.struts2.views.jsp.ui;
 
-import org.apache.struts2.views.jsp.AbstractUITagTest;
 import org.apache.struts2.TestAction;
+import org.apache.struts2.views.jsp.AbstractUITagTest;
 
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
 
-/**
- *
- */
 public class InputTransferSelectTagTest extends AbstractUITagTest {
 
     public void testWithRequired() throws Exception {
-        List list = new ArrayList();
+        List<String> list = new ArrayList<>();
         list.add("Item One");
         list.add("Item Two");
 
@@ -46,7 +43,28 @@ public class InputTransferSelectTagTest extends AbstractUITagTest {
         tag.doStartTag();
         tag.doEndTag();
 
-        //System.out.println(writer.toString());
         verify(InputTransferSelectTagTest.class.getResource("inputtransferselect-1.txt"));
     }
+
+    public void testDynamicAttributes() throws Exception {
+        List<String> list = new ArrayList<>();
+        list.add("Item One");
+        list.add("Item Two");
+
+        TestAction testaction = (TestAction) action;
+        testaction.setCollection(list);
+
+        InputTransferSelectTag tag = new InputTransferSelectTag();
+        tag.setPageContext(pageContext);
+        tag.setDynamicAttribute(null, "input-name", "inputName");
+        tag.setDynamicAttribute(null, "collection-name", "collectionName");
+
+        tag.setName("collection");
+        tag.setList("collection");
+
+        tag.doStartTag();
+        tag.doEndTag();
+
+        verify(InputTransferSelectTagTest.class.getResource("inputtransferselect-2.txt"));
+    }
 }
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java
index 56b7b78..4278d2b 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java
@@ -523,4 +523,36 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest {
         //System.out.println(writer.toString());
         verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-7.txt"));
     }
+
+    public void testDynamicAttributes() throws Exception {
+        List left = new ArrayList();
+        left.add("Left1");
+        left.add("Left2");
+
+        List right = new ArrayList();
+        right.add("Right1");
+        right.add("Right2");
+
+        TestAction testaction = (TestAction) action;
+        testaction.setCollection(left);
+        testaction.setList2(right);
+
+        OptionTransferSelectTag tag = new OptionTransferSelectTag();
+        tag.setPageContext(pageContext);
+
+        tag.setName("collection");
+        tag.setList("collection");
+
+        tag.setDoubleName("list2");
+        tag.setDoubleList("list2");
+
+        tag.setDynamicAttribute(null, "left-name", "leftName");
+        tag.setDynamicAttribute(null, "right-name", "rightName");
+
+        tag.doStartTag();
+        tag.doEndTag();
+
+        //System.out.println(writer.toString());
+        verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-8.txt"));
+    }
 }
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/DoubleSelect-5.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/DoubleSelect-5.txt
new file mode 100644
index 0000000..23cf7f2
--- /dev/null
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/DoubleSelect-5.txt
@@ -0,0 +1,39 @@
+<select name="someName" disabled="disabled" tabindex="99" id="someId" class="cssClass1" style="cssStyle1"
+  title="someTitle" onclick="onclick1" ondblclick="ondblclick1" onmousedown="onmousedown1" onmouseup="onmouseup1"
+  onmouseover="onmouseover1" onmousemove="onmousemove1" onmouseout="onmouseout1" onfocus="onfocus1" onblur="onblur1"
+  onkeypress="onkeypress1" onkeydown="onkeydown1" onkeyup="onkeyup1" onselect="onchange"
+  onchange="someIdRedirect(this.selectedIndex)" first-name="firstName">
+  <option value="BE">Belgium</option>
+  <option value="FR" selected="selected">France</option>
+</select>
+<br />
+<select name="region" disabled="disabled" id="region" title="someTitle" second-name="secondName"></select>
+<script type="text/javascript">
+  var someIdGroup = newArray(2 + 0);
+  for (var i = 0; i < (2 + 0); i++) {
+    someIdGroup[i] = [];
+  }
+  someIdGroup[0][0] = newOption("Antwerp", "AN");
+  someIdGroup[0][1] = newOption("Gent", "GN");
+  someIdGroup[0][2] = newOption("Brugge", "BRG");
+  someIdGroup[1][0] = newOption("Paris", "PA");
+  someIdGroup[1][1] = newOption("Bordeaux", "BOR");
+  var someIdTemp = document.inputForm.region;
+  someIdRedirect(1);
+  function someIdRedirect(x) {
+    var selected = false;
+    for (var m = someIdTemp.options.length - 1; m >= 0; m--) {
+      someIdTemp.remove(m);
+    }
+    for (var i = 0; i < someIdGroup[x].length; i++) {
+      someIdTemp.options[i] = newOption(someIdGroup[x][i].text, someIdGroup[x][i].value);
+      if (someIdTemp.options[i].value == 'BOR') {
+        someIdTemp.options[i].selected = true;
+        selected = true;
+      }
+    }
+    if ((someIdTemp.options.length > 0) && (!selected)) {
+      someIdTemp.options[0].selected = true;
+    }
+  }
+</script>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/inputtransferselect-2.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/inputtransferselect-2.txt
new file mode 100644
index 0000000..264fb6b
--- /dev/null
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/inputtransferselect-2.txt
@@ -0,0 +1,30 @@
+<tr>
+  <td class="tdLabel"></td>
+  <td class="tdInput">
+    <script type="text/javascript" src="/struts/inputtransferselect.js"></script>
+    <table>
+      <tr>
+        <td><input type="text" name="collection_input" id="collection_input" input-name="inputName"/></td>
+        <td class="tdTransferSelect">
+          <input type="button" value="-&gt;"
+            onclick="addOption(document.getElementById('collection_input'),document.getElementById('collection'))" />
+          <br /><br />
+          <input type="button" value="&lt;-" onclick="removeOptions(document.getElementById('collection'))" />
+          <br /><br />
+          <input type="button" value="&lt;&lt;--" onclick="removeAllOptions(document.getElementById('collection'))" />
+          <br />
+          <br />
+        </td>
+        <td>
+          <select name="collection" size="5" id="collection" multiple="multiple" collection-name="collectionName">
+            <option value="ItemOne" selected="selected">ItemOne</option>
+            <option value="ItemTwo" selected="selected">ItemTwo</option>
+          </select>
+          <input type="hidden" id="__multiselect_collection" name="__multiselect_collection" value="" />
+          <input type="button" onclick="moveOptionDown(document.getElementById('collection'),'key','');" value="v" />
+          <input type="button" onclick="moveOptionUp(document.getElementById('collection'),'key','');" value="^" />
+        </td>
+      </tr>
+    </table>
+  </td>
+</tr>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-8.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-8.txt
new file mode 100644
index 0000000..06cfd1c
--- /dev/null
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-8.txt
@@ -0,0 +1,50 @@
+<tr>
+  <td class="tdLabel"></td>
+  <td class="tdInput">
+    <script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+    <table>
+      <tr>
+        <td>
+          <select name="collection" size="15" id="collection" multiple="multiple" left-name="leftName">
+            <option value="Left1" selected="selected">Left1</option>
+            <option value="Left2" selected="selected">Left2</option>
+          </select>
+          <input type="hidden" id="__multiselect_collection" name="__multiselect_collection" value="" />
+          <input type="button" onclick="moveOptionDown(document.getElementById('collection'),'key',''); " value="v" />
+          <input type="button" onclick="moveOptionUp(document.getElementById('collection'),'key',''); " value="^" />
+        </td>
+        <td class="tdTransferSelect">
+          <input type="button" value="<-"
+            onclick="moveSelectedOptions(document.getElementById('list2'),document.getElementById('collection'),false,'');" />
+          <br />
+          <br />
+          <input type="button" value="->"
+            onclick="moveSelectedOptions(document.getElementById('collection'),document.getElementById('list2'),false,'');" />
+          <br />
+          <br />
+          <input type="button" value="<<--"
+            onclick="moveAllOptions(document.getElementById('list2'),document.getElementById('collection'),false,'');" />
+          <br />
+          <br />
+          <input type="button" value="-->>"
+            onclick="moveAllOptions(document.getElementById('collection'),document.getElementById('list2'),false,'');" />
+          <br />
+          <br />
+          <input type="button" value="<*>"
+            onclick="selectAllOptions(document.getElementById('collection'));selectAllOptions(document.getElementById('list2'));" />
+          <br />
+          <br />
+        </td>
+        <td>
+          <select name="list2" size="15" multiple="multiple" id="list2" right-name="rightName">
+            <option value="Right1" selected="selected">Right1</option>
+            <option value="Right2" selected="selected">Right2</option>
+          </select>
+          <input type="hidden" id="__multiselect_list2" name="__multiselect_list2" value="" />
+          <input type="button" onclick="moveOptionDown(document.getElementById('list2'),'key','');" value="v" />
+          <input type="button" onclick="moveOptionUp(document.getElementById('list2'),'key','');" value="^" />
+        </td>
+      </tr>
+    </table>
+  </td>
+</tr>