整个表单reRender后,JSF CommandLink无法在Firefox上运行

时间:2009-11-25 09:16:21

标签: javascript ajax jsf richfaces

我有一个仅在IE6浏览器上使用的JSF 1.2应用程序(Sun RI,Facelets,Richfaces)。现在,我们还必须支持Firefox(是的!)。

在我的一个页面中,我有一个包含一个按钮的表单,该按钮将重新呈现整个表单。重新渲染后,会以此形式添加一些链接(<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是组件<h:commandLink/>生成的Javascript函数)

问题是document.forms["foobar"]在最初呈现页面时运行良好,但是一旦在Ajax调用之后重新呈现表单,此代码在Firefox上不再起作用(但适用于IE6)。

当我在Ajax调用之后单击表单中的一个链接时,这会导致Javascript错误。

请注意,如果我在Ajax调用后调用document.getElementById("foobar");,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正在从DOM树对象中删除 reRender -ed元素(特别是我的foobar表单),这会导致删除来自document.forms数组。 然后,它再次添​​加foobar表单及其新内容。但Firefox确实更新document.forms数组,而IE6则更新document.forms["foobar"]数组。 这就是为什么undefined在Ajax调用之后返回reRender

我解决此问题的方法是更改​​reRender属性,以便仅重新呈现表单的子部分,而不是表单本身。这样,我的链接就可以了。

但是,我想知道是否有其他方法可以解决此问题,而无需修改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); }; 属性。 有什么想法吗?


修改

单击命令链接时的Javascript代码如下:

<h:commandLink>

jsfcljs(document.forms['foobar'], 'someId', '') onclick属性中,我们调用在jsfcljs(undefined, 'someId', '')中评估的f。然后,当调用f is undefined时,我收到一条Javacript错误,指出{{1}}。

2 个答案:

答案 0 :(得分:2)

问题实际上是我所看到的HTML问题。

您的表单应使用名称定义,而不仅仅是id属性:

不同的浏览器对名称和ID等效区别对待。如果这不能解决您的问题评论,我将生成一个测试用例,不需要服务器端来演示您所看到的任何效果。

解决问题代码的另一种方法是在客户端重写内联onclick事件调用,以便通过id而使用document.getElementById(“foobar”)调用来引用表单而不是document.forms [“foobar” ]

答案 1 :(得分:0)

我记得这是Sun Mojarra 1.2(已经存在4年)的一个漏洞。升级lib应该可以解决这个问题。目前最新的Sun Mojarra 1.2是1.2_14,仅在三周前发布。只需用/WEB-INF/lib替换它们中的两个JSF库。