IE6ブラウザーでのみ使用されていたJSF1.2アプリケーション(Sun RI、Facelets、Richfaces)があります。今、Firefoxもサポートする必要があります(ええ!)。
私のページの1つに、フォーム全体を再レンダリングするボタンを含むフォームがあります。再レンダリング後、いくつかのリンク(<h:commandLink/>
)がこのフォームに追加されます。
JSFコードは次のようになります。
<h:form id="foobar">
...
<a4j:commandButton ... reRender="foobar"/>
...
<h:commandLink .../>
</h:form>
私の問題は、コマンドリンクコンポーネントによって生成されたHTMLコードに関連しています。これは次のとおりです。
<a href="#" onclick="if(typeof jsfcljs == 'function'){jsfcljs(document.forms['foobar'],'...','');}return false">bla bla</a>
(詳細についてjsfcljs
は、コンポーネントによって生成されたJavascript関数です<h:commandLink/>
)
問題はdocument.forms["foobar"]
、ページが最初にレンダリングされたときにうまく機能していることですが、Ajax呼び出しの後にフォームが再レンダリングされると、このコードはFirefoxでは機能しなくなります(ただし、IE6では機能します)。
これにより、Ajax呼び出しの後にフォーム内の1つのリンクをクリックすると、Javascriptエラーが発生します。
document.getElementById("foobar");
Ajax呼び出しの後に呼び出すと、Firefoxが私のフォームを見つけることに注意してください...
次のJavascript関数を検討する場合:
function test() {
var e = document.forms;
var tmp = "";
for (i = 0; i < e.length; i++) {
tmp = tmp + e[i].id + " ; ";
}
alert(tmp);
}
Ajax呼び出しの前後に実行すると、次の結果が得られます。
someForm ; anotherForm ; foobar ; // Before Ajax call on FF
someForm ; anotherForm ; // After Ajax call on FF. PROBLEM HERE!
someForm ; anotherForm ; foobar ; // Before Ajax call on IE6
someForm ; anotherForm ; foobar ; // After Ajax call on IE6
問題の理由についての私の考えは次のとおりです。
クライアント側でAjax応答を受信すると、a4jはreRender-ed要素(特に私のfoobar
フォーム)をDOMツリーオブジェクトから削除します。その結果、document.forms
配列から削除されます。次に、foobar
新しいコンテンツを含むフォームを再度追加します。ただし、Firefoxはアレイを更新しませんdocument.forms
が、IE6は更新します。そのため、Ajax呼び出しの後にdocument.forms["foobar"]
戻ります。undefined
この問題を解決するための私の解決策reRender
は、フォーム自体ではなく、フォームのサブパーツのみを再レンダリングするために属性を変更することです。このように、私のリンクは機能します。
reRender
ただし、属性を変更せずにこの問題を解決する別の方法があるかどうかを知りたいと思いました。何か案が?
編集
コマンドリンクをクリックしたときのJavascriptコードは次のとおりです。
function dpf(f) {
var adp = f.adp;
if (adp != null) {
for (var i = 0; i < adp.length; i++) {
f.removeChild(adp[i]);
}
}
};
function apf(f, pvp) {
var adp = new Array();
f.adp = adp;
var ps = pvp.split(',');
for (var i = 0, ii = 0; i < ps.length; i++, ii++) {
var p = document.createElement("input");
p.type = "hidden";
p.name = ps[i];
p.value = ps[i + 1];
f.appendChild(p);
adp[ii] = p;
i += 1;
}
};
function jsfcljs(f, pvp, t) {
apf(f, pvp);
var ft = f.target;
if (t) {
f.target = t;
}
f.submit();
f.target = ft;
dpf(f);
};
<h:commandLink>
onclick属性では、で評価されるを呼び出しjsfcljs(document.forms['foobar'], 'someId', '')
ますjsfcljs(undefined, 'someId', '')
。次に、f
が呼び出されると、それを示すJavacriptエラーが発生しますf is undefined
。