【问题标题】:Overriding JSF component methods with jQuery用 jQuery 覆盖 JSF 组件方法
【发布时间】:2013-02-18 16:50:50
【问题描述】:

我想使用 jQuery 覆盖 p:inputText (commentInput) 组件的 onblur()onfocus() 方法。但是我想我正在努力获取这个组件的固定 Html ID。到目前为止我试过了:

jQuery(document).ready(function() {
     $(document.getElementById("[#{p:component('commentInput')}]")).onblur(function() {
        $(this).css({'background-color':'#DFD8D1'});
     });
});

或者:

jQuery(document).ready(function() {
     $("[id='#{p:component('commentInput')}']").onblur(function() {
        $(this).css({'background-color':'#DFD8D1'});
         });
});

两者都给出相同的结果:Uncaught TypeError: Object [object Object] has no method 'onblur'

Xhtml代码类似这样:

<h:form id="dtForm">
<p:outputPanel id="dataTablePanel">
    <p:dataTable id="dataTable">
        <p:column id="column">
            <p:panel>
                <p:inputText id="commentInput">
                </p:inputText>
            </p:panel>
        </p:column>
    </p:dataTable>
</p:outputPanel>
</h:form>

我在使用 inputText 组件时遇到了另一个问题:

<p:inputText id="commentInput" onkeypress="if (event.keyCode == 13) {onchange(); return false;}" required="#{not empty statusBean.newComment}">
    <f:ajax event="change" listener="#{statusBean.test}" />
</p:inputText>

它以意想不到的方式触发事件;假设光标在 inputText 中并输入 sth。并单击页面中的其他位置,组件会触发 ajax 事件,而它不应该这样做。我认为这个组件不适合像在 Facebook 中那样获得对状态的评论。

【问题讨论】:

    标签: jquery jsf jsf-2 primefaces


    【解决方案1】:

    这里有两个问题。首先,正如 Anthony Grist 在他的回答中所说,定义模糊是由 blur() 而不是 onblur() 完成的。 JSF 中的 ID 包含 : 符号作为 id 分隔符,因此您需要转义那些 : 符号。 Primefaces 已经为此内置了函数,它还在开始时添加了# 符号以便在 jQuery 中使用它:

    jQuery(PrimeFaces.escapeClientId("#{p:component('commentInput')}")).blur(function () {
      // your code here...
    });
    

    另一方面,为什么要复杂化,p:inputTextonblur 属性。有了它,您可以定义要执行的 javascript 回调。它用作标准 HTML 属性:

    <p:inputText onblur="myFunction()"/>
    

    【讨论】:

    • 你的代码看起来是正确的,但没有给出任何错误。
    • 你能检查生成的 html,看看是否生成了 jQuery 选择器吗?用 Firebug 调试?也许 Primefaces 只是覆盖了你的行为 :) 我还添加了替代方法。
    • 我昨天尝试了你的第二个建议,设置 onblur 属性意味着在任何单击输入文本组件后触发 myFunction。在页面加载之前它不起作用。而且我使用了firebug,它似乎没有进入jQuery函数内部,因为您在这里编写的部分//您的代码我在此处更改并添加了css更改器代码,但调试器跳过了这一行并转到:});但它返回正确的 ID:dtForm:dataTable:commentInput
    【解决方案2】:

    用于绑定blur 事件处理程序的jQuery 函数只是.blur(),而不是.onblur()。此外,在您的第一个示例中,您混合了对 jQuery 函数的调用和对本机 JavaScript document.getElementById() 的调用。

    以下应该有效:

    $("##{p:component('commentInput')}")).blur(function() {
        $(this).css({'background-color':'#DFD8D1'});
    });
    

    第一个# 是jQuery 选择器的一部分,第二个是(我假设)JSF 代码的一部分,用于获取该元素的正确ID。我不能保证在服务器端不会出现解析问题(我没有使用 JSF 的经验),但我希望它能够工作。

    【讨论】:

    • 给出:未捕获的错误:语法错误,无法识别的表达式:不支持的伪:dataTable
    【解决方案3】:

    只需在您的&lt;p:inputText&gt; 中使用widgetVar 属性并使用此ID 调用您的组件:

    <p:inputText id="commentInput" widgetVar="txtCommentInput" ... >
    
    ...
    
    jQuery(document).ready(function() {
         txtCommentInput.blur(function() {
            $(this).css({'background-color':'#DFD8D1'});
         });
    });
    

    请注意,不要将idwidgetVar 属性设置为相同的值:http://forum.primefaces.org/viewtopic.php?f=3&t=18830#p59600

    【讨论】:

    • 给出:未捕获的 ReferenceError:未定义 txtCommentInput。我已经添加了 widgetVar 属性但不起作用。
    • @ÖmerFarukAlmalı 确保清除浏览器中的所有缓存并重试。
    • 即使是全新的浏览器也没有任何区别。
    【解决方案4】:

    几个小时后,我找到了正确的方法,我认为所有其他建议对常规情况很有用,但我的建议很特别,因为 DataTable 组件,它破坏了其他解决方案,所以我找到了一个更贪婪的解决方案:

    $(window).bind("load", function() {
        var rowSize = '#{bean.numOfRows}';
        for (var i=0;i &lt; rowSize;i++)
        {
            var rowIndex=i;
            var str = 'dataTableForm' + ':dataTable:' +  rowIndex + ':commentInput';
            var element = $(document.getElementById(str));
            element.blur(function () {
               $(this).css({'box-shadow': '0 0 5px #EB2F28'});
               $(this).css({'background-color':'#DFD8D1'});
            });
         }
    });
    

    函数的第一行决定了页面加载后的执行。然后我为dataTable 中的所有inputText 组件迭代相同的过程。 var str 具有每个 inputText 组件的固定 ID 的值,其余部分;只是 CSS。

    但我的情况比这更糟糕。我正在做一个 ajax 更新来确定 css 值,即使它执行了页面加载,它也会覆盖 javascript 函数值。执行顺序是这样的:

    --Page Load
    ----Function Executes
    ------Ajax Call
    

    能够在决赛中执行功能。我将函数标题更改为:function afterLoad(),并通过以下方式在 ajax 更新程序按钮中调用它:&lt;p:commandLink oncomplete="afterLoad()"/&gt; 并且 BOOM 它可以正常工作!!!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-07
      • 2013-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多