JSF Separation Character und prependId="false"

Es gibt eine unangenehme Inkompatibilität zwischen AngularJS und JSF, die seit Version AngularFaces 2.1.3 entschärft ist, aber nicht vollständig behoben werden konnte.

JSF verwendet in den HTML-Seiten IDs, die nicht den Vorstellungen von AngularJS von einer korrekten ID entsprechen. In JSF wird vor die Client-ID der Komponente die Client-ID sämtlicher Elternelemente im JSF-Baum gesetzt. Diese Bestandteile werden durch einen Doppelpunkt getrennt.

Das ist notwendig, um sämtliche IDs der gesamten HTML-Seite eindeutig zu machen. Besonders deutlich - und wichtig - wird das in DataTables. Wenn man vom Inhalt absieht, besteht jede Zeile aus identischem HTML-Code. Um die Elemente in den Zeilen unterscheiden zu können, wird die Zeilennummer in die IDs eingefügt, wie in diesem Beispiel aus dem PrimeFaces Showcase zu sehen ist:

AngularJS hat mit dem Doppelpunkt ein Problem. Im Prinzip kann man in der web.xml ein anderes Zeichen konfigurieren:

In einer Diskussion auf StackOverflow steht:

"ID uns NAME Token müssen mit einem Buchstaben beginnen und dürfen von Buchstaben, Ziffern, Minuszeichen, Unterstrichen, Doppelpunkten und Punkten gefolgt werden."
"Als einzige vernünftige Alternativen bleiben neben dem Doppelpunkt also das Minuszeichen, der Unterstrich und der Punkt. Der Punkt wiederum ist ein häufig verwendetes Sonderzeichen in CSS-Selektoren. Wer ihn verwendet, riskiert Probleme mit jQuery. Demnach haben wir nur die Wahl zwischen dem Minuszeichen und dem Unterstrich."

Der Unterstrich wiederum wird standardmäßig in JSF-IDs verwendet. Probleme sind daher vorprogrammiert.

AngularJS wiederum akzeptiert ohnehin nur Buchstaben, Ziffern und Unterstriche. In der Praxis sind mir bisher diese Probleme aufgefallen:

  • Das error-Objekt wird nicht in die form gefüllt, wenn die ID eines Eingabefeldes Doppelpunkte enthält. Das merkt man daran, dass ngMessages nicht funktioniert.
  • Man kann kein watch auf ein Fehler mit einer fehlerhaften ID setzen.

AngularFaces 2.1.0 bis 2.1.2 hatten ein großes Problem mit dieser Inkompatibilität. Seinerzeit hatte ich empfohlen, das Attribute prependId="false" zum Formular hinzuzufügen. Leider führt prependId="false" auch zu Problemen - man denke nur an Buttons und editierbare Felder in DataTables.

Seit AngularFaces 2.1.3 sind die meisten Probleme behoben. Die client-seitigen Komponenten <pui-label /gt; und <pui-message /gt; wurden neu geschrieben. Seitdem funktioniert die Client-seitige Bean Validation wieder mit normalen JSF-IDs. Sie sollten allerdings im Hinterkopf behalten, dass es Inkompatibilitäten mit AngularJS geben kann - beispielsweise beim setzen eines watch.

JSF separation character and prependId='false'

There's an annoying incompatibility between AngularJS and JSF. Since AngularFaces 2.1.3, the problem has been mostly, but not completely solved.

JSF gives the DOM elements ids that don't look like what AngularJS considers a valid id. JSF ids are composed of the parent id, plus a colon, plus the component's id. If the JSF view is more complex, there can be an arbitrary number of parent ids preprending the component id.

This is necessary to make ids unique in the entire application's namespace. For instance, data tables consist of several identical rows. To know one row from another the row index is added to the id, as you can see in this example taken from the PrimeFaces showcase:

The separator character of JSF can be configured in the web.xml.

According to StackOverflow,

"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 (".").
"Next to the colon, the only sensible choices are the hyphen, the underscore and the period. As the period is at its own also a special character in CSS selectors, it would have the same problem as the colon. So logically you don't have much other choice than the hyphen - and the underscore _."

The underscore, in turn, is used by JSF itself in ids, so chances are you run into problems, too.

Unfortunately, AngularJS doesn't accept any special character other than the underscore in ids and names of HTML fields. Until now, I've noticed two problems:

  • AngularJS doesn't populate the form's error object for fields with invalid names. You can't use ngMessages.
  • You can't set a watch on an input field with an illegal id.

AngularFaces 2.1.0-2.1.2 suffered badly from this incompatibility. At the time, I recommended to add the attribute prependId="false" to the form. Unfortunately, this doesn't work well, too - for instance, editable input fields and buttons are broken in data tables.

Since AngularFaces 2.1.3, the most offending problems have been solved by rewriting <pui-label /> and <pui-message />. Now you can use regular JSF ids. But keep in mind that you can run into problems if you set a watch on an JSF input field.

A página ainda não foi traduzido para o Português. Por favor, leia a tradução em Inglês. Pedimos desculpas por qualquer inconveniente.

JSF separation character and prependId='false'

There's an annoying incompatibility between AngularJS and JSF. Since AngularFaces 2.1.3, the problem has been mostly, but not completely solved.

JSF gives the DOM elements ids that don't look like what AngularJS considers a valid id. JSF ids are composed of the parent id, plus a colon, plus the component's id. If the JSF view is more complex, there can be an arbitrary number of parent ids preprending the component id.

This is necessary to make ids unique in the entire application's namespace. For instance, data tables consist of several identical rows. To know one row from another the row index is added to the id, as you can see in this example taken from the PrimeFaces showcase:

The separator character of JSF can be configured in the web.xml.

According to StackOverflow,

"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 (".").
"Next to the colon, the only sensible choices are the hyphen, the underscore and the period. As the period is at its own also a special character in CSS selectors, it would have the same problem as the colon. So logically you don't have much other choice than the hyphen - and the underscore _."

The underscore, in turn, is used by JSF itself in ids, so chances are you run into problems, too.

Unfortunately, AngularJS doesn't accept any special character other than the underscore in ids and names of HTML fields. Until now, I've noticed two problems:

  • AngularJS doesn't populate the form's error object for fields with invalid names. You can't use ngMessages.
  • You can't set a watch on an input field with an illegal id.

AngularFaces 2.1.0-2.1.2 suffered badly from this incompatibility. At the time, I recommended to add the attribute prependId="false" to the form. Unfortunately, this doesn't work well, too - for instance, editable input fields and buttons are broken in data tables.

Since AngularFaces 2.1.3, the most offending problems have been solved by rewriting <pui-label /> and <pui-message />. Now you can use regular JSF ids. But keep in mind that you can run into problems if you set a watch on an JSF input field.

JSF Separation Character und prependId="false"

Es gibt eine unangenehme Inkompatibilität zwischen AngularJS und JSF, die seit Version AngularFaces 2.1.3 entschärft ist, aber nicht vollständig behoben werden konnte.

JSF verwendet in den HTML-Seiten IDs, die nicht den Vorstellungen von AngularJS von einer korrekten ID entsprechen. In JSF wird vor die Client-ID der Komponente die Client-ID sämtlicher Elternelemente im JSF-Baum gesetzt. Diese Bestandteile werden durch einen Doppelpunkt getrennt.

Das ist notwendig, um sämtliche IDs der gesamten HTML-Seite eindeutig zu machen. Besonders deutlich - und wichtig - wird das in DataTables. Wenn man vom Inhalt absieht, besteht jede Zeile aus identischem HTML-Code. Um die Elemente in den Zeilen unterscheiden zu können, wird die Zeilennummer in die IDs eingefügt, wie in diesem Beispiel aus dem PrimeFaces Showcase zu sehen ist:

AngularJS hat mit dem Doppelpunkt ein Problem. Im Prinzip kann man in der web.xml ein anderes Zeichen konfigurieren:

In einer Diskussion auf StackOverflow steht:

"ID uns NAME Token müssen mit einem Buchstaben beginnen und dürfen von Buchstaben, Ziffern, Minuszeichen, Unterstrichen, Doppelpunkten und Punkten gefolgt werden."
"Als einzige vernünftige Alternativen bleiben neben dem Doppelpunkt also das Minuszeichen, der Unterstrich und der Punkt. Der Punkt wiederum ist ein häufig verwendetes Sonderzeichen in CSS-Selektoren. Wer ihn verwendet, riskiert Probleme mit jQuery. Demnach haben wir nur die Wahl zwischen dem Minuszeichen und dem Unterstrich."

Der Unterstrich wiederum wird standardmäßig in JSF-IDs verwendet. Probleme sind daher vorprogrammiert.

AngularJS wiederum akzeptiert ohnehin nur Buchstaben, Ziffern und Unterstriche. In der Praxis sind mir bisher diese Probleme aufgefallen:

  • Das error-Objekt wird nicht in die form gefüllt, wenn die ID eines Eingabefeldes Doppelpunkte enthält. Das merkt man daran, dass ngMessages nicht funktioniert.
  • Man kann kein watch auf ein Fehler mit einer fehlerhaften ID setzen.

AngularFaces 2.1.0 bis 2.1.2 hatten ein großes Problem mit dieser Inkompatibilität. Seinerzeit hatte ich empfohlen, das Attribute prependId="false" zum Formular hinzuzufügen. Leider führt prependId="false" auch zu Problemen - man denke nur an Buttons und editierbare Felder in DataTables.

Seit AngularFaces 2.1.3 sind die meisten Probleme behoben. Die client-seitigen Komponenten <pui-label /gt; und <pui-message /gt; wurden neu geschrieben. Seitdem funktioniert die Client-seitige Bean Validation wieder mit normalen JSF-IDs. Sie sollten allerdings im Hinterkopf behalten, dass es Inkompatibilitäten mit AngularJS geben kann - beispielsweise beim setzen eines watch.