jQuery Selector API meets JSF

PrimeFaces 3.3 development has begun fast and furious! Starting with the new partial submit feature, we are glad to introduce another extension feature to Ajax Framework called PrimeFaces Selector API in short PFS.

PFS integrates jQuery Selector API with JSF component referencing model, so for partial update and process, referencing JSF components can be done using jQuery Selector API instead of regular JSF model which is based on UIComponent.findComponent.

So how does it work? Syntax is @(selector), here are a couple of examples;

Update all forms

update="@(form)"

Update first form

update="@(form:first)"

Update all components that has “mystyle” style class

update="@(.mystyle)"

Update and process all inputs

update="@(:input)" process="@(:input)"

Update all datatables

update="@(.ui-datatable)"

Process input components inside panel and update panel

process="@(.ui-panel :input)" update="@(.ui-panel)"

Process input components but not select components

process="@(:input:not(select)))"

Process input components that are disabled

process="@(:input:disabled)"

Sky is the limit with this feature, see the jQuery Selector API docs for more information.

Please note that PFS is an additional feature, backward compatible and can be used with regular referencing, so following is also possible;

update="compId :form:compId @(:input)"

In summary, PFS provides an alternative, flexible, grouping based approach to reference components to partially process and update. There is less CPU server load compared to regular referencing because JSF component tree is not traversed on server side to find a component and figure out the client id as PFS is implemented on client side by looking at dom tree. Another advantage is avoiding naming container limitations, just remember the times you’ve faced with cannot find component exception since the component you are looking for is in a different naming container like a form or a datatable. PFS can help you out in tricky situations by following jQuery’s “write less do more” style.

Always Bet On Prime!

This entry was posted in Uncategorized. Bookmark the permalink.

20 thoughts on “jQuery Selector API meets JSF

  1. That’s great! Finally someone is moving JSF a bit into the right direction, the direction where the real WEB is.

  2. impressive! what a nice feature! Very cool to make a webapp much more faster with easy partial updates and processing

  3. Hello Cagatay,

    Are you sure DOM traversing is faster than JSF one? :-) Great feature, without doubt. Just one note. As I already said in the forum, jQuery “each” function and array’s “push” are slower than native calls. jQuery developers know that. I have prepared a small test page for you with a simple selector and the code from core.js:

    http://jsfiddle.net/nb89R/8/

    Alternative I rewritten this code with native calls to show the difference. My Firefox shows:

    Native Loop : 28 ms
    jQuery Each : 37 ms

    IE8 shows:

    Native Loop : 249 ms
    jQuery Each : 281 ms

    In huge pages the difference is even ca. 1 sek.! Maybe you can consider this fact and keep this in mind for future development. Many, many thanks.

    • Interesting post, Oleg! And I think it’s great that you are willing to test/confirm new features/enhancements and inform us of your test results and provide working test case, so we can see with our own eyes, too. :)

  4. In a complex forms, it was the biggest hurdle for me to correctly specify what to process and what to update. Partial form submit combined with this new feature is exactly what was missing from the JSF specification. Great work!

  5. I’m getting crazy. I’ve replaced jQuery’s .attr(‘id’) by native .getAttribute(‘id’) in for-loop (deleted first $ around components[i]) and now I have in Firefox:

    Native Loop : 4 ms
    jQuery Each : 40 ms

    and in IE8:

    Native Loop : 14 ms
    jQuery Each : 274 ms

    Look this page please: http://jsfiddle.net/nb89R/10/
    Perfomance benefit in IE8 (with choosen selector) is 260 ms. Cool?

    • Oleg,

      What exactly are you trying to measure here? Of course native JS loops are faster than jQuery selectors and each calls, but for a real comparison, you should try to write something like $(“.menu > ul li.selected”) as a native JS loop to find out why jQuery selectors were created for in the first place.

      By the way, your tests are not really executed as separate units, because they don’t have the same starting situation. E.g. clear the list of ids[] in between your timed pieces of code and the difference will already be a whole lot less.

      • Peter. The problem is not a selector. Sure, select something in DOM is better and easier with jQuery. The problem is iteration on the selected result. JQuery each loop vs. native one. Also $(…) in loop is overhead (created a lot of objects). If you would a real-time game developer, you would see differences. On the other hand, nobody develops games with JSF :-)

        Clearing ids[] doesn’t have much impact. 5-6 ms.

  6. Concerns about performance over convenience?
    Get the page working as simply as possible and optimise later.
    Yes JQuery will never perform as well as well crafted explicit JavaScript however developers don’t get paid for how long their code takes to complete do they?

    Frankly if a page is so large that it takes an age to update it even partially then you need to: split it up or reduce its footprint and/or seriously look at what you should be updating as opposed to what you are.

    This latest development to Primefaces is yet another step up in developer convenience which sets Primefaces apart from all of its Open Source and many of its Enterprise competitors.

  7. The most benefit of using update attribute is to decide what should be rerendered on the page (less network traffic, for example), but when using PFS do we get the same benefit?

    I’m asking this because I did not get when you said “It works faster than regular referencing because JSF component tree is not traversed to find a component as PFS is implemented on client side”.

    • Result is same with both approaches, regular JSF referencing first calls findComponent on component tree to find the component instance to update/process and then gets the clientIds, finally sends them to the client when rendering the ajax call. PFS on the other hand does this on the client side, client id resolution is done by running the selector on client side. Network traffic is same. Idea is finding the clientIds on client side by looking at dom tree not on server side via component tree traversal.

  8. Smiling and shaking my head at same time in awe/amazement/disbelief, since PrimeFaces continues to bring such great features to any/all JSF/PrimeFaces/jQuery/web developers. I’m not much of a jQuery developer (right now), since PrimeFaces is doing all (or so much) of that…for me! :)

    But I think it’s great that PrimeFaces caters to and uses jQuery as well, and this is great since so many have complained about the Cannot find component error and did not know how to resolve it, and continue to post new topics instead of searching the forum. Hopefully, PrimeFaces users/developers will learn to read PrimeFaces blog, so they will learn of this new feature, use it, and minimize the new topics related to ‘cannot find component’. :)

  9. Howard, “cannot find component” will not be present now. That’s right. The thing will be quietly. When no component(s) found (e.g. wrong selector), nothing happens, no errors, nothing :-) You don’t know then if you have a selector issue or something else is wrong. Ok. The main advantage of this feature is not preventation of “cannot find component”. The main advantage is speed. I was skeptic first to this feature, but now I found use cases where the new feature can rock. If you have @(#myId) selector, jQuery uses a native call document.getElementById() behind the scene. This is a very fast call. Much faster than on JSF (Java) side with search exp. for findComponent()! You can really optimize you app with Id selectors (Firebug can help here to figure out them). The second use case where selectors are faster is if you have a lot of components with rendered=”true/false”. JSF component tree is very big in this case and findComponent() is expensive. On the client side only a visible part of component tree is rendered (current rendered comp.). DOM is smaller than JSF component tree. That means, selectors work faster. Great feature.

    • Oleg, interesting post/response, and I thank you. I’m going to have to review my JSF/PrimeFaces web app and see where I can add this. For now, I’m having no issue with findComponent(), as I’ve eliminated that, but I did have issues with BlockUI identifying some UIComponents on certain of my pages (not all pages though), and the last time I looked at this blog post, and said to myself, maybe this PrimeFaces Selector can help me use BlockUI more often throughout app, successfully, but then I thought BlockUI executes prior to AJAX response. I wonder if jQuery/PrimeFaces selector can help BlockUI identify any/all UIComponents on xhtml page.

  10. Thank you – this will make it a lot simpler and more controlled to update components :)

  11. I think this is the biggest strategy advance since I use PF. Awsome work PF team. This combined with the hooks will provide no excuses not to use PF at all. What could you arge against it? Amazing component library, great flexibility and with JSF2 (a specification) behind… Any other thing in the wish list?