mirror of
https://github.com/apache/struts.git
synced 2026-08-05 22:56:59 +00:00
Merge pull request #502 from apache/WW-5129-dynamic-attributes
[WW-5129] Supports dynamic attributes in second control
This commit is contained in:
@@ -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>
|
||||
</script>
|
||||
|
||||
@@ -18,15 +18,22 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<#function acceptKey(key)>
|
||||
<#if dynamic_attributes_ignore??>
|
||||
<#return !key?starts_with(dynamic_attributes_ignore) >
|
||||
<#else>
|
||||
<#return true>
|
||||
</#if>
|
||||
</#function>
|
||||
<#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>
|
||||
<#list aKeys?filter(acceptKey) 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}"<#rt/>
|
||||
</#list><#rt/>
|
||||
</#if><#rt/>
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
<label for="leftTitle">${parameters.leftTitle}</label><br />
|
||||
</#if><#t/>
|
||||
|
||||
|
||||
<input type="text"<#rt/>
|
||||
name="${parameters.name!""}_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}"
|
||||
</#if>
|
||||
/>
|
||||
<input type="button"
|
||||
<input type="button"
|
||||
<#if parameters.headerKey?has_content>
|
||||
onclick="moveOptionUp(document.getElementById('${parameters.id}'), 'key', '${parameters.headerKey}');"
|
||||
<#else>
|
||||
|
||||
@@ -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="<#outputformat 'JavaScript'>${parameters.doubleAccesskey}</#outputformat>"
|
||||
</#if>
|
||||
<#include "/${parameters.templateDir}/${parameters.expandTheme}/prefixed-dynamic-attributes.ftl" />
|
||||
<@prefixedDynamicAttributes prefix="right-"/>
|
||||
>
|
||||
<#if parameters.doubleHeaderKey?? && parameters.doubleHeaderValue??><#t/>
|
||||
<option value="${parameters.doubleHeaderKey}">${parameters.doubleHeaderValue}</option>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<#--
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
<#macro prefixedDynamicAttributes prefix>
|
||||
<#if (parameters.dynamicAttributes?? && parameters.dynamicAttributes?size > 0)><#rt/>
|
||||
<#assign aKeys = parameters.dynamicAttributes.keySet()><#rt/>
|
||||
<#list aKeys as aKey><#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?keep_after(prefix)}="${value}"<#rt/>
|
||||
</#if>
|
||||
</#list><#rt/>
|
||||
</#if><#rt/>
|
||||
</#macro>
|
||||
@@ -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>
|
||||
|
||||
+2
-11
@@ -113,12 +113,7 @@ public class FreemarkerResultMockedTest extends StrutsInternalTestCase {
|
||||
ActionMapping mapping = container.getInstance(ActionMapper.class).getMapping(request, configurationManager);
|
||||
dispatcher.serviceAction(request, response, mapping);
|
||||
|
||||
String expectedJDK17 =
|
||||
"<input type=\"text\" name=\"test\" value=\"\" id=\"test\" placeholder=\"input\" foo=\"bar\"/>"
|
||||
+ "<input type=\"text\" name=\"test\" value=\"\" id=\"test\" placeholder=\"input\" foo=\"bar\"/>"
|
||||
+ "<input type=\"text\" name=\"test\" value=\"\" id=\"test\" break=\"true\"/>"
|
||||
+ "<input type=\"text\" name=\"required\" value=\"\" id=\"required\" required=\"true\"/>";
|
||||
String expectedJDK18 =
|
||||
String expected =
|
||||
"<input type=\"text\" name=\"test\" value=\"\" id=\"test\" foo=\"bar\" placeholder=\"input\"/>"
|
||||
+ "<input type=\"text\" name=\"test\" value=\"\" id=\"test\" foo=\"bar\" placeholder=\"input\"/>"
|
||||
+ "<input type=\"text\" name=\"test\" value=\"\" id=\"test\" break=\"true\"/>"
|
||||
@@ -126,11 +121,7 @@ public class FreemarkerResultMockedTest extends StrutsInternalTestCase {
|
||||
|
||||
String result = stringWriter.toString();
|
||||
|
||||
if (result.contains("id=\"test\" foo=\"bar\"")) {
|
||||
assertEquals(expectedJDK18, result);
|
||||
} else {
|
||||
assertEquals(expectedJDK17, result);
|
||||
}
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
public void testManualListInTemplate() throws Exception {
|
||||
|
||||
@@ -287,6 +287,15 @@ public class DoubleSelectTest extends AbstractUITagTest {
|
||||
verifyGenericProperties(tag, "simple", new String[]{"value"});
|
||||
}
|
||||
|
||||
public void testGenericSimpleWithDynamicAttributes() throws Exception {
|
||||
DoubleSelectTag tag = new DoubleSelectTag();
|
||||
tag.setDynamicAttribute(null, "select-name", "firstName");
|
||||
tag.setDynamicAttribute(null, "second-select-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);
|
||||
@@ -379,4 +388,4 @@ public class DoubleSelectTest extends AbstractUITagTest {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -47,7 +44,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-collection-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"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,4 +525,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, "collection", "leftName");
|
||||
tag.setDynamicAttribute(null, "right-collection", "rightName");
|
||||
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
|
||||
//System.out.println(writer.toString());
|
||||
verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-8.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)" select-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" select-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>
|
||||
@@ -0,0 +1,30 @@
|
||||
<tr>
|
||||
<td class="tdLabel"></td>
|
||||
<td class="tdInput">
|
||||
<script type="text/javascript" src="/static/inputtransferselect.js"></script>
|
||||
<table>
|
||||
<tr>
|
||||
<td><input type="text" name="collection_input" id="collection_input" collection-name="inputName" /></td>
|
||||
<td class="tdTransferSelect">
|
||||
<input type="button" value="->"
|
||||
onclick="addOption(document.getElementById('collection_input'),document.getElementById('collection'))" />
|
||||
<br /><br />
|
||||
<input type="button" value="<-" onclick="removeOptions(document.getElementById('collection'))" />
|
||||
<br /><br />
|
||||
<input type="button" value="<<--" 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>
|
||||
@@ -0,0 +1,50 @@
|
||||
<tr>
|
||||
<td class="tdLabel"></td>
|
||||
<td class="tdInput">
|
||||
<script type="text/javascript" src="/static/optiontransferselect.js"></script>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<select name="collection" size="15" id="collection" multiple="multiple" collection="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" collection="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>
|
||||
Reference in New Issue
Block a user