Условно установите атрибут элемента с JSP-документами (JSPX)

В HTML-формах кнопки можно отключить, указав для них атрибут "disabled" с любым значением:

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

Если кнопка должна быть включена, атрибут не должен существовать, поскольку нет определенного значения, которое может быть отключен атрибутом disabled, который оставил бы кнопку включенной.

Это вызывает у меня проблемы, когда я хочу включать/отключать кнопки при использовании JSP-документов (jspx). Поскольку документы JSP должны быть хорошо сформированными XML-документами, я не вижу никакого способа условного включения этого атрибута, поскольку что-то вроде следующего не является законным:

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

Хотя я мог бы повторить тег дважды, используя тег JSTL if, чтобы получить желаемый эффект, в моем конкретном случае у меня есть более 15 атрибутов, объявленных на кнопке (много атрибутов обработчика событий javascript для AJAX), поэтому дублирование тега идет чтобы сделать JSP очень грязным.

Как я могу решить эту проблему, не жертвуя удобочитаемостью JSP? Существуют ли какие-либо пользовательские теги, которые могут добавлять атрибуты родителям, манипулируя выходным DOM?

Ответы

Ответ 1

Я использую специальный JSP-тег с динамическими атрибутами. Вы используете его следующим образом:

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

В принципе, этот тег создает XML-элемент с именем elementName и помещает все атрибуты в тег, но пропускает пустые.

Сам тег довольно прост в реализации, моя реализация составляет всего 44 строки.

Ответ 2

Тег <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>

Это, очевидно, более многословно, чем некоторые другие решения. Но он полностью автономный: никаких специальных тегов не требуется. Кроме того, он легко масштабируется до такого количества атрибутов, сколько вам нужно.

Ответ 3

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

Ответ 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>

Использование нотации сценария не будет работать для JSP-документов (.jspx)

Ответ 5

Чтение об автоматическом 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"/>

или что-то в этом роде. Единственная проблема, указанная на странице выше, заключается в том, что это не работает с условными конструкциями. Автор конвертера работал вокруг этого, создавая некоторые вспомогательные теги, которые вы можете посмотреть на загрузку исходного кода, я думаю. Надеюсь, что это поможет.

Ответ 6

Создайте библиотеку тегов (.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, которое использует кучу библиотек тегов: http://adamgent.com/post/8083703288/conditionally-set-an-attribute-on-an-element-with-jspx

Ответ 7

Синтаксис <% = blah% > не является правовым XML, необходимым для документов JSP. У вас есть 2 варианта:

  • Заменить <% = (isDisabled)? "disabled": ""% > с < jsp.expression > (isDisabled)? "disabled": "" </jsp.expression >
  • Используйте тег taglib и EL (убедитесь, что isDisabled помещен в область страницы):
<c:choose>
  <c:when test="${isDisabled}">"disabled"</c:when>
  <c:otherwise>""</c:otherwise>
</c:choose>

Надеюсь, что помогает:)

Ответ 8

Я только что боролся с той же проблемой. Я попытался использовать <jsp:attribute name="disabled"/> внутри <c:if>, но компилятор пытается привязать отключенный атрибут к элементу c:if, который терпит неудачу. Но я обнаружил, что это работает (stripes:submit - это элемент для создания кнопки типа 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 для генерации кнопки, а элемент тега должен поддерживать отключенный атрибут (передавая его в базовый элемент HTML). Вы не можете использовать jsp:attribute для добавления атрибута к необработанному элементу HTML.

Ответ 9

На самом деле я не использую JSP (и я ответил один раз, а затем удалил его, когда понял "должен с помощью действительного XML" ). Самое чистое, что я могу придумать:

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