使用jQuery覆盖JSF组件方法

时间:2013-02-18 16:50:51

标签: jquery jsf jsf-2 primefaces

我想使用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或某事一样对状态进行评论。

4 个答案:

答案 0 :(得分:3)

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

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

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

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

答案 1 :(得分:1)

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

以下内容应该有效:

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

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

答案 2 :(得分:1)

只需使用widgetVar中的<p:inputText>属性,然后使用此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

答案 3 :(得分:0)

下班后我找到了正确的方法,我认为所有其他建议对于常规案例都很有用,但是由于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'});
        });
     }
});

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

但我的情况甚至比这更糟糕。我正在进行ajax更新以确定css值,即使它已执行页面加载,也会覆盖javascript函数值。执行顺序如下:

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

能够在决赛中执行功能。我将函数头更改为:function afterLoad()并通过以下方式在ajax更新程序按钮中调用它:<p:commandLink oncomplete="afterLoad()"/> AND BOOM IT WORKS !!!!