複数のフォームがあり、必須フィールドとオプションフィールドがあります。
submitそのようなフォームには、必須属性の検証を実行する必要がありますが、これは正常に機能します。 キャンセルこのようなフォームには、属性immediate="true"
上のp:commandbutton
、リクエスト値の適用中にアクションを実行します-ここで説明するフェーズ: 特定のボタンがクリックされましたか?
ただし、大きなフォームの場合は、ユーザーに保存ボタンを提供して、後で続行できるようにします。
現在の状態を保存するだけのために、必須属性の検証も無視したいと思います。ただし、immediate="true"
は機能しません。なぜなら、JSFライフサイクルが「UpdateModelValues」フェーズに決して到達しないため、saveメソッドsimpleは何も保存しないからです。 ( http://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html による)
だから、必要なチェックをバイパスするが、ライフサイクルの半分をスキップしない方法は?
各ボタンは、フォームのメンバーである限り、Param-List内にエントリを作成します。そのため、そのエントリの存在のチェックを「必須」パラメータに単純に適用しました。
<h:form id="form" prependId="true">
...
<p:inputText id="someId"
required="#{param['form:save']==null}" ... />
...
<p:commandButton id="save" value="Save" />
<p:commandButton id="submit" value="Submit" />
<p:commandButton id="cancel" value="Cancel" immediate="true" />
</h:form>
[送信]をクリックすると、param['form:save']
はNULL
であり、式がtrue
に変換されるため、検証が実行されます。
[保存]をクリックすると、param['form:save']
はNOT NULL
(ただし空!)、false
に解決されるため、検証は無視されます。 (または、JSFがfalse
に評価される式beeingのために必須フィールドではないと考えているとしましょう)
ボタンをクリックしたときに検証をスキップする場合は、スキップしたいボタンにパラメーターを簡単に追加します。例:
<p:commandButton value="button1" action="#{bean.action()}" >
<f:param name="skipValidator" value="true"/>
</p:commandButton>
次に、バリデーターでこのパラメーターを読み取り、trueの場合はスキップできます。
@FacesValidator("com.validators.MyValidator")
public class MyValidator implements Validator{
public void validate(FacesContext ct, UIComponent co, Object obj) throws ValidatorException {
if(!continueValidation()){
return;
}
// validation process
}
protected boolean continueValidation() {
String skipValidator= FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("skipValidator");
if (skipValidator != null && skipValidator.equalsIgnoreCase("true")) {
return false;
}
return true;
}
}
これは素晴らしい質問であり、非常に役立つ回答です。このアプローチは、immediate="true"
で多くの手間を省きます。
この情報を追加したいのですが(まだコメントすることはできません)。あなたのコード例ではJSF 2.以上(私を修正)が必要と思われます。私のようにJSF 1.1/1.2を使用することをめている場合は、次の変更/追加を検討してください。
<h:form id="form">
...
<p:inputText id="someId" required="#{!empty param['save']}" ... />
...
<p:commandButton id="save" value="Save" />
</h:form>
="{true and ...}"
を使用していますが、これは間違いかもしれません(#
はありません)?!empty ...
バージョンが好きになりました。他の人が提案したものに代わるものは、カスタムのBeanValidator
を使用することです。これは、たとえば、id saveのボタンをクリックした場合にフォームを検証します。検証を実行するために暗黙的に定義されていない他のボタンは検証されず、利用可能なデータを送信するだけです。ナイスでクリーンな完全な例を見つける here
私の場合、paramsにボタンのclientIdが見つかりませんでしたが、このparam['javax.faces.source'] = buttonClientId
リクエストマップ内。値は、クリックされたボタンのclientIdになります。
このような場合には skipValidators を使用します(すべての検証がスキップされると仮定します)。 omnifaces のコード
<h:form>
<h:dataTable value="#{bean.items}" var="item">
<h:column>
<h:inputText value="#{item.value}" required="true" />
</h:column>
</h:dataTable>
<h:commandButton value="add new row" action="#{bean.add}">
<o:skipValidators />
</h:commandButton>
<h:commandButton value="save all data" action="#{bean.save}" />
<h:messages />
</h:form>