3

I'm using com.sun.faces version 2.1.18. I'm displaying a list of questions and for some questions (based on the database ID) I want to insert some dynamic Javascripts.

According to the h:outputScript tag specification the name attribute is of type: javax.el.ValueExpression (must evaluate to java.lang.String).

However, this code is working for me:

<ui:repeat value="#{js.questionScripts[question.id]}" var="script">
  <h:outputScript name="myScript.js" library="js" target="head"/>
</ui:repeat>

But this code isn't:

<ui:repeat value="#{js.questionScripts[question.id]}" var="script">
  <h:outputScript name="#{script}" library="js" target="head"/>
</ui:repeat>

The #{question} comes from a surrounding <ui:repeat> iteration over a list of questions.

I added an output to see if #{script} was not empty, but it contained the correct resource name.

Any ideas on how to solve this or implement an alternative?

Jasper de Vries
  • 19,370
  • 6
  • 64
  • 102

1 Answers1

3

The <h:outputScript> has to be created during view build time in order to be recognized by JSF resource management. The <ui:repeat> runs during view render time and is therefore too late. You have to use <c:forEach>. I'm not sure how it failed for you, but it works fine for me, provided that #{js} is a request, session or application scoped bean whose questionScripts property is already prepared during its (post)construction and that #{question.id} is available during view build time.

<c:forEach items="#{js.questionScripts[question.id]}" var="script">
    <h:outputScript name="js/#{script}" target="head"/>
</c:forEach>

(note that you've to use items attribute instead of value attribute and also note that I fixed the seemingly improper usage of library attribute).

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you for explaining. The `#{question}` comes from a surrounding `` iteration over a list of questions, so `` will not work for me then. I'll have to come up with a workaround for my problem. – Jasper de Vries Feb 12 '13 at 16:17
  • 1
    Surely that wouldn't work. The `` runs before ``, so it would get `null` as `#{question}` (see also that "See also" link for an elaborate explanation). Either replace that outer `` by a `` as well, or add them programmatically via `UIViewRoot#addComponentResource()`. – BalusC Feb 12 '13 at 16:21
  • I was thinking of using `ResourceHandler#createResource()` in my bean to create URIs for the needed resources, but `UIViewRoot#addComponentResource()` also sounds interesting. – Jasper de Vries Feb 12 '13 at 16:45
  • `createResource()` isn't useful to you, it serves a different purpose and you'd still end up with exactly the same problem. – BalusC Feb 12 '13 at 16:47
  • I would just output the Javascript there using the URL generated by `createResource()`. Just tried it and it works after stripping `jndi:/server` from the URL... it is kind of ugly. I'll have a look at `UIViewRoot#addComponentResource()`. – Jasper de Vries Feb 12 '13 at 16:53
  • If you go that path, better use ``. Note that it doesn't support retargeting. – BalusC Feb 12 '13 at 18:39
  • That what I was using :) Thanks – Jasper de Vries Feb 13 '13 at 08:28