Связать сообщение об ошибке с несколькими UIComponent в JSF2 - PullRequest
2 голосов
/ 23 декабря 2011

Я иду с вопросом о JSF2. В настоящее время я смешиваю два разных кода, предложенных BalusC в своем блоге:

http://balusc.blogspot.com/2007/12/set-focus-in-jsf.html

http://balusc.blogspot.com/2007/12/validator-for-multiple-fields.html

При первом разрешении красным цветом выделите поля, в которых есть сообщение об ошибке. Вторая проверка допустимости выполняется на нескольких полях.

Я ищу способ иметь одно сообщение об ошибке (не хочу, чтобы сообщение отображалось дважды) в FacesContext, которое было связано с несколькими идентификаторами клиента (поскольку сообщение действительно относится к нескольким полям из-за средства проверки нескольких полей) .

Возможно ли это с основами языка? Если я могу, я бы хотел избежать системы, созданной вручную (она должна работать с управляемым компонентом с областью действия «запрос», валидатор помещает clientIds, которые имеют ошибку, в список, к которому обращается PhaseListener). *

Заранее спасибо за ваши советы. Не удалось увидеть ничего похожего на addMessage () на FacesContext, который мог бы выполнить эту работу, но, возможно, есть способ ...

1 Ответ

2 голосов
/ 23 декабря 2011

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

Я понимаючто вы хотите пометить оба компонента как недействительные (чтобы они были выделены) и что вам нужно только одно сообщение.В этом случае вам нужно убедиться, что валидатор запущен один раз, а другой компонент получает пустое / пустое сообщение.

Вам нужно всего лишь изменить валидатор, чтобы получить весь компонент как атрибут, а неего значение (примечание: я тем временем соответствующим образом отредактировал старую статью; у нее есть и другие преимущества), и вам нужно изменить слушатель фазы, чтобы удалить пустые / пустые сообщения.

Например, в поле зрения:

<h:outputLabel for="password" value="Password" />
<h:inputSecret id="password" value="#{bean.password}" required="true">
    <f:validator validatorId="passwordValidator" />
    <f:attribute name="confirm" value="#{confirm}" />
</h:inputSecret>
<h:message for="password" styleClass="error" />

<h:outputLabel for="confirm" value="Confirm password" />
<h:inputSecret id="confirm" binding="#{confirm}" required="true" />
<h:message for="confirm" styleClass="error" />

и в validate() метод:

String password = (String) value;
UIInput confirmComponent = (UIInput) component.getAttributes().get("confirm");
String confirm = confirmComponent.getSubmittedValue();

if (password == null || password.isEmpty() || confirm == null || confirm.isEmpty()) {
    return; // Let required="true" do its job.
}

if (!password.equals(confirm)) {
    confirmComponent.setValid(false);
    context.addMessage(confirmComponent.getClientId(context), new FacesMessage(null));
    throw new ValidatorException(new FacesMessage("Passwords are not equal."));
}

и в фазовом прослушивателе:

Iterator<String> clientIdsWithMessages = facesContext.getClientIdsWithMessages();

while (clientIdsWithMessages.hasNext()) {
    String clientIdWithMessages = clientIdsWithMessages.next();

    if (focus == null) {
        focus = clientIdWithMessages;
    }

    highlight.append(clientIdWithMessages);

    if (clientIdsWithMessages.hasNext()) {
        highlight.append(",");
    }

    Iterator<FacesMessage> messages = facesContext.getMessages(clientIdWithMessages);

    while (messages.hasNext()) {
        if (messages.next().getSummary() == null) {
            messages.remove(); // Remove empty messages.
        }
    }
}

Связанные:


Не связано с конкретной проблемой, в JSF2, кстати, есть другой способ выделить недопустимые поля.Вы можете сделать это с помощью новой неявной переменной #{component} в EL:

<h:inputText styleClass="#{component.valid ? '' : 'error'}" />
...