個々のフィールドですぐに AJAX 検証を行い、AJAX を使用してフォーム全体を処理するフォームを作成しようとしています。
しかし、一部のコンポーネントでは、このアプローチで問題が発生しました。たとえば、OpenFaces の <o:dropDownField/> コンポーネントは、何度もすばやく再レンダリングされると、スクリプト エラーを引き起こします。
JSF 1.2、RichFaces 3.3.3.Final、および OpenFaces 2.0.r13 を使用すると、フォームは次のようになります。
<a4j:queue/>
<h:form>
<h:panelGroup id="myForm">
<f:facet name="aroundInvalidField">
<s:div style="border: 2px solid red"/>
</f:facet>
<h:messages/>
<h:panelGrid id="myGrid" columns="2">
<s:decorate id="dropDownFieldDecorator">
<o:dropDownField id="dropDownField"
value="#{controller.library}"
autoComplete="true">
<o:dropDownItem value="OpenFaces"/>
<o:dropDownItem value="RichFaces"/>
<a4j:support event="onchange"
ajaxSingle="true"
reRender="dropDownFieldDecorator"/>
</o:dropDownField>
</s:decorate>
<a4j:commandButton value="Save"
action="#{controller.save}"
reRender="myForm"/>
</h:panelGrid>
</h:panelGroup>
</h:form>
dropDownField の入力に何かを書き込んで (そしてそこにフォーカスを置いたままにして)、[保存] ボタンをクリックすると、2 つの AJAX 呼び出しが次々に取得されます。
- 1 つは dropDownField の変更イベント用、および
- 1 つは「保存」ボタン用です。
少なくとも IE8 では、「O$.Tables._initColumns: colTags.length(0) != colCount(1)」というスクリプト エラーが発生する可能性が高くなります。
この問題は、<o:dropDownField> コンポーネントの JavaScript 初期化が、setTimeout() でラップすることにより、1 つまたは複数のステップを「延期」するという事実に起因しているようです。
そのため、richfaces AJAX プロセッサは、最初のリクエストの処理が終了したと判断すると、2 番目のリクエストの処理を開始します。しかし、延期されたステップの実行が開始されると、2 つの dropDownField 初期化コード セットが同時にジョブを実行しようとすることになります。これらは互いに足を踏み入れ、スクリプト エラーが発生します...
この問題を回避する方法について何か提案はありますか?