提交后清除JSF表单输入值



如果有一个表单,并且有一个文本框和一个按钮,在提交表单后如何删除文本框的内容?

<h:inputText id="name" value="#{bean.name}" />          
<h:commandButton id="submit" value="Add Name" action="#{bean.submit}" />

在文本框中输入值并提交后,该值仍然出现在文本框中。我需要清除文本框的内容,一旦它被提交。我怎样才能做到这一点呢?

简介

有几种方法可以实现这一点。简单的方法是简单地将后台bean中的字段清空。疯狂的方法是在提交后甚至在页面加载期间抓取JS/jQuery来完成这项工作。这些方法只会引入不必要的代码,并指出思维/设计问题。您所需要的只是从一个新的请求/页面/视图/bean开始。就像get请求一样。

POST-Redirect-GET

因此,最好的方法是在提交后发送一个重定向。您可能已经听说过POST-Redirect-GET。它在POST请求(表单提交)之后给您一个新的GET请求,正如您所期望的那样。这还有一个额外的好处,即当最终用户随后无知地按下F5并忽略浏览器警告时,先前提交的数据不会被重新提交。

在JSF中有几种执行PRG的方法。

  1. 只是返回到相同的视图与faces-redirect=true查询字符串。假设是/page.xhtml,您可以在操作方法中这样做:

    public String submit() {
        // ...
        return "/page.xhtml?faces-redirect=true";
    }
    

    如果您还在摆弄导航用例,那么JSF 1。x的方式,然后这是一个问题,添加<redirect/>的导航情况下的问题。

  2. 为了使其更易于重用,您可以通过编程方式获得视图ID:

    public String submit() {
        // ...
        UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
        return view.getViewId() + "?faces-redirect=true";
    }
    

    无论哪种方式,如果您已经查看了需要保留在请求URL中的参数,那么将&includeViewParams=true附加到结果中。另请参见在JSF表单提交中保留GET请求查询字符串参数

  3. 如果你正在使用一些在JSF上下文之外运行的URL重写解决方案,那么你最好抓住当前请求URL(带有查询字符串)并使用ExternalContext#redirect()重定向到确切的那个。

    public void submit() throws IOException {
        // ...
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        StringBuffer requestURL = ((HttpServletRequest) ec.getRequest()).getRequestURL();
        String queryString = ((HttpServletRequest) ec.getRequest()).getQueryString();
        ec.redirect((queryString == null) ? requestURL.toString() : requestURL.append('?').append(queryString).toString());
    }
    

请求/查看作用域bean

请注意,这一切只有在与请求或视图作用域bean结合使用时才能很好地工作。如果您将会话作用域bean绑定到表单,则不会从头重新创建该bean。然后还有另一个问题需要解决。将其拆分为一个较小的会话作用域,用于会话作用域的数据,以及一个视图作用域的数据。参见如何选择正确的bean作用域?

<

脸消息/h2>

如果你有一个faces消息作为成功操作的结果,那么就把它做成一个flash消息。参见如何在重定向页面中显示人脸信息。

public String submit() {
    // ...
    FacesContext context = FacesContext.getCurrentInstance();
    context.addMessage(clientId, message);
    context.getExternalContext().getFlash().setKeepMessages(true);
    return "/page.xhtml?faces-redirect=true";
}
Ajax

如果您碰巧有一个纯ajax页面,其中F5总是会触发一个新的GET请求,那么简单地清空模型字段在操作方法中应该不会造成那么大的损害。

参见:

  • 如何在JSF中导航?如何使URL反映当前页面(而不是前一个)
  • 防止双重提交的纯Java/JSF实现

您可以清空在呈现响应时不应该重新绘制的受管bean的属性。这可以使用类似于下面发布的代码片段来完成:

private String name;
public String getName(){return name;}
public void setName(String name){this.name=name};
public String submit()
{
    //do some processing
    ...
    // blank out the value of the name property
    name = null;
    // send the user back to the same page.
    return null;
}

当前行为的原因可以在JSF运行时处理请求的方式中找到。对视图的所有JSF请求都按照JSF标准请求-响应生命周期进行处理。根据生命周期,在执行应用程序事件(DataForm.submit)之前,使用请求的值(即设置DataForm.Name的值)更新托管bean内容。在Render Response阶段呈现页面时,将使用bean的当前值将视图呈现给用户。除非在应用程序事件中更改了该值,否则该值将始终是从请求中应用的值。

您可以从提交表单时调用的Bean方法中清除表单;'

private String name;
    private String description;
    private BigDecimal price;
/*----------Properties ------------*/
/*-----Getter and Setter Methods---*/
public void save()throws SQLException{
String sql = "INSERT INTO tableName(name,description,price) VALUES (?,?,?)";
    Connection conn = ds.getConnection();
    try {
        PreparedStatement pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, getName());
        pstmt.setString(2, getDescription());
        pstmt.setBigDecimal(3, getPrice());
        pstmt.executeUpdate();
    } catch (SQLException e) {
        e.getMessage();
        e.toString();
    }finally{
        conn.close();
        clear();
    }
}//End Save Method
public void clear(){
    setName(null);
    setDescription(null);
    setPrice(null);
}//end clear`

注意,在保存方法的所有操作完成后,从保存方法调用clear()方法。作为一个选项,只有当方法操作成功时,您才能执行清除…下面的方法被放置在ProductController类中…

    public String saveProduct(){
    try {
        product.save(); 
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}
view/jsp中的方法调用如下所示:

<h:commandButton value="Save" action="#{productController.saveProduct}"/>

可以使用jQuery。

我也有类似的问题。我需要清除弹出窗口的形式。

<rich:popupPanel id="newProjectDialog" autosized="true"
        header="Create new project">
        <h:form id="newProjectForm">
            <h:panelGrid columns="2">
                <h:outputText value="Project name:" />
                <h:inputText id="newProjectDialogProjectName"
                    value="#{userMain.newProject.projectName}"         required="true" />
                <h:outputText value="Project description:" />
                <h:inputText id="newProjectDialogProjectDescription"
                    value="#{userMain.newProject.projectDescription}"     required="true" />
            </h:panelGrid>
            <a4j:commandButton id="newProjectDialogSubmit" value="Submit"
                oncomplete="#{rich:component('newProjectDialog')}.hide();     return false;"
                render="projects" action="#{userMain.addNewProject}" />
            <a4j:commandButton id="newProjectDialogCancel" value="Cancel"
                onclick="#{rich:component('newProjectDialog')}.hide();     return false;" />
        </h:form>
        </rich:popupPanel>
jQuery代码:

$('#newProjectForm').children('input').on('click', function(){$('#newProjectForm').find('table').find('input').val('');});

我添加了一个代码片段,如何在这里为JSF 2递归地重置当前ViewRoot的所有值:重置表单

中的所有字段

这适用于显示验证错误的提交表单以及表单中新输入的值。

相关内容

  • 没有找到相关文章

最新更新