20

在 HTML 表单中,可以通过在按钮上定义 "disabled" 属性来禁用按钮,其值为任意值:

<button name="btn1" disabled="disabled">Hello</button>

如果要启用按钮,则该属性不应该存在,因为没有定义的值可以设置 disabled 属性以使按钮保持启用状态。

当我想在使用 JSP 文档 (jspx) 时启用/禁用按钮时,这会导致我出现问题。由于 JSP 文档必须是格式良好的 XML 文档,因此我看不到任何有条件地包含此属性的方式,因为以下内容是不合法的:

<button name="btn1" <%= (isDisabled) ? "disabled" : "" %/> >Hello</button>

虽然我可以使用 JSTL if 标签复制标签两次以获得所需的效果,但在我的具体情况下,我在按钮上声明了超过 15 个属性(AJAX 的许多 javascript 事件处理程序属性),因此复制标签将使JSP 很乱。

如何在不牺牲 JSP 可读性的情况下解决这个问题?是否有任何自定义标签可以通过操作输出 DOM 向父级添加属性?

4

11 回答 11

12

我使用具有动态属性的自定义 JSP 标记。你像这样使用它:

<util:element elementName="button" name="btn1" disabled="$(isDisabled ? 'disabled' : '')"/>

基本上,这个标签所做的是生成一个带有 elementName 的 XML 元素,并将所有存在的属性放在标签中,但会跳过空的属性。

标签本身很容易实现,我的实现只有 44 行。

于 2008-10-16T09:11:39.537 回答
7

@alex 使用三元运算符的绝佳解决方案。我添加了一些我的示例,感谢您,我只是更改了条件的结果,如果为 true,则写入属性,否则不写入任何内容

填充列表并选择使用的值,避免使用 c:if

<select id="selectLang" name="selectLang" >
<c:forEach var="language" items="${alLanguages}" >
    <option value="${language.id}" ${language.code == usedLanguage ? 'selected' : ''} >${language.description}</option>
</c:forEach>

在开始时检查单选按钮以避免 c:if:

<input type="radio" id="id0" value="0" name="radio" ${modelVar == 0 ? 'checked' : ''} />
<input type="radio" id="id1" value="1" name="radio" ${modelVar == 1 ? 'checked' : ''} />
<input type="radio" id="id2" value="2" name="radio" ${modelVar == 2 ? 'checked' : ''} />
于 2015-10-23T09:09:40.623 回答
6

您可以使用该<jsp:text>标签通过有效的 XML 来解决此问题:

<jsp:text><![CDATA[<button name="btn1"]]></jsp:text>
    <c:if test="${isDisabled}"> disabled="disabled"</c:if>
    >
    Hello!
<jsp:text><![CDATA[</button>]]></jsp:text>

这显然比其他一些解决方案更冗长。但它是完全独立的:不需要自定义标签。此外,它可以轻松扩展到您需要的任意数量的属性。

于 2009-04-22T00:43:15.493 回答
4

我想自上一篇文章以来已经过去了一段时间,但我遇到了与标签完全相同的问题<select><option selected="selected">,即动态声明选择了哪个选项。为了解决这个问题,我制作了一个自定义 tagx;我在这里的另一个答案中发布了详细信息

我得出的结论是没有好的捷径;EL 和 JSP 表达式只能存在于 XML 元素属性中(以及正文内容中)。因此,您必须执行以下操作;

<c:choose>
    <c:when test="${isDisabled}"><button name="btn1" disabled="disabled">Hello</button></c:when>
    <c:otherwise><button name="btn1">Hello</button></c:otherwise>
</c:choose>

使用 scriptlet 表示法不适用于 JSP 文档 (.jspx)

于 2010-02-28T23:56:24.273 回答
3

阅读有关自动jsp 到 jspx 转换器的信息时,我遇到了<jsp:element>and<jsp:attribute>标签。如果我理解正确,你应该能够做类似的事情

<jsp:element name="button">
  <jsp:attribute name="someAttribute">value</jsp:attribute>
</jsp:element>

并有jsp引擎输出

<button someAttribute="value"/>

或类似的东西。上面页面中指出的唯一问题是,这似乎不适用于条件构造。转换器的作者解决了创建一些帮助标签的问题,你可以看看下载我猜的源代码。希望有帮助。

于 2008-10-15T11:10:46.007 回答
2

创建一个标签库 (.tagx) 然后使用 scriptlet 标签。

请参阅http://code.google.com/p/jatl/wiki/JSPExample

<?xml version="1.0" encoding="UTF-8" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1">
<jsp:directive.page import="com.googlecode.jatl.Html"/>
<jsp:directive.page import="com.evocatus.product.data.AttributeValue"/>
<jsp:directive.page import="com.evocatus.domain.Product"/>

<jsp:scriptlet>
//<![CDATA[
    final Product p = (Product) request.getAttribute("product");
        new Html(out) {{
           for (AttributeValue v : p.summaryAttributeValues()) {
                   p();
                        strong().text(v.getLabel()).end();
                        text(": " + v.getValue());
                   endAll();
           }
        }};
//]]>
</jsp:scriptlet>

</jsp:root>

是的,这是作弊......但它完成了工作。另外,您能否以这种方式对树结构进行非常讨厌的复杂递归。

我还在我的博客和 gist.github 上发布了另一个解决方案,它使用了一堆 tagx 库:http ://adamgent.com/post/8083703288/conditionally-set-an-attribute-on-an-element-with-jspx

于 2011-07-15T22:52:57.823 回答
0

<%= blah %> 语法不是 JSP 文档所需的合法 XML。您有 2 个选项:

  1. 替换 <%= (isDisabled) ?"disabled" : "" %> with <jsp.expression>(isDisabled) ? “禁用”:“”</jsp.expression>
  2. 使用 Core taglib 和 EL(确保将 isDisabled 放入页面范围),如下所示:
<c:选择>
  <c:when test="${isDisabled}">"禁用"</c:when>
  <c:otherwise>""</c:otherwise>
</c:选择>

希望有帮助:)

于 2008-10-04T05:46:28.377 回答
0

我一直在努力解决同样的问题。我尝试使用<jsp:attribute name="disabled"/>inside <c:if>,但编译器尝试将 disabled 属性附加到c:if失败的元素。但我发现这确实有效(stripes:submit是一个用于创建带状提交类型按钮的元素):

<stripes:submit name="process" value="Hello">
   <jsp:attribute name="disabled">
       <c:if test="${x == 0}">disabled</disabled>
   </jsp:attribute>
</stripes:submit>

如果正文仅包含空格,似乎jsp:attribute根本不会创建属性,因此您要么得到disabled="disabled"要么什么都没有。

这仅在您使用某种标记库生成按钮时才有效,并且标记元素必须支持 disabled 属性(将其传递给底层 HTML 元素)。您不能使用jsp:attribute将属性添加到原始 HTML 元素。

于 2011-06-15T02:56:14.957 回答
0

我像https://stackoverflow.com/a/207882/242042一样实现它并封装了https://stackoverflow.com/a/775295/242042以便它可以作为标签重复使用。

<%@ tag
  display-name="element"
  pageEncoding="utf-8"
  description="similar to jsp:element with the capability of removing attributes that are blank, additional features depending on the key are documented in the tag."
  trimDirectiveWhitespaces="true"
  dynamic-attributes="attrs"
%>
<%@ attribute
  name="tag"
  description="Element tag name.  Used in place of `name` which is a common attribute in HTML"
  required="true"
%>
<%-- key ends with Key, use i18n --%>
<%-- key starts with x-bool- and value is true, add the key attribute, no value  --%>
<%-- key starts with x-nc- for no check and value is empty, add the key attribute, no value  --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<jsp:text><![CDATA[<]]></jsp:text>
<c:out value="${tag} " />
<c:forEach var="attr" begin="0" items="${attrs}">
  <c:choose>
    <c:when test='${fn:endsWith(attr.key, "Key")}'>
      ${attr.key}=<fmt:message key="${attr.value}" />
    </c:when>
    <c:when test='${fn:startsWith(attr.key, "x-bool-") && attr.value == "true"}'>
      <c:out value="${fn:substringAfter(attr.key, 'x-bool-')}" />
    </c:when>
    <c:when test='${fn:startsWith(attr.key, "x-bool-") && attr.value != "true"}'>
    </c:when>
    <c:when test='${fn:startsWith(attr.key, "x-nc-")}'>
      <c:out value="${fn:substringAfter(attr.key, 'x-nc-')}" />="<c:out value='${attr.value}' />"
    </c:when>
    <c:when test='${not empty attr.value}'>
      <c:out value="${attr.key}" />="<c:out value='${attr.value}' />"
    </c:when>
  </c:choose>
  <c:out value=" " />
</c:forEach>
<jsp:doBody var="bodyText" />
<c:choose>
  <c:when test="${not empty fn:trim(bodyText)}">
    <jsp:text><![CDATA[>]]></jsp:text>
      ${bodyText}
    <jsp:text><![CDATA[<]]></jsp:text>
      <c:out value="/${tag}" />
    <jsp:text><![CDATA[>]]></jsp:text>
  </c:when>
  <c:otherwise>
    <jsp:text><![CDATA[/>]]></jsp:text>
  </c:otherwise>
</c:choose>

要使用它,请将其放在 taglib tagdir 中。

<%@ taglib tagdir="/WEB-INF/tags" prefix="xyz"%>
...
<xyz:element tag="input"
  type="date"
  id="myDate"
  name="myDate"
  x-bool-required="true"
/>

输出将呈现为

<input 
    name="myDate"
    id="myDate"
    type="date"
    required/>
于 2020-03-11T17:56:20.447 回答
0

使用纯JSP 的正确方法是:

<jsp:element name="button">
  <jsp:attribute name="name">btn1</jsp:attribute>
  <jsp:attribute name="disabled" omit="${not isDisabled}">disabled</jsp:attribute>
  <jsp:body>Hello</jsp:body>
</jsp:element>

关键是使用omit属性 on <jsp:attribute>- 如果表达式计算结果为,true则该属性根本不会被渲染。

于 2020-03-23T09:09:36.037 回答
-2

我并没有真正使用JSP(我回复过一次,然后在我理解“必须通过有效的XML”事情时将其删除)。我能想到的最干净的是:

<% if (isDisabled) { %>
  <button name="btn1" disabled="disabled">Hello</button>
<% } else { %>
  <button name="btn1">Hello</button>
<% } %>
于 2008-10-01T10:45:59.697 回答