【问题标题】:Disable validator via ajax通过 ajax 禁用验证器
【发布时间】:2012-05-27 12:35:26
【问题描述】:

我有一个简单的请求范围实体/pojo,它有一个枚举和一个字符串作为属性。

public Enum Type
{
    None,
    Email,
    Fax;
}

@ManagedBean(name = "testEntity")
@RequestScoped
public class TestEntity
{
    private Type type; //Default = None
    private String address;

    //getter and setter
}

此枚举有一个“电子邮件”字段,用于标识具有相关地址的电子邮件地址。
在 JSF 中,我现在想要启用/禁用与 SelectOneMenu 中当前选择的类型有关的地址 InputText 字段的验证器。

<h:form id="formId">
    <p:selectOneMenu id="type" value="#{testEntity.type}>
        <p:ajax event="change" update=":formId:address"/>
        <f:selectItem itemLabel="E-mail" itemValue="Email"/>
        <f:selectItem itemLabel="Fax" itemValue="Fax"/>
    </p:selectOneMenu>
    <p:inputText id="address" value="#{testEntity.address}">
        <f:validator validatorId="emailValidator" disabled="#{testEntity.type != 'Email'}"/>
    </p:inputText>
    <!-- button to call bean method with testEntity as param -->
</h:form>

validator is never active 不起作用,但 ajax 调用正在工作,因为我可以在其他字段中看到更改值。

【问题讨论】:

  • 顺便说一句,这对于 OmniFaces 来说是一个有趣的想法。这不是一个不常见的要求。
  • 不错的项目,稍后会看看它的展示。

标签: ajax jsf validation


【解决方案1】:

很遗憾,这是不可能的。 &lt;f:xxx&gt; 标签是在视图构建期间而不是在视图渲染期间运行的标记处理程序(不是 UI 组件)。因此,如果它在构建视图期间被禁用,它将始终被禁用,直到重新创建视图(例如,通过新请求或非空导航)。

您需要有一个“全局”验证器,它根据type 属性进一步委托给所需的验证器。

例如

<p:inputText ... validator="#{testEntity.validateAddress}" />

public void validateAddress(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    if (type == Email) {
        context.getApplication().createValidator("emailValidator").validate(context, component, value);
    }
}

更新OmniFaces最近添加了一个新的&lt;o:validator&gt;标签,它应该可以解决这个问题,如下所示:

<o:validator validatorId="emailValidator" disabled="#{testEntity.type != 'Email'}"/>

查看展示示例here

【讨论】:

  • 它是一个共享的远程实体,我不希望其中有任何 jsf。 (注解也在 faces-config 中)我看不到任何其他方法可以在文本字段验证器中搜索类型组件/将其 id 作为属性传递或在 bean 提交方法中验证它。
  • 为什么不调用“new EmailValidator().validate(...)?
  • 您能否详细说明您的评论?明天将检查新的omnifaces验证器。
  • 您的验证器不可用于电子邮件验证器以外的其他验证器。因此,如果您需要另一个验证器,则基本上需要再次创建/复制粘贴另一个全局验证器。
  • 这是预期行为。请改用视图范围。另见code.google.com/p/omnifaces/issues/detail?id=19
【解决方案2】:

感谢 BalusC 的帮助,也许有人对我如何解决它感兴趣。

将类型组件 clientId 传递给自定义转换器。

<f:attribute name="typeComponentId" value=":formId:type"/>

验证器:

public class TestEntity implements Validator
{
    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
    { 
        final String typeComponentId = (String)component.getAttributes().get("typeComponentId");

        final UIInput compType = (UIInput)context.getViewRoot().findComponent(typeComponentId);

        if(compType != null)
        {
            final Type type = (Type)compType.getValue();

            if(type == Type.Email)
                new EmailValidator().validate(context, component, value);
        }
    }
}

编辑:

在 ui:repeat 组件(例如 p:datatable)中不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    相关资源
    最近更新 更多