gpt4 book ai didi

jsf - h :commandButton/h:commandLink does not work on first click, 仅在第二次点击时有效

转载 作者:行者123 更新时间:2023-12-03 11:33:55 25 4
gpt4 key购买 nike

我们有一个 ajax 导航菜单,用于更新动态包含。每个包含文件都有自己的形式。

<h:form>
<h:commandButton value="Add" action="#{navigator.setUrl('AddUser')}">
<f:ajax render=":propertiesArea" />
</h:commandButton>
</h:form>
<h:panelGroup id="propertiesArea" layout="block">
<ui:include src="#{navigator.selectedLevel.url}" />
</h:panelGroup>

它工作正常,但包含文件中的任何命令按钮在第一次单击时都不起作用。它仅适用于第二次点击。

我发现了这个问题 commandButton/commandLink/ajax action/listener method not invoked or input value not updated我的问题在第 9 点中有所描述。
我知道我需要明确包含 <h:form> 的 ID在包含在 <f:ajax render> 中来解决它。
<f:ajax render=":propertiesArea :propertiesArea:someFormId" />

但是,就我而言,表单 ID 事先并不知道。此外,此表单最初在上下文中不可用。

上述情况有什么解决办法吗?

最佳答案

您可以使用以下脚本修复 Mojarra 2.0/2.1/2.2 错误(注意:这不会出现在 MyFaces 中)。此脚本将创建 javax.faces.ViewState ajax 更新后未检索任何 View 状态的表单的隐藏字段。

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>因为他们在幕后使用 jQuery 来完成这项工作。要涵盖 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> 中声明以下脚本即可.另见 showcase .
<h:body>
<h:outputScript library="omnifaces" name="fixviewstate.js" target="head" />
...
</h:body>

关于jsf - h :commandButton/h:commandLink does not work on first click, 仅在第二次点击时有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11408130/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com