フォームがあり、テキストボックスとボタンがある場合、フォームを送信した後、テキストボックスのコンテンツをどのように消去しますか?
<h:inputText id="name" value="#{bean.name}" />
<h:commandButton id="submit" value="Add Name" action="#{bean.submit}" />
テキストボックスに値を入力して送信した後も、値はテキストボックスに表示されます。送信したら、テキストボックスの内容をクリアする必要があります。どうすればこれを達成できますか?
フォームの送信時に呼び出される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`
Saveメソッドのすべての操作が完了した後、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}"/>
応答をレンダリングするときに再描画してはならないマネージド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標準の要求/応答ライフサイクル に従って処理されます。ライフサイクルに従って、管理対象Beanの内容は、アプリケーションイベント(DataForm.Name
)が実行される前に、要求からの値で更新されます(つまり、DataForm.submit
の値が設定されます)。ページがRenderResponseフェーズでレンダリングされると、Beanの現在の値を使用して、ビューがユーザーにレンダリングされます。アプリケーションイベントで値が変更されない限り、値は常にリクエストから適用された値になります。
これを達成する方法はいくつかあります。素朴な方法は、バッキングBeanのフィールドを単純に無効にすることです。非常識な方法は、送信後またはページの読み込み中にもそれを行うジョブのJS/jQueryを取得することです。これらの方法は、不要なコードを導入するだけであり、思考/設計の問題を示しています。必要なのは、新しいリクエスト/ページ/ビュー/ Beanから始めることだけです。 GETリクエストで取得するのと同じように。
したがって、最善の方法は、送信後にリダイレクトを送信することです。おそらくすでに聞いたことがあるでしょう: POST-Redirect-GET 。 POSTリクエスト(フォーム送信)の後に、意図したとおりに新しいGETリクエストを提供します。これには、以前に送信されたデータが再送信されないという追加の利点があります。エンドユーザーはその後、無意識のうちにF5を押し、ブラウザの警告を無視します。
JSFでPRGを実行する方法はいくつかあります。
_faces-redirect=true
_クエリ文字列を使用して同じビューに戻るだけです。 _/page.xhtml
_を想定すると、アクションメソッドでこれを行うことができます。
_public String submit() {
// ...
return "/page.xhtml?faces-redirect=true";
}
_
JSF 1.xの方法でナビゲーションケースをいじくり回している場合は、問題のナビゲーションケースに_<redirect/>
_を追加する必要があります。 navigation-ruleを使用してリダイレクトを行う方法 も参照してください。
再利用性を高めるために、プログラムでビューIDを取得できます。
_public String submit() {
// ...
UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
return view.getViewId() + "?faces-redirect=true";
}
_
いずれにせよ、リクエストURLにも保持する必要のあるパラメータを表示している場合は、結果に_&includeViewParams=true
_を追加します。 JSFフォーム送信でのGETリクエストクエリ文字列パラメータの保持 も参照してください。
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スコープを選択する方法は?
アクションが成功した結果として表示される顔のメッセージがある場合は、それをフラッシュメッセージにします。 リダイレクトされたページにfacesメッセージを表示する方法 も参照してください。
_public String submit() {
// ...
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(clientId, message);
context.getExternalContext().getFlash().setKeepMessages(true);
return "/page.xhtml?faces-redirect=true";
}
_
F5が常に新しいGETリクエストをトリガーするajaxのみのページがある場合にのみ、アクションメソッドでモデルフィールドを単にnullにすることはそれほど害にはなりません。
あなたは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のすべての値を再帰的にリセットする方法のコードスニペットをここに追加しました: フォームのすべてのフィールドをリセット
これは、検証エラーを示す送信済みフォーム、およびフォームに新しく入力された値に対して機能します。