Igor Marakov wrote:
Hardcoded subview id does not work when I need to include components in the
loop. In the code piece I put on the original email I need to include
multiple screen section containers handled by the same tile layout. Tile
inclusion needs to be wrapped in subview. As number of components is not
known in advance I cannot hardwire subview Id.

Ok, I hadn't seen the <% for ... %> wrapped around the f:subview.

The TLD is correct: the JSF spec declares the "id" attribute of the f:subview component to be mandatory. As far as I know, id is optional for all other components.

OK, but nobody says that Id has to be *coded* and cannot be generated by
implementation. TLD also says that id will be generated if omitted. And it
does get generated properly. That's why I say that TLD needs to be
corrected.

In the JSF 1.1 spec:

Section 9.4.11, about the f:subview tag says:

<quote>
Must have an id attribute whose value is unique...
</quote>

MyFaces must comply with the spec; therefore the id attribute on f:subview must be marked "required". And that means the JSP page *must* provide some kind of value for that attribute. If you look at the Sun RI TLD, you'll see that it is also marked mandatory there. I don't know offhand the reason why id is mandatory for this tag, but presumably there *is* a reason.

Section 3.1.4, "Value Binding Expressions" says:
<quote>
For the standard component classes defined by this specification, all
attributes, and all properties other than id and parent, are value binding enabled.
</quote>

So unfortunately, "id" can't be a value binding without breaking JSF compliance. As it's required, the only other option is a literal string. So there's no possibility for it to be "generated by implementation" like id works for other components.

That doesn't mean that a t:subview couldn't be created which makes the id attribute optional (or you could create your own subview component for your application). However the standard f:subview tag can't be changed. Personally, though, I would want to find out *why* the spec says that id is mandatory for subview before accepting into tomahawk a component that bypasses that limitation.


Note that section 9.2.8 of that spec says:
<quote>
JSF component custom actions may not be nested inside a custom action that iterates over its body (such as JSTL’s <c:forEach>). Instead, you should use a Renderer that performs its own iteration (such as the Table renderer used by <h:dataTable>).
</quote>
In this context, "custom action" means a JSP tag.

So unfortunately your whole <% for ... %> approach is explicitly unsupported by JSF. I know for sure that if the size of your loop varies between two renderings of the same view then very bad things will happen to any JSF components with auto-assigned ids on that page.

The **JSF 1.2** spec does say that id attributes are permitted to include ${...} which is "to allow ${} expressions in the id attribute so that <c:forEach> can include faces components that incorporate the index into their id". That's effectively what you want, I believe. However that cannot be supported with JSP 1.1 as far as I know.



No component allows EL expressions for ids; if specified it *must* be a literal string.
This sounds rather 'kludgy' but spec is a spec I guess.

Basically it all boils down to lack of "include" tag and loop processing
facilities in JSF itself.


Tomahawk provides the t:dataList component. You might be able to use this as a replacement for your <% for ... %> code, as that component effectively does a for-loop. Currently, t:dataList isn't a NamingContainer as far as I know, though, so it won't replace that feature of your f:subview. If you really need NamingContainer behaviour, maybe you could use h:dataTable.

Or you could just create your own subview component for use in your app.

Otherwise you might have to move to the beta version of Sun's RI which implements JSF 1.2. Note, however, that this requires JSP 1.2 too; as fara as I know the only product which implements JSP 1.2 is Sun's "glassfish". JSP2.1 and JSF1.2 specs are not yet officially released, and it looks like quite a long while before tomcat/MyFaces will be implementing them.




Anyone out there know *why* the spec declares the id attribute of f:subview to be mandatory?


Regards,

Simon

Reply via email to