如何使接缝中的字段无效?

时间:2022-04-14 20:00:04

I need to validate two user input fields against each other in seam. Field1 must be greater than Field2 for each row in a ui:repeat tag. As of now, i have the two fields wrapped in an s:decorate tag that wraps all input in an s:validateAll tag. This allows me to float an error message out to the right of the fields if validation fails for any of them.

我需要在seam中相互验证两个用户输入字段。对于ui:repeat标记中的每一行,Field1必须大于Field2。截至目前,我有两个字段包装在一个s:decorate标签中,该标签包含s:validateAll标签中的所有输入。这允许我将错误消息浮动到字段的右侧,如果其中任何一个验证失败。

For example (i can't insert an image, so i have to use ascii picture, forgive the low-quality please, italics indicate red text):

例如(我不能插入图像,所以我必须使用ascii图片,原谅低质量请,斜体表示红色文字):

Label: | Yellow | 0|% Red: | 0%| | Yellow and Red must be between 0 and 100, and Yellow must be greater than Red.

Label: | Yellow | 0|% Red: | 0%| | Yellow and Red must be between 0 and 100, and Yellow must be greater than Red.

标签:|黄色| 0 |%红色:| 0%| |黄色和红色必须介于0到100之间,黄色必须大于红色。标签:|黄色| 0 |%红色:| 0%| |黄色和红色必须介于0到100之间,黄色必须大于红色。

The two controls and the decorate xhtml are below. NOTE: The "value between 0 and 100" validation is already taken care of via hibernate annotation. I only need to know how to validate these 2 fields against each other to make sure yellow is greater than red, and still have the error message show up.

两个控件和装饰xhtml如下。注意:“0到100之间的值”验证已经通过hibernate注释处理。我只需要知道如何相互验证这两个字段以确保黄色大于红色,并且仍然显示错误消息。

My desired solution would be to set the #{invalid} property for the corresponding s:decorate tag, so the error message will show up, but i'll take any ideas.

我想要的解决方案是为相应的s:decorate标签设置#{invalid}属性,因此会显示错误消息,但我会采取任何想法。

The inputs:

<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>

and the decorateMultipleInputs.xhtml:

和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


I would attach your own custom JSF validator to the red <h:inputText/>

我会将您自己的自定义JSF验证器附加到红色

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

Implement a JSF validator (since you're using Seam you can use the @Validator annotation).

实现一个JSF验证器(因为你使用的是Seam,你可以使用@Validator注释)。

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

The key here is the UIComponent object passed to the validate() method. This is the <h:inputText/> you've bound the validator to. From here you can call getParent() to get the <h:inputText/> parent (<h:panelGrid/>). You can now enumerate the <h:panelGrid/> children objects to find the yellow <h:inputText/>, retrieve the value passed in to it and compare with the value parameter passed to the validate() method.

这里的关键是传递给validate()方法的UIComponent对象。这是您将验证器绑定到的 。从这里你可以调用getParent()来获取 parent( )。您现在可以枚举 子对象以查找黄色 ,检索传入其中的值,并与传递给validate()方法的value参数进行比较。

If yellow is less than red you can do the following in your validate() method:

如果黄色小于红色,则可以在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);

#2


Seam does not currently have a way to do multi-field validation. This is currently on the docket for the JSR-299 WebBeans but there is not a clean nor clear cut way how to do this.

Seam目前没有办法进行多字段验证。这是目前JSR-299 WebBeans的备忘录,但是如何做到这一点还没有一个干净或明确的方法。

You can achieve this by validating after a form-submit as part of your usual action handler. ie.

您可以通过在表单提交后作为常用操作处理程序的一部分进行验证来实现此目的。即。

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";
}

Or something to that effect. :)

或者那种效果。 :)

#1


I would attach your own custom JSF validator to the red <h:inputText/>

我会将您自己的自定义JSF验证器附加到红色

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

Implement a JSF validator (since you're using Seam you can use the @Validator annotation).

实现一个JSF验证器(因为你使用的是Seam,你可以使用@Validator注释)。

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

The key here is the UIComponent object passed to the validate() method. This is the <h:inputText/> you've bound the validator to. From here you can call getParent() to get the <h:inputText/> parent (<h:panelGrid/>). You can now enumerate the <h:panelGrid/> children objects to find the yellow <h:inputText/>, retrieve the value passed in to it and compare with the value parameter passed to the validate() method.

这里的关键是传递给validate()方法的UIComponent对象。这是您将验证器绑定到的 。从这里你可以调用getParent()来获取 parent( )。您现在可以枚举 子对象以查找黄色 ,检索传入其中的值,并与传递给validate()方法的value参数进行比较。

If yellow is less than red you can do the following in your validate() method:

如果黄色小于红色,则可以在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);

#2


Seam does not currently have a way to do multi-field validation. This is currently on the docket for the JSR-299 WebBeans but there is not a clean nor clear cut way how to do this.

Seam目前没有办法进行多字段验证。这是目前JSR-299 WebBeans的备忘录,但是如何做到这一点还没有一个干净或明确的方法。

You can achieve this by validating after a form-submit as part of your usual action handler. ie.

您可以通过在表单提交后作为常用操作处理程序的一部分进行验证来实现此目的。即。

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";
}

Or something to that effect. :)

或者那种效果。 :)