仅在验证成功时渲染组件

Render a component only when validation success

在 JSF 2.X 中,是否可以仅在验证成功时才渲染组件?

在我的应用程序中,我有许多必须填写的字段。这些数据可以通过搜索键从 WebService 导入。

当用户输入有效的搜索键时,系统会搜索其他字段并使用新值呈现它们。但是,当用户输入不存在的密钥(或任何其他验证错误)时,服务器会生成验证错误但仍会呈现字段,从而丢失已填充的所有数据。

我需要的是用户可以执行查询,如果查询没有 return 结果,这不会影响他已经输入的任何数据。

下面是一个代码示例。因此,如果用户填写了 updateThisOnSuccess 中的字段,并且在尝试查询未成功之后,填写的值不会丢失。

    <h:inputText value="#{controller.searchWebService}" >
        <f:ajax execute="@this" render="updateThisOnSuccess messages" />
    </h:inputText>

    <h:panelGroup id="updateThisOnSuccess">
        <h:inputText value="#{controller.field}" />
        <!-- other fields -->
    </h:panelGroup>

将字段值提交给 运行 搜索似乎也不是一个选项,因为这将导致需要验证 updateThisOnSuccess.

中的字段

注意:我看到 由@BalusC 给出了类似的问题,但这与我想知道的不同,在那种情况下,foo-holder 总是呈现并且 foo 是调节。这不是我的情况,因为这种方法会使控件在验证失败时不出现。

你可以这样做:

<f:ajax execute="@this" render="#{controller.success} message"/>

其中 success 是一个字符串属性,如果 WS 失败则为空,否则为 "updateThisOnSuccess"。

或者您可以取消用于通知用户 WS 失败的 JSF 验证机制。想一想,它并不是真正的模型验证。您可以在 WS Id 字段旁边绘制一个红色图标或使用支持 bean 中的布尔标志属性的类似内容。

您可以更改将在渲染阶段处理的组件,更改 getRenderIds() of PartialViewContext. According to documentation 处的集合,此 集合是可变的

FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().remove("formName:updateThisOnSuccess");

为了测试这个解决方案,我使用了这个控制器:

@Named
@ViewScoped
public class Controller implements Serializable {

    private static final long serialVersionUID = 1L;

    private final static List<String> LIST_VALID_WEB_SERVICE_SEARCHS =
        Arrays.asList(new String[] {"foo", "bar"});

    private String webServiceParameter;
    private Integer field01;

    public void searchWebService() {

        if (LIST_VALID_WEB_SERVICE_SEARCHS.contains(getWebServiceParameter())) {
            setField01(123);
        } else {

            FacesContext facesContext = FacesContext.getCurrentInstance();

            facesContext.getPartialViewContext().getRenderIds().remove("formFields");

            FacesMessage facesMessage = new FacesMessage("Search not found in WebService.");
            facesMessage.setSeverity(FacesMessage.SEVERITY_ERROR);
            facesContext.addMessage("formName:searchWebService", facesMessage);
        }
    }

    public void submit() {
        System.out.println("submitted");
    }

    // Getters and Setters
}

并使用了这个视图:

<h:form id="formSearch">
    <h:inputText id="webServiceParameter" value="#{controller.webServiceParameter}">
        <f:ajax execute="@this" render="formFields messages" listener="#{controller.searchWebService}" />
    </h:inputText><br />
</h:form>

<h:form id="formFields">
    <h:inputText id="field01" value="#{controller.field01}" required="true">
        <f:validateLongRange minimum="2" maximum="345" />
    </h:inputText><br />
    <!-- other fields -->

    <h:commandButton value="submit" action="#{controller.submit}">
        <f:ajax render="@form messages" execute="@form" />
    </h:commandButton>
</h:form>

<h:messages id="messages" />

请试试这个。要求是您必须使用 Bean Validation 实现模型验证,如果需要,搜索字段必须实现 JSF 验证。 如果您写入“123456”,则返回数据,否则不返回任何内容并打印一条消息。

支持 bean:

@Named
@ViewScoped
public class yourBean implements Serializable{

    private static final long serialVersionUID = 1L;

    @Size(min=2)
    private String field01;

    private String searchWebService;    

    public void saveF(){
        System.out.println("save");
    }

    public void searchWebServiceF(){

        Boolean successWS = ("123456").equals(this.searchWebService);
        if(successWS){
            this.setField01("WS data");
        }else{
            FacesContext.getCurrentInstance().
                addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "WS fails", ""));
        }
    }

    public String getSearchWebService() {
        return searchWebService;
    }
    public void setSearchWebService(String searchWebService) {
        this.searchWebService = searchWebService;
    }
    public String getField01() {
        return field01;
    }
    public void setField01(String field01) {
        this.field01 = field01;
    }
}

在您的页面中:

<h:form id="form01">
<h:messages id="message"/>
    <h:inputText id="wsid" value="#{pruebasBorradorBean.searchWebService}">
        <f:validateLength maximum="6"/>
        <f:ajax execute="@form" render="@form" listener="#{pruebasBorradorBean.searchWebServiceF()}" />
    </h:inputText>

    <h:panelGroup id="thedata">
        <h:inputText value="#{pruebasBorradorBean.field01}">
            <f:validateBean disabled="#{param['javax.faces.source']!='form01:save'}"/>
        </h:inputText>
        <!-- other fields -->
    </h:panelGroup>
    <h:commandButton id="save" value="submit">
        <f:ajax render="thedata message" execute="@this thedata" listener="#{pruebasBorradorBean.saveF()}"/>
    </h:commandButton>

</h:form>

试试这个

<h:panelGroup id="updateThisOnSuccess">
    <ui:fragment rendered="#{not facesContext.validationFailed}">
        <h:inputText value="#{controller.field}" />
        <!-- other fields -->
    </ui:fragment>
</h:panelGroup>