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 2022/11/05 07:37:34 UTC

[struts] branch WW-5240-doubleselect created (now ac168968a)

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

lukaszlenart pushed a change to branch WW-5240-doubleselect
in repository https://gitbox.apache.org/repos/asf/struts.git


      at ac168968a WW-5240 Uses doubleOn* attributes in the template This allows assign custom JS event handlers to the second select box

This branch includes the following new commits:

     new ac168968a WW-5240 Uses doubleOn* attributes in the template This allows assign custom JS event handlers to the second select box

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[struts] 01/01: WW-5240 Uses doubleOn* attributes in the template This allows assign custom JS event handlers to the second select box

Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit ac168968a02d043ac6c36b7966ac501b0a04b1a8
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Sat Nov 5 08:31:46 2022 +0100

    WW-5240 Uses doubleOn* attributes in the template
    This allows assign custom JS event handlers to the second select box
---
 .../resources/template/simple/doubleselect.ftl     |  85 ++++++--
 core/src/main/resources/template/simple/select.ftl |   6 +-
 .../struts2/views/jsp/ui/DoubleSelectTest.java     | 233 +++++++++++++++++----
 .../apache/struts2/views/jsp/ui/DoubleSelect-6.txt |  42 ++++
 4 files changed, 299 insertions(+), 67 deletions(-)

diff --git a/core/src/main/resources/template/simple/doubleselect.ftl b/core/src/main/resources/template/simple/doubleselect.ftl
index 674680ef1..2a87e30f5 100644
--- a/core/src/main/resources/template/simple/doubleselect.ftl
+++ b/core/src/main/resources/template/simple/doubleselect.ftl
@@ -20,58 +20,99 @@
 -->
 <#global dynamic_attributes_ignore = "second-"/>
 <#include "/${parameters.templateDir}/simple/select.ftl" />
-<#assign startCount = 0/>
+<#assign startCount = 0/><#rt/>
 <#if parameters.headerKey?? && parameters.headerValue??>
-    <#assign startCount = startCount + 1/>
+    <#assign startCount = startCount + 1/><#rt/>
 </#if>
 <#if parameters.emptyOption??>
-    <#assign startCount = startCount + 1/>
+    <#assign startCount = startCount + 1/><#rt/>
 </#if>
-
 <br/>
 <select<#rt/>
-        name="${(parameters.doubleName!"")}"<#rt/>
+ name="${(parameters.doubleName!"")}"<#rt/>
 <#if parameters.disabled!false>
-        disabled="disabled"<#rt/>
+ disabled="disabled"<#rt/>
 </#if>
 <#if parameters.doubleTabindex?has_content>
-        tabindex="${parameters.doubleTabindex}"<#rt/>
+ tabindex="${parameters.doubleTabindex}"<#rt/>
 </#if>
 <#if parameters.doubleId?has_content>
-        id="${parameters.doubleId}"<#rt/>
+ id="${parameters.doubleId}"<#rt/>
 </#if>
 <#if parameters.doubleCss?has_content>
-        class="${parameters.doubleCss}"<#rt/>
+ class="${parameters.doubleCss}"<#rt/>
 </#if>
 <#if parameters.doubleStyle?has_content>
-        style="${parameters.doubleStyle}"<#rt/>
+ style="${parameters.doubleStyle}"<#rt/>
 </#if>
 <#if parameters.title?has_content>
-        title="${parameters.title}"<#rt/>
+ title="${parameters.title}"<#rt/>
 </#if>
 <#if parameters.multiple!false>
-        multiple="multiple"<#rt/>
+ multiple="multiple"<#rt/>
 </#if>
 <#if parameters.get("doubleSize")?has_content>
-        size="${parameters.get("doubleSize")}"<#rt/>
+ size="${parameters.get("doubleSize")}"<#rt/>
 </#if>
 <#if parameters.doubleMultiple!false>
-        multiple="multiple"<#rt/>
+ multiple="multiple"<#rt/>
 </#if>
 <#if parameters.doubleDisabled!false>
-        disabled="disabled"<#rt/>
+ disabled="disabled"<#rt/>
+</#if>
+<#if parameters.doubleOnclick??>
+ onclick="<#outputformat 'JavaScript'>${parameters.doubleOnclick}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOndblclick??>
+ ondblclick="<#outputformat 'JavaScript'>${parameters.doubleOndblclick}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnmousedown??>
+ onmousedown="<#outputformat 'JavaScript'>${parameters.doubleOnmousedown}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnmouseup??>
+ onmouseup="<#outputformat 'JavaScript'>${parameters.doubleOnmouseup}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnmouseover??>
+ onmouseover="<#outputformat 'JavaScript'>${parameters.doubleOnmouseover}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnmousemove??>
+ onmousemove="<#outputformat 'JavaScript'>${parameters.doubleOnmousemove}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnmouseout??>
+ onmouseout="<#outputformat 'JavaScript'>${parameters.doubleOnmouseout}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnfocus??>
+ onfocus="<#outputformat 'JavaScript'>${parameters.doubleOnfocus}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnblur??>
+ onblur="<#outputformat 'JavaScript'>${parameters.doubleOnblur}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnkeypress??>
+ onkeypress="<#outputformat 'JavaScript'>${parameters.doubleOnkeypress}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnkeydown??>
+ onkeydown="<#outputformat 'JavaScript'>${parameters.doubleOnkeydown}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnkeyup??>
+ onkeyup="<#outputformat 'JavaScript'>${parameters.doubleOnkeyup}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnselect??>
+ onselect="<#outputformat 'JavaScript'>${parameters.doubleOnselect}</#outputformat>"<#rt/>
+</#if>
+<#if parameters.doubleOnchange??>
+ onchange="<#outputformat 'JavaScript'>${parameters.doubleOnchange}</#outputformat>"<#rt/>
 </#if>
 <#include "/${parameters.templateDir}/${parameters.expandTheme}/prefixed-dynamic-attributes.ftl" />
 <@prefixedDynamicAttributes prefix="second-"/>
-        >
+>
 </select>
 <#if parameters.doubleMultiple!false>
-<input type="hidden" id="__multiselect_${parameters.doubleId}"
-       name="__multiselect_${(parameters.doubleName!"")}" value=""<#rt/>
-    <#if parameters.doubleDisabled!false>
-       disabled="disabled"<#rt/>
-    </#if>
-        />
+<input type="hidden" id="__multiselect_${parameters.doubleId}"<#rt/>
+ name="__multiselect_${(parameters.doubleName!"")}" value=""<#rt/>
+<#if parameters.doubleDisabled!false>
+ disabled="disabled"<#rt/>
+</#if>
+/><#rt/>
 </#if>
 <@s.script type="text/javascript">
     <#assign itemCount = startCount/>
diff --git a/core/src/main/resources/template/simple/select.ftl b/core/src/main/resources/template/simple/select.ftl
index 7e90c8045..c10633e5e 100644
--- a/core/src/main/resources/template/simple/select.ftl
+++ b/core/src/main/resources/template/simple/select.ftl
@@ -45,9 +45,9 @@
 <#include "/${parameters.templateDir}/${parameters.expandTheme}/dynamic-attributes.ftl" />
 >
 <#if parameters.headerKey?? && parameters.headerValue??>
-    <option value="${parameters.headerKey}"
+    <option value="${parameters.headerKey}"<#rt/>
     <#if tag.contains(parameters.nameValue, parameters.headerKey) == true>
-    selected="selected"
+    selected="selected"<#rt/>
     </#if>
     >${parameters.headerValue}</option>
 </#if>
@@ -121,9 +121,7 @@
         </#if>
     >${itemValue}</option><#lt/>
 </...@s.iterator>
-
 <#include "/${parameters.templateDir}/${parameters.expandTheme}/optgroup.ftl" />
-
 </select>
 
 <#if parameters.multiple!false>
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 ce40fa5ca..d073811a4 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
@@ -37,7 +37,7 @@ public class DoubleSelectTest extends AbstractUITagTest {
         Region antwerp = new Region("Antwerp", "AN");
         Region gent = new Region("Gent", "GN");
         Region brugge = new Region("Brugge", "BRG");
-        ArrayList belgiumRegions = new ArrayList();
+        List<Region> belgiumRegions = new ArrayList<>();
         belgiumRegions.add(antwerp);
         belgiumRegions.add(gent);
         belgiumRegions.add(brugge);
@@ -45,16 +45,16 @@ public class DoubleSelectTest extends AbstractUITagTest {
 
         Region paris = new Region("Paris", "PA");
         Region bordeaux = new Region("Bordeaux", "BOR");
-        ArrayList franceRegions = new ArrayList();
+        List<Region> franceRegions = new ArrayList<>();
         franceRegions.add(paris);
         franceRegions.add(bordeaux);
         Country france = new Country("France", "FR", franceRegions);
 
-        Collection collection = new ArrayList(2);
+        Collection<String> collection = new ArrayList<>(2);
         collection.add("AN");
         testAction.setCollection(collection);
 
-        List countries = new ArrayList();
+        List<Country> countries = new ArrayList<>();
         countries.add(belgium);
         countries.add(france);
 
@@ -103,13 +103,87 @@ public class DoubleSelectTest extends AbstractUITagTest {
                 strutsBodyTagsAreReflectionEqual(tag, freshTag));
     }
 
+    public void testDoubleJavaScriptEvents() throws Exception {
+        TestAction testAction = (TestAction) action;
+
+        Region antwerp = new Region("Antwerp", "AN");
+        Region gent = new Region("Gent", "GN");
+        Region brugge = new Region("Brugge", "BRG");
+        List<Region> belgiumRegions = new ArrayList<>();
+        belgiumRegions.add(antwerp);
+        belgiumRegions.add(gent);
+        belgiumRegions.add(brugge);
+        Country belgium = new Country("Belgium", "BE", belgiumRegions);
+
+        Region paris = new Region("Paris", "PA");
+        Region bordeaux = new Region("Bordeaux", "BOR");
+        List<Region> franceRegions = new ArrayList<>();
+        franceRegions.add(paris);
+        franceRegions.add(bordeaux);
+        Country france = new Country("France", "FR", franceRegions);
+
+        Collection<String> collection = new ArrayList<>(2);
+        collection.add("AN");
+        testAction.setCollection(collection);
+
+        List<Country> countries = new ArrayList<>();
+        countries.add(belgium);
+        countries.add(france);
+
+        testAction.setList2(countries);
+
+        DoubleSelectTag tag = new DoubleSelectTag();
+        tag.setPageContext(pageContext);
+        tag.setTheme("simple");
+        tag.setLabel("mylabel");
+        tag.setName("foo");
+        tag.setDoubleName("region");
+
+        tag.setList("list2");
+        tag.setDoubleList("regions");
+
+        tag.setListKey("iso");
+        tag.setDoubleListKey("key");
+        tag.setListValue("name");
+        tag.setDoubleListValue("name");
+
+        tag.setFormName("inputForm");
+
+        tag.setDoubleOnclick("testMe()");
+        tag.setDoubleOndblclick("testMe()");
+        tag.setDoubleOnmousedown("testMe()");
+        tag.setDoubleOnmouseup("testMe()");
+        tag.setDoubleOnmouseover("testMe()");
+        tag.setDoubleOnmousemove("testMe()");
+        tag.setDoubleOnmouseout("testMe()");
+        tag.setDoubleOnfocus("testMe()");
+        tag.setDoubleOnblur("testMe()");
+        tag.setDoubleOnkeypress("testMe()");
+        tag.setDoubleOnkeydown("testMe()");
+        tag.setDoubleOnkeyup("testMe()");
+        tag.setDoubleOnselect("testMe()");
+        tag.setDoubleOnchange("testMe()");
+
+        tag.doStartTag();
+        tag.doEndTag();
+
+        verify(SelectTag.class.getResource("DoubleSelect-6.txt"));
+
+        // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag().
+        DoubleSelectTag freshTag = new DoubleSelectTag();
+        freshTag.setPageContext(pageContext);
+        assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set.  " +
+                "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.",
+                strutsBodyTagsAreReflectionEqual(tag, freshTag));
+    }
+
     public void testDouble_clearTagStateSet() throws Exception {
         TestAction testAction = (TestAction) action;
 
         Region antwerp = new Region("Antwerp", "AN");
         Region gent = new Region("Gent", "GN");
         Region brugge = new Region("Brugge", "BRG");
-        ArrayList belgiumRegions = new ArrayList();
+        List<Region> belgiumRegions = new ArrayList<>();
         belgiumRegions.add(antwerp);
         belgiumRegions.add(gent);
         belgiumRegions.add(brugge);
@@ -117,16 +191,16 @@ public class DoubleSelectTest extends AbstractUITagTest {
 
         Region paris = new Region("Paris", "PA");
         Region bordeaux = new Region("Bordeaux", "BOR");
-        ArrayList franceRegions = new ArrayList();
+        ArrayList<Region> franceRegions = new ArrayList<>();
         franceRegions.add(paris);
         franceRegions.add(bordeaux);
         Country france = new Country("France", "FR", franceRegions);
 
-        Collection collection = new ArrayList(2);
+        Collection<String> collection = new ArrayList<>(2);
         collection.add("AN");
         testAction.setCollection(collection);
 
-        List countries = new ArrayList();
+        List<Country> countries = new ArrayList<>();
         countries.add(belgium);
         countries.add(france);
 
@@ -178,13 +252,90 @@ public class DoubleSelectTest extends AbstractUITagTest {
                 strutsBodyTagsAreReflectionEqual(tag, freshTag));
     }
 
+    public void testDoubleJavaScriptEvents_clearTagStateSet() throws Exception {
+        TestAction testAction = (TestAction) action;
+
+        Region antwerp = new Region("Antwerp", "AN");
+        Region gent = new Region("Gent", "GN");
+        Region brugge = new Region("Brugge", "BRG");
+        List<Region> belgiumRegions = new ArrayList<>();
+        belgiumRegions.add(antwerp);
+        belgiumRegions.add(gent);
+        belgiumRegions.add(brugge);
+        Country belgium = new Country("Belgium", "BE", belgiumRegions);
+
+        Region paris = new Region("Paris", "PA");
+        Region bordeaux = new Region("Bordeaux", "BOR");
+        ArrayList<Region> franceRegions = new ArrayList<>();
+        franceRegions.add(paris);
+        franceRegions.add(bordeaux);
+        Country france = new Country("France", "FR", franceRegions);
+
+        Collection<String> collection = new ArrayList<>(2);
+        collection.add("AN");
+        testAction.setCollection(collection);
+
+        List<Country> countries = new ArrayList<>();
+        countries.add(belgium);
+        countries.add(france);
+
+        testAction.setList2(countries);
+
+        DoubleSelectTag tag = new DoubleSelectTag();
+        tag.setPerformClearTagStateForTagPoolingServers(true);  // Explicitly request tag state clearing.
+        tag.setPageContext(pageContext);
+        tag.setTheme("simple");
+        tag.setLabel("mylabel");
+        tag.setName("foo");
+        tag.setDoubleName("region");
+
+        tag.setList("list2");
+        tag.setDoubleList("regions");
+
+        tag.setListKey("iso");
+        tag.setDoubleListKey("key");
+        tag.setListValue("name");
+        tag.setDoubleListValue("name");
+
+        tag.setFormName("inputForm");
+
+        tag.setDoubleOnclick("testMe()");
+        tag.setDoubleOndblclick("testMe()");
+        tag.setDoubleOnmousedown("testMe()");
+        tag.setDoubleOnmouseup("testMe()");
+        tag.setDoubleOnmouseover("testMe()");
+        tag.setDoubleOnmousemove("testMe()");
+        tag.setDoubleOnmouseout("testMe()");
+        tag.setDoubleOnfocus("testMe()");
+        tag.setDoubleOnblur("testMe()");
+        tag.setDoubleOnkeypress("testMe()");
+        tag.setDoubleOnkeydown("testMe()");
+        tag.setDoubleOnkeyup("testMe()");
+        tag.setDoubleOnselect("testMe()");
+        tag.setDoubleOnchange("testMe()");
+
+        tag.doStartTag();
+        setComponentTagClearTagState(tag, true);  // Ensure component tag state clearing is set true (to match tag).
+        tag.doEndTag();
+
+        verify(SelectTag.class.getResource("DoubleSelect-6.txt"));
+
+        // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag().
+        DoubleSelectTag freshTag = new DoubleSelectTag();
+        freshTag.setPerformClearTagStateForTagPoolingServers(true);
+        freshTag.setPageContext(pageContext);
+        assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set.  " +
+                "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.",
+                strutsBodyTagsAreReflectionEqual(tag, freshTag));
+    }
+
     public void testOnchange() throws Exception {
         TestAction testAction = (TestAction) action;
 
         Region antwerp = new Region("Antwerp", "AN");
         Region gent = new Region("Gent", "GN");
         Region brugge = new Region("Brugge", "BRG");
-        ArrayList belgiumRegions = new ArrayList();
+        List<Region> belgiumRegions = new ArrayList<>();
         belgiumRegions.add(antwerp);
         belgiumRegions.add(gent);
         belgiumRegions.add(brugge);
@@ -192,16 +343,16 @@ public class DoubleSelectTest extends AbstractUITagTest {
 
         Region paris = new Region("Paris", "PA");
         Region bordeaux = new Region("Bordeaux", "BOR");
-        ArrayList franceRegions = new ArrayList();
+        List<Region> franceRegions = new ArrayList<>();
         franceRegions.add(paris);
         franceRegions.add(bordeaux);
         Country france = new Country("France", "FR", franceRegions);
 
-        Collection collection = new ArrayList(2);
+        Collection<String> collection = new ArrayList<>(2);
         collection.add("AN");
         testAction.setCollection(collection);
 
-        List countries = new ArrayList();
+        List<Country> countries = new ArrayList<>();
         countries.add(belgium);
         countries.add(france);
 
@@ -255,7 +406,7 @@ public class DoubleSelectTest extends AbstractUITagTest {
         Region antwerp = new Region("Antwerp", "AN");
         Region gent = new Region("Gent", "GN");
         Region brugge = new Region("Brugge", "BRG");
-        ArrayList belgiumRegions = new ArrayList();
+        List<Region> belgiumRegions = new ArrayList<>();
         belgiumRegions.add(antwerp);
         belgiumRegions.add(gent);
         belgiumRegions.add(brugge);
@@ -263,16 +414,16 @@ public class DoubleSelectTest extends AbstractUITagTest {
 
         Region paris = new Region("Paris", "PA");
         Region bordeaux = new Region("Bordeaux", "BOR");
-        ArrayList franceRegions = new ArrayList();
+        List<Region> franceRegions = new ArrayList<>();
         franceRegions.add(paris);
         franceRegions.add(bordeaux);
         Country france = new Country("France", "FR", franceRegions);
 
-        Collection collection = new ArrayList(2);
+        Collection<String> collection = new ArrayList<>(2);
         collection.add("AN");
         testAction.setCollection(collection);
 
-        List countries = new ArrayList();
+        List<Country> countries = new ArrayList<>();
         countries.add(belgium);
         countries.add(france);
 
@@ -330,7 +481,7 @@ public class DoubleSelectTest extends AbstractUITagTest {
         Region antwerp = new Region("Antwerp", "AN");
         Region gent = new Region("Gent", "GN");
         Region brugge = new Region("Brugge", "BRG");
-        ArrayList belgiumRegions = new ArrayList();
+        List<Region> belgiumRegions = new ArrayList<>();
         belgiumRegions.add(antwerp);
         belgiumRegions.add(gent);
         belgiumRegions.add(brugge);
@@ -338,16 +489,16 @@ public class DoubleSelectTest extends AbstractUITagTest {
 
         Region paris = new Region("Paris", "PA");
         Region bordeaux = new Region("Bordeaux", "BOR");
-        ArrayList franceRegions = new ArrayList();
+        List<Region> franceRegions = new ArrayList<>();
         franceRegions.add(paris);
         franceRegions.add(bordeaux);
         Country france = new Country("France", "FR", franceRegions);
 
-        Collection collection = new ArrayList(2);
+        Collection<String> collection = new ArrayList<>(2);
         collection.add("AN");
         testAction.setCollection(collection);
 
-        List countries = new ArrayList();
+        List<Country> countries = new ArrayList<>();
         countries.add(belgium);
         countries.add(france);
 
@@ -398,7 +549,7 @@ public class DoubleSelectTest extends AbstractUITagTest {
         Region antwerp = new Region("Antwerp", "AN");
         Region gent = new Region("Gent", "GN");
         Region brugge = new Region("Brugge", "BRG");
-        ArrayList belgiumRegions = new ArrayList();
+        List<Region> belgiumRegions = new ArrayList<>();
         belgiumRegions.add(antwerp);
         belgiumRegions.add(gent);
         belgiumRegions.add(brugge);
@@ -406,16 +557,16 @@ public class DoubleSelectTest extends AbstractUITagTest {
 
         Region paris = new Region("Paris", "PA");
         Region bordeaux = new Region("Bordeaux", "BOR");
-        ArrayList franceRegions = new ArrayList();
+        List<Region> franceRegions = new ArrayList<>();
         franceRegions.add(paris);
         franceRegions.add(bordeaux);
         Country france = new Country("France", "FR", franceRegions);
 
-        Collection collection = new ArrayList(2);
+        Collection<String> collection = new ArrayList<>(2);
         collection.add("AN");
         testAction.setCollection(collection);
 
-        List countries = new ArrayList();
+        List<Country> countries = new ArrayList<>();
         countries.add(belgium);
         countries.add(france);
 
@@ -468,7 +619,7 @@ public class DoubleSelectTest extends AbstractUITagTest {
         Region antwerp = new Region("Antwerp", "AN");
         Region gent = new Region("Gent", "GN");
         Region brugge = new Region("Brugge", "BRG");
-        ArrayList belgiumRegions = new ArrayList();
+        List<Region> belgiumRegions = new ArrayList<>();
         belgiumRegions.add(antwerp);
         belgiumRegions.add(gent);
         belgiumRegions.add(brugge);
@@ -476,16 +627,16 @@ public class DoubleSelectTest extends AbstractUITagTest {
 
         Region paris = new Region("Paris", "PA");
         Region bordeaux = new Region("Bordeaux", "BOR");
-        ArrayList franceRegions = new ArrayList();
+        List<Region> franceRegions = new ArrayList<>();
         franceRegions.add(paris);
         franceRegions.add(bordeaux);
         Country france = new Country("France", "FR", franceRegions);
 
-        Collection collection = new ArrayList(2);
+        Collection<String> collection = new ArrayList<>(2);
         collection.add("AN");
         testAction.setCollection(collection);
 
-        List countries = new ArrayList();
+        List<Country> countries = new ArrayList<>();
         countries.add(belgium);
         countries.add(france);
 
@@ -532,7 +683,7 @@ public class DoubleSelectTest extends AbstractUITagTest {
         Region antwerp = new Region("Antwerp", "AN");
         Region gent = new Region("Gent", "GN");
         Region brugge = new Region("Brugge", "BRG");
-        ArrayList belgiumRegions = new ArrayList();
+        List<Region> belgiumRegions = new ArrayList<>();
         belgiumRegions.add(antwerp);
         belgiumRegions.add(gent);
         belgiumRegions.add(brugge);
@@ -540,16 +691,16 @@ public class DoubleSelectTest extends AbstractUITagTest {
 
         Region paris = new Region("Paris", "PA");
         Region bordeaux = new Region("Bordeaux", "BOR");
-        ArrayList franceRegions = new ArrayList();
+        List<Region> franceRegions = new ArrayList<>();
         franceRegions.add(paris);
         franceRegions.add(bordeaux);
         Country france = new Country("France", "FR", franceRegions);
 
-        Collection collection = new ArrayList(2);
+        Collection<String> collection = new ArrayList<>(2);
         collection.add("AN");
         testAction.setCollection(collection);
 
-        List countries = new ArrayList();
+        List<Country> countries = new ArrayList<>();
         countries.add(belgium);
         countries.add(france);
 
@@ -619,7 +770,7 @@ public class DoubleSelectTest extends AbstractUITagTest {
         Region antwerp = new Region("Antwerp", "AN");
         Region gent = new Region("Gent", "GN");
         Region brugge = new Region("Brugge", "BRG");
-        ArrayList belgiumRegions = new ArrayList();
+        List<Region> belgiumRegions = new ArrayList<>();
         belgiumRegions.add(antwerp);
         belgiumRegions.add(gent);
         belgiumRegions.add(brugge);
@@ -627,18 +778,18 @@ public class DoubleSelectTest extends AbstractUITagTest {
 
         Region paris = new Region("Paris", "PA");
         Region bordeaux = new Region("Bordeaux", "BOR");
-        ArrayList franceRegions = new ArrayList();
+        List<Region> franceRegions = new ArrayList<>();
         franceRegions.add(paris);
         franceRegions.add(bordeaux);
         Country france = new Country("France", "FR", franceRegions);
 
-        Collection collection = new ArrayList(2);
+        Collection<String> collection = new ArrayList<>(2);
         collection.add("AN");
         testAction.setCollection(collection);
 
         tag.setList("collection");
 
-        List countries = new ArrayList();
+        List<Country> countries = new ArrayList<>();
         countries.add(belgium);
         countries.add(france);
 
@@ -659,12 +810,12 @@ public class DoubleSelectTest extends AbstractUITagTest {
         tag.setFormName("inputForm");
     }
 
-    public class Country {
+    public static class Country {
         String name;
         String iso;
-        Collection regions;
+        Collection<Region> regions;
 
-        public Country(String name, String iso, Collection regions) {
+        public Country(String name, String iso, Collection<Region> regions) {
             this.name = name;
             this.iso = iso;
             this.regions = regions;
@@ -678,12 +829,12 @@ public class DoubleSelectTest extends AbstractUITagTest {
             return iso;
         }
 
-        public Collection getRegions() {
+        public Collection<Region> getRegions() {
             return regions;
         }
     }
 
-    public class Region {
+    public static class Region {
         String name;
         String key;
 
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/DoubleSelect-6.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/DoubleSelect-6.txt
new file mode 100644
index 000000000..a0a51aa49
--- /dev/null
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/DoubleSelect-6.txt
@@ -0,0 +1,42 @@
+<select name="foo" id="foo" onchange="fooRedirect(this.selectedIndex)">
+    <option value="BE">Belgium</option>
+    <option value="FR">France</option>
+</select>
+
+<br/>
+<select name="region" id="region" onclick="testMe()" ondblclick="testMe()" onmousedown="testMe()" onmouseup="testMe()" onmouseover="testMe()" onmousemove="testMe()" onmouseout="testMe()" onfocus="testMe()" onblur="testMe()" onkeypress="testMe()" onkeydown="testMe()" onselect="testMe()" onchange="testMe()">
+</select>
+<script type="text/javascript"  >
+    var fooGroup = new Array(2 + 0);
+    for (var i = 0; i < (2 + 0); i++) {
+        fooGroup[i] = [];
+    }
+
+    fooGroup[0][0] = new Option("Antwerp", "AN");
+
+    fooGroup[0][1] = new Option("Gent", "GN");
+
+    fooGroup[0][2] = new Option("Brugge", "BRG");
+
+    fooGroup[1][0] = new Option("Paris", "PA");
+
+    fooGroup[1][1] = new Option("Bordeaux", "BOR");
+
+
+    var fooTemp = document.inputForm.region;
+    fooRedirect(0);
+    function fooRedirect(x) {
+        var selected = false;
+        for (var m = fooTemp.options.length - 1; m >= 0; m--) {
+            fooTemp.remove(m);
+        }
+
+        for (var i = 0; i < fooGroup[x].length; i++) {
+            fooTemp.options[i] = new Option(fooGroup[x][i].text, fooGroup[x][i].value);
+        }
+
+        if ((fooTemp.options.length > 0) && (! selected)) {
+            fooTemp.options[0].selected = true;
+        }
+    }
+</script>