Очистить входные значения формы JSF после отправки - PullRequest
10 голосов
/ 08 августа 2011

Если есть форма, в которой есть текстовое поле и кнопка, как вы удаляете содержимое текстового поля после отправки формы?

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

После того как я введу значение в текстовое поле и отправлю его, оно все равно появится в текстовом поле. Мне нужно очистить содержимое текстового поля после его отправки. Как мне этого добиться?

Ответы [ 5 ]

12 голосов
/ 08 августа 2011

Вы можете исключить свойство управляемого компонента, которое не следует перекрашивать при отображении ответа. Это можно сделать с помощью кода, аналогичного приведенному ниже фрагменту кода:

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.Name) перед выполнением события приложения (DataForm.submit). Когда страница отображается в фазе ответа ответа, текущее значение bean-компонента используется для визуализации представления пользователю. Если значение не изменяется в событии приложения, оно всегда будет тем, которое применено из запроса.

11 голосов
/ 23 апреля 2015

Введение

Есть несколько способов добиться этого. Наивный способ - просто обнулить поля в бобе. Безумный способ - захватить JS / jQuery для работы, которая делает это после отправки или даже во время загрузки страницы. Эти способы только вводят ненужный код и указывают на проблему мышления / дизайна. Все, что вам нужно, это просто начать с нового запроса / page / view / bean. Примерно так, как вы получите с запросом GET.

POST-Redirect-GET

Таким образом, лучший способ - просто отправить перенаправление после отправки. Вы, вероятно, когда-либо слышали об этом: POST-Redirect-GET . Он дает вам новый новый запрос GET после запроса POST (отправка формы), именно так, как вы и планировали. Это дает дополнительное преимущество, заключающееся в том, что ранее представленные данные не передаются повторно, когда конечный пользователь неосознанно нажимает F5 после этого и игнорирует предупреждение браузера.

Существует несколько способов выполнения PRG в JSF.

  1. Просто вернитесь к тому же представлению со faces-redirect=true строкой запроса. Предполагая /page.xhtml, вы можете сделать это в методе действия:

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

    Если вы все еще возитесь с навигационными кейсами по пути JSF 1.x, тогда вам нужно добавить <redirect/> к рассматриваемому кейсу. См. Также Как сделать перенаправление с помощью правила навигации .

  2. Чтобы сделать его более пригодным для повторного использования, вы можете получить идентификатор вида программно:

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

    В любом случае, если вы просматриваете параметры, которые также должны быть сохранены в URL запроса, добавьте &includeViewParams=true к результату. См. Также Сохранение параметров строки запроса GET в форме JSF submit .

  3. Если вы используете какое-либо решение для перезаписи URL, которое работает вне контекста JSF, то вам лучше всего взять текущий 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-компонент не будет воссоздан с нуля. У вас есть еще одна проблема, которую тоже нужно решить. Разделите его на меньшую область сессий для данных области сеанса и область с видом представления для данных области просмотра. См. Также Как правильно выбрать область применения бобов?

Лица сообщений

Если у вас есть сообщение лица, которое будет показано в результате успешного действия, просто сделайте его мгновенным. См. Также Как показать сообщение о лицах на перенаправленной странице .

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, то просто обнуление полей модели в методе действия не должно сильно навредить.

Смотри также:

4 голосов
/ 16 июля 2012

Вы можете очистить форму из метода 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 () вызывается из метода save после всех операцийметод сохранения завершен.В качестве опции вы можете выполнить очистку, только если операция методов прошла успешно ... Метод ниже помещен в класс ProductController ...

    public String saveProduct(){
    try {
        product.save(); 
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}

Вызов метода из view / jsp будет выглядеть так:следующее:

<h:commandButton value="Save" action="#{productController.saveProduct}"/>
3 голосов
/ 23 декабря 2012

Вы можете сделать это с помощью 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('');});
1 голос
/ 18 февраля 2017

Я добавил фрагмент кода, как рекурсивно сбросить все значения для текущего ViewRoot для JSF 2: Сбросить все поля в форме

Это работает для отправленных форм, также показывая ошибки проверкикак для вновь введенных значений в форме.

...