By default, JSF generates unusable IDs, which are incompatible with the CSS part of web standards
Can someone who is an active JSF (or Primefaces) user explain why by default this happens why nobody is doing anything about it:
<p:commandLink id="baz" update=":foo:boop" value="Example" />
Which generates markup that cannot be used in JavaScript or CSS without hacks and should generally be considered invalid:
<a href="javascript:void(0);" id=":foo:bar:baz">Example</a>
The id=":bar:baz:foo"
attribute here contains colons, which aren't a valid character for this attribute, at least from CSS perspective.
While the attribute may be valid according to spec, it fails to work with real-world JavaScript and CSS implementations.
In short, default id
attribute generation in JSF is unusable for front-end development.
Solution 1:
The :
is been chosen because that's the only sensible separator character for which can be guaranteed that the enduser won't accidently use it in JSF component IDs (which is been validated) and that it's possible to use it in CSS selectors by escaping it with \
.
Note that the HTML4 spec says that the colon is a valid value in id
and name
attribute. So your complaint that it isn't compatible with "web standards" goes nowhere.
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
The only problem is thus that the :
is a special character in CSS selectors which needs to be escaped. JS has at its own no problems with colons. The document.getElementById("foo:bar")
works perfectly fine. The only possible problem is in jQuery because it uses CSS selector syntax.
If you really need to, then you can always change the default separator character :
by setting the javax.faces.SEPARATOR_CHAR
context param to e.g. -
or _
as below. You only need to guarantee that you don't use that character anywhere in JSF component IDs yourself (it's not been validated!).
<context-param>
<param-name>javax.faces.SEPARATOR_CHAR</param-name>
<param-value>-</param-value>
</context-param>
The _
has by the way the additional disadvantage that it occurs in JSF autogenerated IDs like j_id1
, thus you should also ensure that all NamingContainer
components throughout your JSF pages have a fixed ID instead of an autogenerated one. Otherwise JSF will have problems finding naming container children.
I would only not recommend it. It's in long term confusing and brittle. To think about it again, unique elements in the average JSF webapp are by itself usually already not inside forms or tables. They generally just represent the main layout aspects. I'd say, it's otherwise a bad design in general HTML/CSS perspective. Just select them by reusable CSS class names instead of IDs. If you really need to, you can always wrap it in a plain HTML <div>
or <span>
whose ID won't be prepended by JSF.
See also:
- What are valid values for the id attribute in HTML?
- Is it possible to change the element id separator in JSF?
- How to select JSF components using jQuery?
- How to use JSF generated HTML element ID with colon ":" in CSS selectors?
- Integrate JavaScript in JSF composite component, the clean way