admin管理员组文章数量:1291089
I'm executing the following jQuery function on <p:dataTable>
filter (whose id is id
) that allows users to enter only digits in the filter ponent.
$(document).ready(function() {
$("#form\\:dataTable\\:id\\:filter").keydown(function(event) {
//Allow: tab, escape, and enter
if(event.keyCode===9||event.keyCode===27||event.keyCode===13||
//Allow: Ctrl+A, Ctrl+C
(event.keyCode===65&&event.ctrlKey===true)||(event.keyCode===67&&event.ctrlKey===true)||
//Allow: home, end, left, right
(event.keyCode>=35&&event.keyCode<=39)){
//let it happen, don't do anything
event.preventCapture();
return;
}//backspace, delete
else if(event.keyCode===46||event.keyCode===8)
{
return;
}
else{//Ensure that it is a number and stop the keypress
if (event.shiftKey||(event.keyCode<48||event.keyCode>57)&&(event.keyCode< 96||event.keyCode>105)){
//event.preventDefault();
event.preventCapture();
}
}
});
});
This function is placed under context/resources/default/js/digit_only_textfield.js
. Therefore, it can be used on XHTML pages like,
<h:outputScript library="default" name="js/digit_only_textfield.js"/>
The XHTML page looks like the following.
<h:outputScript library="default" name="js/digit_only_textfield.js"/>
<h:form id="form" prependId="true">
<!--PrimeFaces extension <pe:blockUI>-->
<p:remoteCommand name="updateTable" update="dataTable"/>
<p:panel id="panel">
<h:panelGrid id="panelGrid" columns="3" cellpadding="5">
<!--Some UIInput ponents-->
<p:mandButton id="btnSubmit"
update="panel"
onstart="PF('blockUIWidget').block();"
onplete="if(!args.validationFailed) {updateTable();}PF('blockUIWidget').unblock();"
actionListener="#{bean.insert}"
value="Save"/>
</h:panelGrid>
</p:panel>
<p:dataTable id="dataTable"
var="row"
value="#{bean}"
filterEvent="keydown"
...
... >
...
...
<p:dataTable>
<h:form>
This jQuery works fine for the filter whose id is is
but when this <p:dataTable>
is updated by pressing the given <p:mandButton>
, it stops functioning.
How to make this function work after <p:dataTable>
is updated by AJAX?
A new problem domain introduced:
This question and corresponding replies on the PrimeFaces Community Forum still do not lead to a workaround/solution to the following problem domain.
if a wrong key is hit (i.e a non-digit key, except backspace, delete etc) then, the data table is updated unnecessarily that causes some costly queries to be fired upon the database which is pletely unnecessary and the data table must be prevented from being updated.
I'm executing the following jQuery function on <p:dataTable>
filter (whose id is id
) that allows users to enter only digits in the filter ponent.
$(document).ready(function() {
$("#form\\:dataTable\\:id\\:filter").keydown(function(event) {
//Allow: tab, escape, and enter
if(event.keyCode===9||event.keyCode===27||event.keyCode===13||
//Allow: Ctrl+A, Ctrl+C
(event.keyCode===65&&event.ctrlKey===true)||(event.keyCode===67&&event.ctrlKey===true)||
//Allow: home, end, left, right
(event.keyCode>=35&&event.keyCode<=39)){
//let it happen, don't do anything
event.preventCapture();
return;
}//backspace, delete
else if(event.keyCode===46||event.keyCode===8)
{
return;
}
else{//Ensure that it is a number and stop the keypress
if (event.shiftKey||(event.keyCode<48||event.keyCode>57)&&(event.keyCode< 96||event.keyCode>105)){
//event.preventDefault();
event.preventCapture();
}
}
});
});
This function is placed under context/resources/default/js/digit_only_textfield.js
. Therefore, it can be used on XHTML pages like,
<h:outputScript library="default" name="js/digit_only_textfield.js"/>
The XHTML page looks like the following.
<h:outputScript library="default" name="js/digit_only_textfield.js"/>
<h:form id="form" prependId="true">
<!--PrimeFaces extension <pe:blockUI>-->
<p:remoteCommand name="updateTable" update="dataTable"/>
<p:panel id="panel">
<h:panelGrid id="panelGrid" columns="3" cellpadding="5">
<!--Some UIInput ponents-->
<p:mandButton id="btnSubmit"
update="panel"
onstart="PF('blockUIWidget').block();"
onplete="if(!args.validationFailed) {updateTable();}PF('blockUIWidget').unblock();"
actionListener="#{bean.insert}"
value="Save"/>
</h:panelGrid>
</p:panel>
<p:dataTable id="dataTable"
var="row"
value="#{bean}"
filterEvent="keydown"
...
... >
...
...
<p:dataTable>
<h:form>
This jQuery works fine for the filter whose id is is
but when this <p:dataTable>
is updated by pressing the given <p:mandButton>
, it stops functioning.
How to make this function work after <p:dataTable>
is updated by AJAX?
A new problem domain introduced:
This question and corresponding replies on the PrimeFaces Community Forum still do not lead to a workaround/solution to the following problem domain.
Share Improve this question edited Mar 11, 2015 at 12:02 BalusC 1.1m376 gold badges3.6k silver badges3.6k bronze badges asked Nov 26, 2013 at 21:46 TinyTiny 27.9k112 gold badges351 silver badges607 bronze badges 6if a wrong key is hit (i.e a non-digit key, except backspace, delete etc) then, the data table is updated unnecessarily that causes some costly queries to be fired upon the database which is pletely unnecessary and the data table must be prevented from being updated.
-
Have you tried running the jQuery
keydown
function again after the table is updated? If the table is rendered from scratch by PrimeFaces upon update, then the jQuery on event trigger would be erased. – patstuart Commented Nov 26, 2013 at 22:12 -
It is just a filter event in PrimeFaces data table - an attribute of
<p:dataTable>
,filterEvent="keydown"
. – Tiny Commented Nov 26, 2013 at 22:16 - I don't understand the bounty and the apparent new problem. – BalusC Commented Dec 9, 2013 at 0:51
- I could have asked a separate question but mostly it would have been the same scenario except the text in the block quote in the question. – Tiny Commented Dec 9, 2013 at 9:32
- Isn't that already the whole intent of your custom jQuery function? Or didn't that part work? – BalusC Commented Dec 9, 2013 at 16:46
1 Answer
Reset to default 9 +100The flow is as follows:
- Browser retrieves HTML output.
- Browser populates HTML DOM tree based on HTML markup.
- When finished, browser triggers HTML DOM
ready
event. - jQuery's
$(document).ready()
function handlers are all invoked. - Yours finds an element in DOM by ID and attaches a
keydown
listener to it. - During user interaction, an ajax request is fired and the HTML DOM tree is updated with new HTML elements delivered by the ajax response.
- Among others, exactly that element having the
keydown
listener is removed from HTML DOM tree and replaced by a fresh new element without anykeydown
listener. The documentready
event is not fired during ajax requests. Your ready handler is never re-invoked. Thekeydown
listener is never re-attached. To the enduser, it then indeed seemingly "stops functioning".
The solution on this particular case should now be obvious: explicitly re-attach the keydown
listener on plete of ajax call. Most straightforward would be to extract the job of attaching the keydown
listener into a reusable function and fire it as follows:
function applyKeydownOnTableFilter() {
// ...
}
$(document).ready(applyKeydownOnTableFilter);
So that you can just do a:
<p:mandButton ... onplete="applyKeydownOnTableFilter()" />
But this is quite tedious to repeat for every single ajax mand/listener and not very maintenance friendly. Better is to approach it differently: use jQuery's $.on()
instead. Replace
$(document).ready(function() {
$("#form\\:dataTable\\:id\\:filter").keydown(function(event) {
// ...
});
});
by
$(document).on("keydown", "#form\\:dataTable\\:id\\:filter", function(event) {
// ...
});
This way the keydown
listener isn't actually attached to the element of interest. Instead, thanks to the event bubbling feature of JavaScript, the keydown event will ultimately reach the $(document)
— which is always present and usually not changed during JSF ajax requests. Once reached, the $(document).on()
is triggered, which will then determine the source of the event and check it if matches the given selector and if so, then invoke the function. This all without the need to attach the keydown
listener to the physical element and thus not sensitive to whether the element is removed/replaced in the HTML DOM tree.
See also:
- JSF/PrimeFaces ajax updates breaks jQuery event listener function bindings
By the way, do you also see how much similarities there are between HTML DOM tree and JSF ponent tree?
本文标签: JavaScriptjQuery event listeners do not work after JSF component is updated via AjaxStack Overflow
版权声明:本文标题:JavaScriptjQuery event listeners do not work after JSF component is updated via Ajax - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741505234a2382281.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论