【问题标题】:JSF:: h:commandLink onsubmit(return validateRow(this)) problemJSF::h:commandLink onsubmit(return validateRow(this)) 问题
【发布时间】:2026-01-08 06:10:01
【问题描述】:

我在数据表的一列中有一个 h:commandLink。

JSF

<h:commandLink id="save" actionListener="#{ApplicationManagerBean.update}"  
rendered="#{routeappcode.edit}"
value="save" onclick="return validateRow(this)"/>

生成的 HTML 是

 <a id="routeappcodesummary:summarytable:2:save" 
 onclick="var cf = function(){return validateRow(this)};
 var oamSF = function(){return oamSubmitForm('routeappcodesummary','routeappcodesummary:summarytable:2:save');};return (cf()==false)? false : oamSF();" 
    href="#">save</a>

Mojarra 1.2_15

    <a href="#" onclick="var a=function(){return validateRow(this);};var b=function()
{if(typeof jsfcljs == 'function'){jsfcljs(document.getElementById('j_id_jsp_1765393453_2'),
{'j_id_jsp_1765393453_2:j_id_jsp_1765393453_3:0:j_id_jsp_1765393453_7':'j_id_jsp_1765393453
_2:j_id_jsp_1765393453_3:0:j_id_jsp_1765393453_7'},'');}return false};return (a()==false) ?
 false : b();">test</a>

这里为onclick生成的javascript封装了JSF标签中提供的脚本。

function validateRow(link){
    //link is not a link object but some window object.
    var parent = link.parentNode;
}

在 javascript 函数中,我们获取的不是链接对象,而是窗口对象。 原因是 JSF 标记中提供的脚本被封装并且由于 this 的值 参考变化。

我该如何解决这个问题,以便我可以在我的脚本中获取链接对象?

使用 onmouseup 在 IE 6 中不起作用。

使用 JSF 1.2

【问题讨论】:

  • 我记得大约 4-5 年前发布的古代 Mojarra 1.2 版本中的类似问题,但是我不认识自动生成的 oamSF 变量名称。您使用的是什么 1.2 impl/version 确切?较新的 Mojarra 应该在 webapp 启动期间记录,否则只需提取 impl JAR 文件并读取 MANIFEST.MF 文件。如果仍然不确定,只需升级到最新版本并重试。 Mojarra 目前在 1.2_15。
  • 与最新的 mojarra 相同。
  • Google 得知生成的代码是 MyFaces 的典型代码。你真的用 Mojarra 代替它吗?如果生成的代码相同,那么肯定没有正确升级/替换。
  • 我正在使用 mojarra 和 tomahawk 组件库。
  • 我敢打赌,你的类路径被 Mojarra 和 MyFaces 实现的混合污染了。您问题的代码 sn-p 中生成的 JS 代码是 MyFaces 的典型代码。我不认识那些来自 Mojarra 的生成的 JS 变量名。您不能也不应该混合 JSF 实现。使用其中之一。我个人推荐 Mojarra。请注意,Tomahawk 是独立于实现的。它只是一个组件库。 Tomahawk 不需要 MyFaces 作为实现。它在 Mojarra 上同样有效。

标签: javascript jsf


【解决方案1】:

您确实不能为您的 JavaScript 函数提供对 this 的引用,因为 onclick 代码将被封装在 JavaScript 函数中。

您可以尝试使用一些 JavaScript 代码在您的 validateRow() 函数中找到此链接元素,例如 one proposed by Stig Henriksen

另一个想法是在你的链接上添加一个 fake CSS 类,然后使用这个类搜索你的元素:

<h:commandLink id="save" actionListener="#{ApplicationManagerBean.update}"
    rendered="#{routeappcode.edit}" value="save"
    onclick="return validateRow();" styleClass="saveLink"/>

然后,在您的 JavaScript 代码中(我在这里使用 jQuery,但您可以改用纯 JS):

function validateRow() {
    // We retrieve a jQuery object:
    var jQueryObject = $("a.saveLink");
    // If you prefer to get a "pure" JavaScript object
    var pureJavaScriptObject = $("a.saveLink").get(0);
    // continue your work here...
}

【讨论】:

    【解决方案2】:

    不知道为什么 JSF 会这样做,但这里有一个使用 jQuery 获取链接的解决方法:

      <h:commandLink id="save" actionListener="#{ApplicationManagerBean.update}"  
        rendered="#{routeappcode.edit}"value="save" 
        onclick="return validateRow($('a[id*=save]')[0])"/>
    

    【讨论】: