次のスクリプトを使用して、Mojarra 2.0/2.1/2.2 バグを修正できます (注: これは MyFaces には現れません)。このスクリプトはjavax.faces.ViewState
、ajax 更新後にビュー ステートを取得しなかったフォームの非表示フィールドを作成します。
jsf.ajax.addOnEvent(function(data) {
if (data.status == "success") {
fixViewState(data.responseXML);
}
});
function fixViewState(responseXML) {
var viewState = getViewState(responseXML);
if (viewState) {
for (var i = 0; i < document.forms.length; i++) {
var form = document.forms[i];
if (form.method == "post") {
if (!hasViewState(form)) {
createViewState(form, viewState);
}
}
else { // PrimeFaces also adds them to GET forms!
removeViewState(form);
}
}
}
}
function getViewState(responseXML) {
var updates = responseXML.getElementsByTagName("update");
for (var i = 0; i < updates.length; i++) {
var update = updates[i];
if (update.getAttribute("id").match(/^([\w]+:)?javax\.faces\.ViewState(:[0-9]+)?$/)) {
return update.textContent || update.innerText;
}
}
return null;
}
function hasViewState(form) {
for (var i = 0; i < form.elements.length; i++) {
if (form.elements[i].name == "javax.faces.ViewState") {
return true;
}
}
return false;
}
function createViewState(form, viewState) {
var hidden;
try {
hidden = document.createElement("<input name='javax.faces.ViewState'>"); // IE6-8.
} catch(e) {
hidden = document.createElement("input");
hidden.setAttribute("name", "javax.faces.ViewState");
}
hidden.setAttribute("type", "hidden");
hidden.setAttribute("value", viewState);
hidden.setAttribute("autocomplete", "off");
form.appendChild(hidden);
}
function removeViewState(form) {
for (var i = 0; i < form.elements.length; i++) {
var element = form.elements[i];
if (element.name == "javax.faces.ViewState") {
element.parentNode.removeChild(element);
}
}
}
エラーページの<h:outputScript name="some.js" target="head">
中に含めるだけです。<h:body>
問題のページが JSF を使用していることを保証できない場合は、 の<f:ajax>
自動インクルードをトリガーするため、呼び出しの前に追加のチェックjsf.js
を追加するか、if (typeof jsf !== 'undefined')
jsf.ajax.addOnEvent()
<h:outputScript library="javax.faces" name="jsf.js" target="head" />
jsf.ajax.addOnEvent
標準の JSF のみをカバーし<f:ajax>
、PrimeFaces<p:ajax>
などをカバーしていないことに注意してください<p:commandXxx>
。PrimeFaces ajax リクエストにも対応するには、以下を追加します。
$(document).ajaxComplete(function(event, xhr, options) {
if (typeof xhr.responseXML != 'undefined') { // It's undefined when plain $.ajax(), $.get(), etc is used instead of PrimeFaces ajax.
fixViewState(xhr.responseXML);
}
}
JSF ユーティリティ ライブラリOmniFacesを使用している場合は更新してください。1.7以降、上記が OmniFaces の一部になっていることを知っておくとよいでしょう。で次のスクリプトを宣言するだけ<h:body>
です。ショーケースもご覧ください。
<h:body>
<h:outputScript library="omnifaces" name="fixviewstate.js" target="head" />
...
</h:body>