使用JSP Documents(JSPX)有条件地在元素上设置属性

时间:2008-10-01 10:25:00

标签: jsp xhtml webforms jspx

在HTML表单中,可以通过使用任何值定义“disabled”属性来禁用按钮:

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

如果要启用某个按钮,该属性不应该存在,因为没有定义的值可以将disabled属性设置为启用该按钮。

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

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

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

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

11 个答案:

答案 0 :(得分:10)

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

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

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

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

答案 1 :(得分:8)

您可以使用<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>

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

答案 2 :(得分:6)

@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' : ''} />

答案 3 :(得分:4)

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

中发布了详细信息

我得出结论,没有好的捷径; 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)

答案 4 :(得分:3)

阅读自动jsp to jspx converter我遇到了<jsp:element><jsp:attribute>标签。如果我理解正确,你应该可以做类似

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

并拥有jsp引擎输出

<button someAttribute="value"/>

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

答案 5 :(得分: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

答案 6 :(得分:0)

&lt;%= blah%&gt;语法不是JSP文档所需的合法XML。您有两个选择:

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

    希望有所帮助:)

答案 7 :(得分:0)

我一直在努力解决同样的问题。我尝试在<jsp:attribute name="disabled"/>内使用<c:if>,但编译器会尝试将已禁用的属性附加到失败的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",要么根本没有。

这只有在使用某种taglib生成按钮时才有效,而tag元素必须支持disabled属性(将其传递给底层HTML元素)。您无法使用jsp:attribute将属性添加到原始HTML元素。

答案 8 :(得分: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/>

答案 9 :(得分:0)

使用 JSP的正确方法是这样的:

public function index()
 {
$mytime = Carbon\Carbon::now();
$checkdate=$mytime->toDateString();
$lead=Lead::whereDate('created_at', $checkdate)->orderBy('created_at', 'desc')->get()
return view('admin.lead.index',compact('lead'));
 }

关键是要在<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属性-如果表达式的计算结果为<jsp:attribute>,则该属性将不再可用。

答案 10 :(得分:-2)

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

<% if (isDisabled) { %>
  <button name="btn1" disabled="disabled">Hello</button>
<% } else { %>
  <button name="btn1">Hello</button>
<% } %>