mirror of
https://github.com/apache/struts.git
synced 2026-08-05 22:56:59 +00:00
Merge pull request #636 from apache/WW-5260-global-submit-unchecked
[WW-5260] Introduces a constant to set submitUnchecked attribute of checkbox tag globally
This commit is contained in:
@@ -379,7 +379,7 @@ public final class StrutsConstants {
|
||||
public static final String STRUTS_CONVERTER_FILE_PROCESSOR = "struts.converter.file.processor";
|
||||
public static final String STRUTS_CONVERTER_ANNOTATION_PROCESSOR = "struts.converter.annotation.processor";
|
||||
public static final String STRUTS_CONVERTER_CREATOR = "struts.converter.creator";
|
||||
public static final String STRUTS_CONVERTER_HOLDER = "struts..converter.holder";
|
||||
public static final String STRUTS_CONVERTER_HOLDER = "struts.converter.holder";
|
||||
|
||||
public static final String STRUTS_EXPRESSION_PARSER = "struts.expression.parser";
|
||||
|
||||
@@ -462,4 +462,7 @@ public final class StrutsConstants {
|
||||
public static final String STRUTS_URL_QUERY_STRING_PARSER = "struts.url.queryStringParser";
|
||||
public static final String STRUTS_URL_ENCODER = "struts.url.encoder";
|
||||
public static final String STRUTS_URL_DECODER = "struts.url.decoder";
|
||||
|
||||
/** A global flag to set property {@link org.apache.struts2.components.Checkbox#setSubmitUnchecked(String)} */
|
||||
public static final String STRUTS_UI_CHECKBOX_SUBMIT_UNCHECKED = "struts.ui.checkbox.submitUnchecked";
|
||||
}
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
*/
|
||||
package org.apache.struts2.components;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.views.annotations.StrutsTag;
|
||||
import org.apache.struts2.views.annotations.StrutsTagAttribute;
|
||||
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* <!-- START SNIPPET: javadoc -->
|
||||
@@ -46,15 +47,19 @@ import com.opensymphony.xwork2.util.ValueStack;
|
||||
*
|
||||
* <!-- END SNIPPET: example -->
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
@StrutsTag(
|
||||
name="checkbox",
|
||||
tldTagClass="org.apache.struts2.views.jsp.ui.CheckboxTag",
|
||||
description="Render a checkbox input field",
|
||||
allowDynamicAttributes=true)
|
||||
name = "checkbox",
|
||||
tldTagClass = "org.apache.struts2.views.jsp.ui.CheckboxTag",
|
||||
description = "Render a checkbox input field",
|
||||
allowDynamicAttributes = true)
|
||||
public class Checkbox extends UIBean {
|
||||
final public static String TEMPLATE = "checkbox";
|
||||
|
||||
private static final String ATTR_SUBMIT_UNCHECKED = "submitUnchecked";
|
||||
|
||||
public static final String TEMPLATE = "checkbox";
|
||||
|
||||
private String submitUncheckedGlobal;
|
||||
|
||||
protected String fieldValue;
|
||||
protected String submitUnchecked;
|
||||
@@ -69,35 +74,45 @@ public class Checkbox extends UIBean {
|
||||
|
||||
protected void evaluateExtraParams() {
|
||||
if (fieldValue != null) {
|
||||
addParameter("fieldValue", findString(fieldValue));
|
||||
addParameter(ATTR_FIELD_VALUE, findString(fieldValue));
|
||||
} else {
|
||||
addParameter("fieldValue", "true");
|
||||
addParameter(ATTR_FIELD_VALUE, "true");
|
||||
}
|
||||
|
||||
if (submitUnchecked != null) {
|
||||
Object parsedValue = findValue(submitUnchecked, Boolean.class);
|
||||
addParameter("submitUnchecked", parsedValue == null ? Boolean.valueOf(submitUnchecked) : parsedValue);
|
||||
addParameter(ATTR_SUBMIT_UNCHECKED, parsedValue == null ? Boolean.valueOf(submitUnchecked) : parsedValue);
|
||||
} else if (submitUncheckedGlobal != null) {
|
||||
addParameter(ATTR_SUBMIT_UNCHECKED, Boolean.parseBoolean(submitUncheckedGlobal));
|
||||
} else {
|
||||
addParameter("submitUnchecked", false);
|
||||
addParameter(ATTR_SUBMIT_UNCHECKED, false);
|
||||
}
|
||||
}
|
||||
|
||||
protected Class getValueClassType() {
|
||||
@Override
|
||||
protected Class<?> getValueClassType() {
|
||||
return Boolean.class; // for checkboxes, everything needs to end up as a Boolean
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(description="The actual HTML value attribute of the checkbox.", defaultValue="true")
|
||||
@Inject(value = StrutsConstants.STRUTS_UI_CHECKBOX_SUBMIT_UNCHECKED, required = false)
|
||||
public void setSubmitUncheckedGlobal(String submitUncheckedGlobal) {
|
||||
this.submitUncheckedGlobal = submitUncheckedGlobal;
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(description = "The actual HTML value attribute of the checkbox.", defaultValue = "true")
|
||||
public void setFieldValue(String fieldValue) {
|
||||
this.fieldValue = fieldValue;
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(description="If set to true, unchecked elements will be submitted with the form.", type="Boolean", defaultValue="false")
|
||||
@StrutsTagAttribute(description = "If set to true, unchecked elements will be submitted with the form. " +
|
||||
"Since Struts 6.1.1 you can use a constant \"" + StrutsConstants.STRUTS_UI_CHECKBOX_SUBMIT_UNCHECKED + "\" to set this attribute globally",
|
||||
type = "Boolean", defaultValue = "false")
|
||||
public void setSubmitUnchecked(String submitUnchecked) {
|
||||
this.submitUnchecked = submitUnchecked;
|
||||
}
|
||||
|
||||
@Override
|
||||
@StrutsTagAttribute(description="Define label position of form element (top/left), also 'right' is supported when using 'xhtml' theme")
|
||||
@StrutsTagAttribute(description = "Define label position of form element (top/left), also 'right' is supported when using 'xhtml' theme")
|
||||
public void setLabelPosition(String labelPosition) {
|
||||
super.setLabelPosition(labelPosition);
|
||||
}
|
||||
|
||||
@@ -435,8 +435,11 @@ import java.util.Map;
|
||||
*
|
||||
*/
|
||||
public abstract class UIBean extends Component {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(UIBean.class);
|
||||
|
||||
protected static final String ATTR_FIELD_VALUE = "fieldValue";
|
||||
|
||||
protected HttpServletRequest request;
|
||||
protected HttpServletResponse response;
|
||||
|
||||
|
||||
@@ -38,11 +38,11 @@
|
||||
<#include "/${parameters.templateDir}/${parameters.expandTheme}/scripting-events.ftl" />
|
||||
<#include "/${parameters.templateDir}/${parameters.expandTheme}/common-attributes.ftl" />
|
||||
<#include "/${parameters.templateDir}/${parameters.expandTheme}/dynamic-attributes.ftl" />
|
||||
/>
|
||||
/><#rt/>
|
||||
<#if parameters.submitUnchecked!false>
|
||||
<input type="hidden" id="__checkbox_${parameters.id}" name="__checkbox_${parameters.name}" value="${parameters.fieldValue}"<#rt/>
|
||||
<#if parameters.disabled!false>
|
||||
disabled="disabled"<#rt/>
|
||||
</#if>
|
||||
/>
|
||||
</#if><#rt/>
|
||||
/><#rt/>
|
||||
</#if>
|
||||
|
||||
@@ -283,7 +283,7 @@
|
||||
<td class="tag-attribute">false</td>
|
||||
<td class="tag-attribute">false</td>
|
||||
<td class="tag-attribute">Boolean</td>
|
||||
<td class="tag-attribute">If set to true, unchecked elements will be submitted with the form.</td>
|
||||
<td class="tag-attribute">If set to true, unchecked elements will be submitted with the form. Since Struts 6.1.1 you can use a constant "struts.ui.checkbox.submitUnchecked" to set this property globally</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tag-attribute">tabindex</td>
|
||||
|
||||
@@ -18,11 +18,21 @@
|
||||
*/
|
||||
package org.apache.struts2.views.jsp.ui;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.config.ConfigurationException;
|
||||
import com.opensymphony.xwork2.config.ConfigurationProvider;
|
||||
import com.opensymphony.xwork2.inject.ContainerBuilder;
|
||||
import com.opensymphony.xwork2.test.StubConfigurationProvider;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.location.LocatableProperties;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.TestAction;
|
||||
import org.apache.struts2.views.jsp.AbstractUITagTest;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
|
||||
public class CheckboxTest extends AbstractUITagTest {
|
||||
|
||||
/**
|
||||
@@ -31,7 +41,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
* String, String[])} as properties to verify.<br> This implementation extends testdata from AbstractUITag.
|
||||
*
|
||||
* @return A Map of PropertyHolders values bound to {@link org.apache.struts2.views.jsp.AbstractUITagTest.PropertyHolder#getName()}
|
||||
* as key.
|
||||
* as key.
|
||||
*/
|
||||
@Override
|
||||
protected Map<String, PropertyHolder> initializedGenericTagTestProperties() {
|
||||
@@ -73,7 +83,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testChecked_clearTagStateSet() throws Exception {
|
||||
@@ -102,7 +112,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testCheckedWithTopLabelPosition() throws Exception {
|
||||
@@ -129,10 +139,10 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testCheckedWithTopLabelPosition_clearTagStateSet() throws Exception {
|
||||
public void testCheckedWithTopLabelPosition_clearTagStateSet() throws Exception {
|
||||
TestAction testAction = (TestAction) action;
|
||||
testAction.setFoo("true");
|
||||
|
||||
@@ -159,7 +169,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testCheckedWithLeftLabelPosition() throws Exception {
|
||||
@@ -186,7 +196,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testCheckedWithLeftLabelPosition_clearTagStateSet() throws Exception {
|
||||
@@ -216,7 +226,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testCheckedWithError() throws Exception {
|
||||
@@ -245,7 +255,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testCheckedWithError_clearTagStateSet() throws Exception {
|
||||
@@ -277,7 +287,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testCheckedWithErrorStyle() throws Exception {
|
||||
@@ -306,7 +316,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testCheckedWithErrorStyle_clearTagStateSet() throws Exception {
|
||||
@@ -338,7 +348,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testUnchecked() throws Exception {
|
||||
@@ -362,7 +372,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testUnchecked_clearTagStateSet() throws Exception {
|
||||
@@ -389,7 +399,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testDisabled() throws Exception {
|
||||
@@ -414,7 +424,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testDisabled_clearTagStateSet() throws Exception {
|
||||
@@ -442,7 +452,7 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
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));
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
|
||||
public void testSubmitUncheckedAsFalse() throws Exception {
|
||||
@@ -487,4 +497,29 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
verify(CheckboxTag.class.getResource("Checkbox-8.txt"));
|
||||
}
|
||||
|
||||
public void testSubmitUncheckedGlobalAsTrue() throws Exception {
|
||||
initDispatcherWithConfigs("struts-default.xml, struts-checkbox-submit-unchecked.xml");
|
||||
String submitUnchecked = container.getInstance(String.class, StrutsConstants.STRUTS_UI_CHECKBOX_SUBMIT_UNCHECKED);
|
||||
assertEquals("true", submitUnchecked);
|
||||
|
||||
createMocks();
|
||||
|
||||
TestAction testAction = (TestAction) action;
|
||||
testAction.setFoo("true");
|
||||
|
||||
CheckboxTag tag = new CheckboxTag();
|
||||
tag.setPageContext(pageContext);
|
||||
tag.setLabel("mylabel");
|
||||
tag.setName("foo");
|
||||
tag.setFieldValue("baz");
|
||||
// tag.setSubmitUnchecked("true"); - value should be injected by container
|
||||
tag.setTitle("mytitle");
|
||||
tag.setDisabled("true");
|
||||
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
|
||||
verify(CheckboxTag.class.getResource("Checkbox-8.txt"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
|
||||
"https://struts.apache.org/dtds/struts-6.0.dtd">
|
||||
<struts>
|
||||
<constant name="struts.ui.checkbox.submitUnchecked" value="true"/>
|
||||
|
||||
<package name="default" extends="struts-default">
|
||||
</package>
|
||||
|
||||
</struts>
|
||||
Reference in New Issue
Block a user