Как сделать недействительным поле в шве? - PullRequest
1 голос
/ 30 июня 2009

Мне нужно проверить два пользовательских поля ввода друг против друга в шве. Поле1 должно быть больше поля2 для каждой строки в теге ui: repeat. На данный момент у меня есть два поля, обернутые в тег s: decorate, который оборачивает все входные данные в тег s: validateAll. Это позволяет мне выводить сообщение об ошибке справа от полей, если проверка не удалась для любого из них.

Например (я не могу вставить изображение, поэтому я должен использовать изображение ascii, простите за низкое качество, курсивом выделен красный текст):

Метка: | Желтый | 0 |% Красный: | 0% | | Желтый и красный должны быть в диапазоне от 0 до 100, а желтый должен быть больше красного.

Метка: | Желтый | 0 |% Красный: | 0% | | Желтый и красный должны быть в диапазоне от 0 до 100, а желтый должен быть больше красного.

Два элемента управления и декорация xhtml ниже. ПРИМЕЧАНИЕ. Проверка «значения между 0 и 100» уже выполняется с помощью аннотации гибернации. Мне нужно только знать, как проверять эти 2 поля друг против друга, чтобы убедиться, что желтый больше красного, и при этом отображается сообщение об ошибке.

Мое желаемое решение - установить свойство # {invalid} для соответствующего тега s: decorate, чтобы появилось сообщение об ошибке, но я приму любые идеи.

Входы:

<table>
    <ui:repeat value="#{action.List}" var="var">
        <s:decorate template="/layout/decorateMultipleInputs.xhtml" >
            <ui:define name="label">
                Label:
            </ui:define>
            <ui:define name="input">
                <h:panelGrid columns="8" frame="border">
                    <h:outputText value="Yellow:" />
                    <h:inputText value="#{var.yellow}" style="width:25px; text-align:right" maxlength="3"/>
                    %

                    <h:outputText value="Red:" />
                    <h:inputText value="#{var.red}" style="width:25px; text-align:right" maxlength="3"/>
                    %
                </h:panelGrid>
            </ui:define>
            <ui:define name="message">Yellow and Red must be between 0 and 100, and Yellow must be greater than Red.
            </ui:define>
        </s:decorate>
    </ui:repeat>
</table>

и decorateMultipleInputs.xhtml:

<ui:composition  xmlns="http://www.w3.org/1999/xhtml"
             xmlns:ui="http://java.sun.com/jsf/facelets"
             xmlns:h="http://java.sun.com/jsf/html"
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:s="http://jboss.com/products/seam/taglib">
<tr>
<td>        
    <s:label styleClass="#{invalid?'error':''}">
        <ui:insert name="label"/>
        <s:span styleClass="required" rendered="#{required}">*</s:span>
    </s:label>
</td>
<td>
    <s:validateAll>
        <ui:insert name="input"/>
    </s:validateAll>
</td>
<td>
    <s:div styleClass="error" rendered="#{invalid}">
        <h:graphicImage value="/images/error.gif" />
    </s:div>    
</td>
<td>
    <s:div styleClass="error" rendered="#{invalid}">
        <ui:insert name="message"/>
    </s:div>    
</td>
</tr>
</ui:composition>

Ответы [ 2 ]

1 голос
/ 30 июня 2009

Я бы прикрепил ваш собственный валидатор JSF к красному <h:inputText/>

<h:inputText value="#{var.red}" style="width:25px; text-align:right" maxlength="3">
  <f:validator validatorId="rowValidator"/>
</inputText>

Реализация валидатора JSF (поскольку вы используете Seam, вы можете использовать аннотацию @Validator).

@Validator
public class RowValidator implements javax.faces.validator.Validator
{
    public void validate(FacesContext context, UIComponent component, Object value)
        throws ValidatorException 
    {
        <snip/>  
    }
}

Ключ здесь - это объект UIComponent, переданный методу validate(). Это <h:inputText/>, с которым вы связали валидатор. Отсюда вы можете позвонить getParent(), чтобы получить <h:inputText/> родителя (<h:panelGrid/>). Теперь вы можете перечислить дочерние объекты <h:panelGrid/>, чтобы найти желтый <h:inputText/>, получить переданное ему значение и сравнить с параметром value, переданным методу validate().

Если желтый меньше красного, вы можете сделать следующее в вашем validate() методе:

FacesMessage message = new FacesMessage();
message.setDetail("Yellow must be greater than red");
message.setSummary("Yellow must be greater than red");
message.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(message);
0 голосов
/ 30 июня 2009

В Seam в настоящее время нет способа выполнить проверку нескольких полей. В настоящее время это находится на рассмотрении для JSR-299 WebBeans, но нет ни четкого, ни четкого способа сделать это.

Этого можно добиться, проверив после отправки формы как часть обычного обработчика действий. то есть.

public String processRedsAndYellows() {
   for(RedYellow var : ActionBean.getList()) {
      if(var.getYellow() <= var.getRed()) {
         messages.addMessage("All Yellows must be greater than Reds");
         return null;
      }
   }
   return "success";
}

Или что-то на этот счет. :)

...