页面刷新验证

时间:2014-05-23 14:21:28

标签: java ajax jsf

我的输入字段附加了一个<f:ajax>对象,可通过按TAB进行验证:

<h:inputText id="input2" value="#{bean.property}">
    <f:validator validatorId="customValidator" />
    <f:ajax execute="@form" render="@this" />
</h:inputText>

如果有任何验证错误,它们将通过类似于<h:messages>的自定义组件显示,输入框将通过自定义PhaseListener设置样式。

我已经实现了一个自定义Faces Validator来跳过验证:

public class CustomValidator {

public void validate(FacesContext context, UIComponent component,
        Object value) throws ValidatorException {
    if (skipValidation(context)) {
        return;
    }
    //Validation code goes here
}

这使我可以根据某些条件跳过bean验证,例如:切换到另一个编辑器视图并在支持bean中保存(可能是错误的)数据。

现在,刷新当前页面时出现问题(通过按F5,点击导航栏中的相同链接或类似链接)。支持中明显错误的数据按预期正确显示,但也应标记为无效。因此,我需要一种方法来在每个页面加载时调用验证(目前它仅通过<f:ajax>对象调用)。

我试着摆弄这样的东西

<f:ajax event="load" execute="editform" render="editform"/>

附在<h:body>上。这是有效的,但网站被绘制了两次 - 如果由于页面首先被绘制而没有邪恶的闪烁,我将不会非常关心,然后进行验证&amp;通过ajax请求更新。

我已经搜索了几个小时来解决这个问题,也许我只是在错误的方向搜索。有关如何解决此问题的任何建议吗?

2 个答案:

答案 0 :(得分:2)

不要使用@SessionScoped bean来支持页面;它是一个JSF设计气味(如果有这样的事情)


使用preRenderView事件触发(或检查)您在页面加载时选择的任何验证逻辑。作为开始:

<f:event type="preRenderView" listener="#{bean.validate}" rendered="#{facesContext.postBack}" />
  1. <f:event/>标记会在您的网页上注册一个事件监听器。
  2. type="preRenderView"属性规定事件应在页面加载之前执行
  3. rendered="#{facesContext.postBack}"将确保仅在刷新同一页面时加载事件,而不是在第一次加载时加载
  4. listener将引用一个支持bean方法,您可以在其中执行所需的验证。在此侦听器中,您可以抛出ValidationException并适当地排队FacesMessages

  5. 备选方案:

    1. 您可以在viewParam中引用组件的值,并将相同的验证器附加到该组件:

      <f:metadata>
          <f:viewParam name="theParam" rendered="#{facesContext.postBack}" value="param['form:input2']" validator="customValidator"/>
      </f:metadata>
      

      这样做会尝试重新提交input2组件的值作为视图参数。视图参数(在此用法中)与任何其他参数一样是UIComponent,并且受到相同的转换/验证语义的约束。

    2. 如果您想要更复杂地处理该组件的内容,您还可以将整个组件作为属性传递到viewParam。首先将input2组件绑定到页面范围:

       <h:inputText id="input2" binding="#{input2}" value="#{bean.property}">
           <f:validator validatorId="customValidator" />
           <f:ajax execute="@form" render="@this" />
       </h:inputText>
      

      然后将组件作为属性传递:

        <f:metadata>
          <f:viewParam name="theParam" rendered="#{facesContext.postBack}" validator="customValidator"/>
               <f:attribute name="input2" value="#{input2}"/>
        </f:metadata>
      
    3. 然后,您可以在验证器中检索该值:

            UIInput input2= (UIInput)component.getAttributes().get("input2");
      
            String input2Value= input2.getSubmittedValue().toString();
      

答案 1 :(得分:0)

您可以隐藏表单并使用JSF-AJAX节点的 onevent 属性。 当获取AJAX响应并将表单设置为可见时,将调用它。

所以整个过程可能就像:

  1. 通过css使表单不可见。与<form style="display:none">
  2. 一样
  3. 正在处理您的<f:ajax>元素。
  4. 获得回复后,调用其属性 onevent 并将您的表单设置为可见。
  5. 提示:为了更好的外观和感觉,您可以使用JQuery来显示表单。使用它像:

    $("#myform").fadeIn();