Расширить h:outputText для пользовательских функций

Я использую JSF + RF более 2 лет и не имел возможности расширить существующие возможности компонентов.

Теперь требуется обрезать строку и отобразить ее, если она превышает 25 символов.

Это было достигнуто, как показано ниже

                        <c:choose>
                            <c:when test="#{fn:length(teststep.name) > 25}">
                                <h:outputText title="#{teststep.name}" value="#{fn:substring(teststep.name, 0, 25)}..."/>
                            </c:when>
                            <c:otherwise>
                                <h:outputText title="#{teststep.name}" value="#{teststep.name}"/>
                            </c:otherwise>
                        </c:choose>

Но я использую этот код во многих местах (и хочу каждый раз избегать шаблонного кода из 8 строк), поэтому подумал о пользовательском h: outputText, чтобы обеспечить функциональность обрезки.

Не могли бы вы сообщить мне, как мне написать собственный тег в JSF?

С уважением, Сатья.


person Satya    schedule 22.02.2012    source источник


Ответы (1)


Предполагая, что вы используете JSP, а не Facelets, поместите содержимое файла .tag в /WEB-INF, например /WEB-INF/tags/outputLimitedText.tag.

<%@ tag body-content="empty" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<c:choose>
    <c:when test="#{fn:length(value) > maxlength}">
        <h:outputText title="#{value}" value="#{fn:substring(value, 0, maxlength)}..."/>
    </c:when>
    <c:otherwise>
        <h:outputText title="#{value}" value="#{value}"/>
    </c:otherwise>
</c:choose>

Затем вы можете ссылаться на него следующим образом:

<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %> 
...
<my:outputLimitedText value="#{teststep.name}" maxlength="25" />

Вы также можете использовать Converter.

<h:outputText title="#{teststep.name}" value="#{teststep.name}">
    <f:converter converterId="substringConverter" />
    <f:attribute name="maxlength" value="25" />
</h:outputText>

с участием

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    String string = (String) value;
    int maxlength = Integer.valueOf((String) component.getAttributes().get("maxlength"));

    if (string.length() > maxlength) {
        return string.substring(0, maxlength) + "...";
    } else {
        return string;
    }
}

Вы также можете создать пользовательскую функцию EL. Так что вы в конечном итоге с

<h:outputText title="#{teststep.name}" value="#{util:ellipsis(teststep.name, 25)}">

Конкретный пример функции EL приведен в этом ответе: Как объединить Строки в EL?

person BalusC    schedule 22.02.2012
comment
Я попробовал первое решение, и оно меня не впечатлило :), но я хотел бы сделать что-то вроде ‹h:outputText title=#{value} value=#{value} trimByChars=25/› . Возможно ли сохранить функции h: outputText и добавить только некоторые дополнительные возможности? - person Satya; 22.02.2012
comment
Я попробую третий вариант, кажется, это что-то новое для меня :). Большое спасибо BalusC - person Satya; 22.02.2012
comment
Добавление нового атрибута к существующему компоненту возможно только с помощью пользовательского компонента, а не пользовательского тега. Это очень утомительная работа. Вы должны скопировать все существующие атрибуты тега, так как невозможно наследовать от существующих тегов. Проще было бы предоставить дополнительный атрибут как <f:attribute> и переопределить значение по умолчанию Renderer. - person BalusC; 22.02.2012