【问题标题】:h:commandLink not firing the form.submit eventh:commandLink 未触发 form.submit 事件
【发布时间】:2011-11-25 22:59:53
【问题描述】:

当我的页面被加载时,我会执行以下 JS 脚本,当任何表单被提交时,我会使用它来显示一个弹出窗口(请稍候...)。

jQuery(function(){
  jQuery("form").submit(function(){jQuery('#wait-link').trigger('click');return true;});
});

这在使用 h:commandButton 标签时可以正常工作,但是当我使用 h:commandLink 标签时它不起作用,因为表单是由 java 脚本提交的(从 jar jsf-impl.jar 中的文件 jsf.js 中)如下所示

mojarra.jsfcljs = function jsfcljs(f, pvp, t) {
  mojarra.apf(f, pvp);
  var ft = f.target;
  if (t) {
    f.target = t;
  }
  f.submit();
  f.target = ft;
  mojarra.dpf(f);
};

为了解决这个问题,我复制了 WEB-INF/resources/javax.faces/jsf.js 下的 jsf.js 文件并修改它以触发表单提交使用 jQuery 的方法。这工作正常,但是:

1) 我不喜欢我正在触摸 jsf.js 文件这一事实,因为它可能会在 JSF 的较新版本中发生变化。

2) 我不喜欢在 jsf.js 文件中使用 jQuery。

有没有更好的解决方案来解决这个问题?

【问题讨论】:

    标签: jsf-2 commandlink


    【解决方案1】:

    您应该使用jsf.ajax.*,因为它是 JSF2 规范的一部分。在那里你有例如jsf.ajax.addOnEvent(callback),它可以满足你的需求。

    在你挂上你的监听器之后,你可以使用尽可能多的 jQuery。

    更新:

    如果你想从你自己的 JS 中截取它,而不用接触他们的东西你可以这样做:

    (function() {
        var oldjsfcljs = mojarra.jsfcljs;
    
        mojarra.jsfcljs = function() { 
            console.log('my stuff before');
            oldjsfcljs.apply(this, arguments);
            console.log('my stuff after');
        }
    })();
    

    【讨论】:

    • jsf.ajax.addOnEvent(callback) 不是只在ajax的情况下使用吗?
    • 是的。即使出于某种奇怪的原因您需要它用于任何形式的表单,您仍然可以仅从 JS 中截取它,而无需触及这些文件:
    • 感谢工作,但我不得不提到 jsf.ajax.addOnEvent(callback) 与问题无关。我将在单独的答案中添加以下解决方案。
    【解决方案2】:

    正如 Bodgan 建议的更好的解决方案是在页面加载时执行以下代码,我不知道 JS 中的术语是什么,但对我来说似乎是一种覆盖。

    jQuery(function(){
      var oldjsfcljs = mojarra.jsfcljs; // save a pointer to the old function
    
      mojarra.jsfcljs = function jsfcljs(f, pvp, t) {
        jQuery(jq(f.id)).trigger('submit');
        oldjsfcljs.apply(this, arguments);
      };
    });
    
    function jq(myid) {
      return '#' + myid.replace(/(:|\.)/g, '\\$1');
    }
    

    注意:jq() 方法仅用于对表单 ID 中的特殊字符进行转义。

    更新:上面的代码似乎可以工作,但如果你有表单中的参数,它就不会,所以我不得不重写 mojarra.jsfcljs 函数如下:

    jQuery(function(){
      mojarra.jsfcljs = function jsfcljs(f, pvp, t) {
        mojarra.apf(f, pvp);
        var ft = f.target;
        if (t) {
          f.target = t;
        }
    
        // trigger the submit event manually.
        jQuery(jq(f.id)).trigger('submit');
    
        f.submit();
        f.target = ft;
        mojarra.dpf(f);
      };
    };
    

    【讨论】:

    • oldjsfcljs 需要一个“var”,否则会污染全局范围。
    • 您的原始代码已损坏,因为您显然不了解 JS。它应该是:oldjsfcljs.apply(this, [f, pvp, t]); 或者 oldjsfcljs.apply(this, arguments);,就像我的代码一样。 JS 中的function.apply() 调用只有 2 个参数:this 对象和带有参数的类似列表的对象。
    • 您对 (arguments) 或 [f,pvp,t] 是正确的,但这并不能解决问题,问题是应该先调用 mojarra.apf(f, pvp)我触发了提交事件,apf 会将键/值数组 pvp 添加为表单中的隐藏字段,这就是它起作用的原因。
    猜你喜欢
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 2019-01-31
    • 2013-04-09
    • 2015-07-25
    • 2017-06-25
    • 2012-02-21
    相关资源
    最近更新 更多