Zach’s ugly mug (his face) Zach Leatherman

JavaScript Frameworks and JSF

July 10, 2007

Warning

This article is old and may contain information that is outdated, irrelevant, or—dare I say it—no longer accurate. Read with care!

You’re programming a new web application using JSF, maybe with Facelets, maybe without. Which client-side JavaScript framework is going to work with it’s unstandardized method of assigning ID attributes to it’s elements? Here is an example of a JSF file:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html>
<body>
<f:view>
<h:form id="myForm">
<h:inputText id="myText"/>
</h:form>
</f:view>
</body>
</html>

or maybe the same thing using Facelets:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<body>
<f:view>
<form jsfc="h:form" id="myForm">
<input type="text" jsfc="h:inputText" id="myText"/>
</form>
</f:view>
</body>
</html>

These will both output the following result:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<form id="myForm">
<input type="text" id="myForm:myText"/>
</form>
</body>
</html>

Notice how the resulting text field has an ID attribute with the parent id prepended on. Now the real question is, how do we select this result node using the various JavaScript frameworks that are available to us?

Works, but we don’t care: Raw JavaScript or any GetById Function

Obviously using document.getElementById( 'myForm:myText' ); will function correctly. As will any framework that has a similar “GetById” function (YAHOO.util.Dom.get, or $ in Prototype, etc) What is more interesting to us is the behavior using the various CSS selector packages included with each JavaScript library.

Does not work: DomQuery in Ext 1.1 Beta 2

Ext.query( '#myForm:myText' );
Ext.query( '#myForm\:myText' );

These two tests will throw the error Ext.DomQuery.pseudos[name] is not a function, which obviously means that myText is not a pseudo class like :first or :last.

Ext.query( '#myForm\\:myText' );

Throws the error: Error parsing selector, parsing failed at "\:myText"

Works: jQuery 1.1.3

jQuery( '#myForm\\:myText' );

As of version 1.1.3 (the latest of this writing), they have added support for the colon in ID selection when escaped with a double backslash. Versions older than 1.1.3 will not function properly. This is not yet in the documentation but can be viewed in the Escape selectors section of a blog post.

Does not Work: Prototype 1.5.1.1

$$( '#myForm:myText' );
$$( '#myForm\:myText' );

Returns the form instead of the input element and treats myText as a pseudo class.

$$( '#myForm\\:myText' );

Interprets as XPATH selectors (\\ means anywhere in the document), using myText as a pseudo selector now, so it returns ALL nodes in the document.

Does not Work: Dojo query 0.9.0 Beta

dojo.query( '#myForm:myText' );
dojo.query( '#myForm\:myText' );
dojo.query( '#myForm\\:myText' );

It’s becoming mind numbingly obvious that if the framework doesn’t specifically say that you can escape selectors, it’s not going to let you do so. In the first two tests, Dojo performs the same as Prototype. In the double backslash test however, Dojo returns no result nodes.

Does not Work: Mootools 1.11

$$( '#myForm:myText' );
$$( '#myForm\:myText' );
$$( '#myForm\\:myText' );

All throw the error The expression is not a legal expression." code: "51.

There you have it folks. jQuery is the JavaScript library of choice for the discerning JSF applications developer. Kudos to you if you’re already using it.


Zach Leatherman IndieWeb Avatar for https://zachleat.com/is a builder for the web at IndieWeb Avatar for https://fontawesome.com/Font Awesome and the creator/maintainer of IndieWeb Avatar for https://www.11ty.devEleventy (11ty), an award-winning open source site generator. At one point he became entirely too fixated on web fonts. He has given 84 talks in nine different countries at events like Beyond Tellerrand, Smashing Conference, Jamstack Conf, CSSConf, and The White House. Formerly part of CloudCannon, Netlify, Filament Group, NEJS CONF, and NebraskaJS. Learn more about Zach »

6 Comments
  1. digitarald Disqus

    11 Jul 2007
    I don't see the reason to use $$ for querying one Element with his ID when there is $ to get an Element by ID.
  2. kangax Disqus

    11 Jul 2007
    Zach,$$( *[id="myForm:Foo"] ) works just fine in Prototypesome tests can be found at http://yura.thinkweb2.com/s...(results are printed into firebug console)I understand it looks more like a hack but at least it's possible :)Cheers,Juriy
  3. Tom Disqus

    12 Jul 2007
    $$("*[id='myForm:myName']") works in Prototype.
  4. John Resig Disqus

    12 Jul 2007
    Glad to hear that the character escaping is of use to you guys - it was oft-requested, so I put some effort into getting it in the latest release; I didn't realize just how important it could be!
  5. Giuseppe Disqus

    26 Apr 2009
    Through this article I could write a library of components for jsf based on jQuery. Thank you very much
  6. Ariel Disqus

    19 Jan 2010
    Thx...exactly what I needed.
Shamelessly plug your related post

These are webmentions via the IndieWeb and webmention.io.

Sharing on social media?

This is what will show up when you share this post on Social Media:

How did you do this? I automated my Open Graph images. (Peer behind the curtain at the test page)