p:dialog
コンポーネント内のフォームがAJAX経由で送信されています。ダイアログ内のフォームは、ui:include
の別の.xhtml
フォームとそのコンポーネントだけを含んでいます(いいえ、私はフォームを入れ子にしていません;ダイアログ自体はどのフォームにもありません)。インクルードされたページのバッキングBeanは「ViewScoped」です。アクションフォーム/メソッド呼び出しが失敗した後、p:ダイアログで閉じるフォーム
ほとんどのものは、細かい機能:
- 成功した検証では、フォームが保存メソッドを実行します。保存に成功すると、ダイアログが閉じます。後続のレコードを開くと、データベースから適切なレコード情報が表示されます。
- 検証に失敗すると、送信された値はそのまま残り、ダイアログは開いたままになり、検証エラーが表示され、無効なフィールドが修正され、結果が正常に保存されます。
p:commandButton
で呼び出されたaction
が失敗すると問題が発生します。それが失敗した場合、ダイアログは開いたままになり、h:messages
を介して "変更を保存中にエラーが発生しました"と表示されます。さらに、提出された値は依然として入力フィールドに残っています。これはフォームが開いたままの状態では問題ありませんが、ダイアログを閉じて再度開くと、入力された値はテキストフィールドにSTILLになります。これは、保存が成功したという印象をユーザーに与えるためです(ダイアログの更新により、h:messages
コンポーネントが空白になったため)。
- 1.1)ダイアログのオープンで、Beanの新しいインスタンスに含まれるフォームのバッキングBeanの設定:
は、これまでのところ私はこの問題を改善しているNONEそのうち以下を、試してみました。
- 1.2)Beanは新しいインスタンスになっているので、データオブジェクトの詳細をアドレスオブジェクトに再投入しています。
- 2.1)ダイアログのクローズボタンを無効にし、
p:commandButton
"0123"ボタンを追加して、 のp:resetInput
コンポーネントにダイアログを閉じます/フォームをリセットします。 (ダイアログは閉じますが、フォームには の値が続きます)。 - 2.2)
p:commandButton
のメソッドを呼び出し、インクルードされたフォームのバッキングBeanのRequestMap
を削除します。 - 2.3)ボタンを
immediate=true
とimmediate=false
の両方に設定してみました。 - 2.4)
[email protected]
に設定されたボタンを試しましたが、同様の方法を使ってフォームを閉じて、 の再オープン時に新しいフィールドを確保しています。
バッキングBeanを新しいインスタンスに設定してからアドレスオブジェクトを再投入すると、新鮮なフォームが表示されますが、NOPEと考えると思います。 mainform.xhtmlの
部分
<p:dialog id="dlgAddress"
header="Address Edit"
widgetVar="dialogAddress"
dynamic="true"
modal="false"
closable="false"
resizable="false"
styleClass="dlgAddress"
visible="#{addressform.showDlgAddress}">
<ui:include src="addressform.xhtml"/>
</p:dialog>
addressform:ここ
は、ソースの一部です。XHTML
<h:form id="fDlgAddress">
<div id="addresses-container">
<h:messages id="msgDlgAddress" errorClass="errormsg" infoClass="infomsg1" layout="table"/>
<h:panelGrid columns="1"
styleClass="pgAddresses"
rendered="#{!addressform.address.exists}">
<h:outputText value="No active #{addressform.address.atypCode} address found."
styleClass="record-not-exists"/>
<h:outputText value="Use the form below to create one."/>
</h:panelGrid>
<p:panelGrid columns="2"
styleClass="pgDlgForm pgAddresses">
<h:outputLabel value="Address Type"/>
<h:inputText id="atypCode1"
value="#{addressform.address.atypCode}"
disabled="true"
rendered="#{addressform.address.exists}"/>
<h:selectOneMenu id="atypCode2"
value="#{addressform.address.atypCode}"
rendered="#{!addressform.address.exists}">
<f:selectItems value="#{addressform.atypCodeList}"
var="atyp"
itemValue="#{atyp}"
itemLabel="#{atyp}"/>
</h:selectOneMenu>
<h:outputLabel value="Street 1"
for="street1"/>
<h:inputText id="street1"
value="#{addressform.address.addressLine1}"/>
<h:outputLabel value="Street 2"
for="street2"/>
<h:inputText id="street2"
value="#{addressform.address.addressLine2}"/>
<h:outputLabel value="Street 3"
for="street3"/>
<h:inputText id="street3"
value="#{addressform.address.addressLine3}"/>
<h:outputLabel value="Street 4"
for="street4"/>
<h:inputText id="street4"
value="#{addressform.address.addressLine4}"/>
<h:outputLabel value="City"
for="city"/>
<h:inputText id="city"
value="#{addressform.address.city}"
required="true"
requiredMessage="Please enter a city."/>
<h:outputLabel value="State"
for="statCode"/>
<h:selectOneMenu id="statCode"
value="#{addressform.address.stateCode}">
<f:selectItem itemLabel="Select State/Province"
itemValue=""/>
<f:selectItems value="#{states.statesList}"
var="stat"
itemValue="#{stat.statCode}"
itemLabel="#{stat.statDesc}"/>
</h:selectOneMenu>
<h:outputLabel value="Zip Code"
for="zipCode"/>
<h:inputText id="zipCode"
value="#{addressform.address.zip}"/>
<h:outputLabel value="Country"
for="natnCode"/>
<h:selectOneMenu id="natnCode"
value="#{addressform.address.nationCode}"
required="true"
requiredMessage="Please choose a nation.">
<f:selectItem itemLabel="Select Country"
itemValue=""/>
<f:selectItems value="#{nations.nationsList}"
var="natn"
itemValue="#{natn.natnCode}"
itemLabel="#{natn.natnDesc}"/>
</h:selectOneMenu>
<h:outputLabel value="From Date"
for="fromDate"/>
<p:calendar id="fromDate"
value="#{addressform.address.fromDate}"
showButtonPanel="true"/>
<h:outputLabel value="To Date"
for="toDate"/>
<p:calendar id="toDate"
value="#{addressform.address.toDate}"
showButtonPanel="true"/>
<h:outputLabel value="Inactivate"
for="inactivateAddress"
rendered="#{addressform.address.exists}"/>
<h:selectBooleanCheckbox id="inactivateAddress"
value="#{addressform.address.inactivate}"
rendered="#{addressform.address.exists}"/>
<h:outputLabel value="Delete"
for="deleteAddress"
rendered="#{addressform.address.exists}"/>
<h:selectBooleanCheckbox id="deleteAddress"
value="#{addressform.address.delete}"
rendered="#{addressform.address.exists}"/>
</p:panelGrid>
</div>
<div class="button-container">
<p:commandButton value="Save Changes"
action="#{addressform.save}"
type="submit"
ajax="true"
process="@form"
update="@form"/>
<p:commandButton value="Cancel"
process="@this"
onclick="dialogAddress.hide();">
<p:resetInput target="fDlgAddress"/>
</p:commandButton>
</div>
</h:form>
Recorddetailsform(アドレスダイアログが呼び出されるフォームのバッキングBean)
public void showDlgAddress(){
FacesContext ctx = FacesContext.getCurrentInstance();
ELResolver resolver = ctx.getApplication().getELResolver();
RecordDetails recordDetails = (RecordDetails) resolver.getValue(ctx.getELContext(), null, "recordDetails");
//Set addressform backing bean to new instance and load address into it from recordDetails
resolver.setValue(ctx.getELContext(), null, "addressform", new Addressform());
Addressform addressform = (Addressform) resolver.getValue(ctx.getELContext(), null, "addressform");
addressform.setAddress(recordDetails.getAddress());
}
Addressform(アドレス形式のバッキングBean)
public void save() {
FacesContext ctx = FacesContext.getCurrentInstance();
RequestContext rctx = RequestContext.getCurrentInstance();
ELResolver resolver = ctx.getApplication().getELResolver();
Records records = (Records) resolver.getValue(ctx.getELContext(), null, "records");
RecordDetails recordDetails = (RecordDetails) resolver.getValue(ctx.getELContext(), null, "recordDetails");
Mainform mainform = (Mainform) resolver.getValue(ctx.getELContext(), null, "mainform");
Person person = (Person) resolver.getValue(ctx.getELContext(), null, "person");
//Pretty lengthy SQL stuff here. Commented out. Just wanted to display the display logic below for the dialog.
if (errorMsg != null) {//If errorMsg is not null, then error occurred.
showDlgAddress = true;//Ensures address dialog remains open in event of action error.
queueErrorMessage(errorMsg);
rctx.update("dlgAddress");
return;//break out of method on error.
} else {
showDlgAddress = false;
rctx.update("dlgAddress");
}
//If everything saves without error, repopulate address and update recordDetails dialog.
recordDetails.populateAddress(records.getSelectedRecord());
mainform.updateDlgRecordDetails();
}
その他の情報:
- JSF2
- Primefaces 3.5
- のTomcat 6.0
- Netbeansの
うん...私は明日仕事でこれを試すことができますが、私はすでにこれを試したと思います。結果はp:resetInputは、レコードがロードされていないかのようにフォームを表示させ、クリアされる前のレコードからの「スタック」された値だけでなく、新しい着信レコードの値もクリアしました。 – mousouchop
信じられないほどこのソリューションは機能します!私は私のダイアログの値をリセットするこの問題について絶望的でした。 '
'はこのトリックを行います。どうもありがとう! –はい。私はこれが確実に動作することを発見しました。私はしかし、問題を引き起こすようではない私のダイアログ内で自分のフォームを入れ子にします。私は自分の問題は、最初に '
'のターゲットとして '@ form'を使って試したときに起こったと思います。 **このコンポーネントで実際のフォームIDを使用する必要があります**また、上記の例と同じフォームを更新する必要があります。ありがとう。 – mousouchop