How to select JSF components using jQuery?
jquery, jsf, jsf-2, primefaces
Solution
You should realize that jQuery works with the HTML DOM tree in the client side. jQuery doesn't work directly on JSF components as you've written in the JSF source code, but jQuery works directly with the HTML DOM tree which is generated by those JSF components. You need to open the page in webbrowser and rightclick and then View Source. You'll see that JSF prepends the ID of the generated HTML input elements with the IDs of all parent `NamingContainer` components (such as `<h:form>`, `<h:dataTable>`, etc) with `:` as default separator character. So for example
<h:form id="foo">
<p:selectManyCheckbox id="bar" />
...
will end up in generated HTML as
<form id="foo" name="foo">
<input type="checkbox" id="foo:bar" name="foo:bar" />
...
You need to select elements by exactly that ID instead. The `:` is however a special character in CSS identifiers representing a pseudo selector. To select an element with a `:` in the ID using CSS selectors in jQuery, you need to either escape it by backslash or to use the `[id=...]` attribute selector or just use the old `getElementById()`:
var $element1 = $("#foo\\:bar");
// or
var $element2 = $("[id='foo:bar']");
// or
var $element3 = $(document.getElementById("foo:bar"));
If you see an autogenerated `j_idXXX` part in the ID where `XXX` represents an incremental number, then you must give the particular component a fixed ID, because the incremental number is dynamic and is subject to changes depending on component's physical position in the tree.
As an alternative, you can also just use a class name:
<x:someInputComponent styleClass="someClassName" />
which ends up in HTML as
<input type="..." class="someClassName" />
so that you can get it as
var $elements = $(".someClassName");
This allows for better abstraction and reusability. Surely those kind of elements are not unique. Only the main layout elements like header, menu, content and footer are really unique, but they are in turn usually not in a `NamingContainer` already.
As again another alternative, you could just pass the HTML DOM element itself into the function:
<x:someComponent onclick="someFunction(this)" />
function someFunction(element) {
var $element = $(element);
// ...
}
See also:
- How can I know the id of a JSF component so I can use in Javascript
- How to use JSF generated HTML element ID with colon ":" in CSS selectors?
- By default, JSF generates unusable IDs, which are incompatible with the CSS part of web standards
- Integrate JavaScript in JSF composite component, the clean way
Problem
I am trying to implement jQuery with PrimeFaces and JSF components, but it's not working properly. When I tried to do the same with HTML tags it;s working properly. Here is the code with HTML tags which works properly with jQuery: ``` <input type="checkbox" id="check2"></input> <h:outputText value="Check the box, if your permanent address is as same as current address."></h:outputText> <h:message for="checkbox" style="color:red" /> ``` with ``` $("#check2").change(function() { if ($("#check2").is(":checked")) { $("#p2").hide(); } else { $("#p2").show(); } }); ``` Here is the code with PrimeFaces/JSF which doesn't work properly with jQuery: ``` <p:selectManyCheckbox > <f:selectItem itemLabel="1" value="one" id="rad" ></f:selectItem> </p:selectManyCheckbox> ``` with ``` $("#rad").change(function() { if ($("#rad:checked").val() == "one") { $("#p2").hide(); } else { $("#p2").show(); } }); ```