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