<br><br><div class="gmail_quote">2009/5/11 Jim Driscoll <span dir="ltr">&lt;<a href="mailto:Jim.Driscoll@sun.com">Jim.Driscoll@sun.com</a>&gt;</span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On 5/11/09 9:30 AM, David Geary wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
2009/5/11 Ryan Lubke &lt;<a href="mailto:Ryan.Lubke@sun.com" target="_blank">Ryan.Lubke@sun.com</a> &lt;mailto:<a href="mailto:Ryan.Lubke@sun.com" target="_blank">Ryan.Lubke@sun.com</a>&gt;&gt;<div><div></div><div class="h5">
<br>
<br>
    On 5/11/09 7:40 AM, David Geary wrote:<br>
<br>
        I have a login composite component that looks like this:<br>
<br>
        &lt;composite:interface&gt;...&lt;/composite:interface&gt;<br>
        ...<br>
        &lt;composite:implementation&gt;<br>
        &lt;script type=&quot;text/javascript&quot;&gt;<br>
                        function checkForm(form) {<br>
                          var name = form[&#39;#{cc.clientId}:name&#39;].value;<br>
                          var pwd = form[&#39;#{cc.clientId}:password&#39;].value;<br>
<br>
                          if (name == &quot;&quot; || pwd == &quot;&quot;) {<br>
                            alert(&quot;Please enter name and password.&quot;);<br>
                            return false;<br>
                          }<br>
                          return true;<br>
                        }<br>
        &lt;/script&gt;<br>
          ...<br>
        &lt;/composite:implementation&gt;<br>
<br>
        I have components with &quot;name&quot; and &quot;password&quot; component ids in a<br>
        form in the ... part of the implementation. That works fine<br>
<br>
        However, if I pull the JS out into its own file, and do this:<br>
<br>
        &lt;composite:interface&gt;...&lt;/composite:interface&gt;<br>
        ...<br>
        &lt;composite:implementation&gt;<br>
        &lt;h:outputScript library=&quot;components/login&quot; name=&quot;login.js&quot;/&gt;<br>
          ...<br>
        &lt;/composite:implementation&gt;<br>
<br>
        h:outputScript puts the JS in the page, but the JS no longer<br>
        works because the expression cc.clientId evaluates to an empty<br>
        string.<br>
<br>
        That&#39;s a bug, is it not?<br>
<br>
    No, I don&#39;t believe it is.  The javascript file will be served in a<br>
    separate request.  There is no way to determine the<br>
    component at that time.<br>
<br>
<br>
That&#39;s what I figured, but that&#39;s not going to be obvious to the average<br>
developer. This is a pretty serious violation of the principle of least<br>
astonishment, and JSF has enough of those violations, IMO.<br>
<br>
If there&#39;s no way to make it work, it should be documented, preferably<br>
in the pdl (or is it vdl now?) docs that h:outputScript will not work<br>
when the corresponding JS references a composite component.<br>
<br>
</div></div></blockquote>
<br>
I agree that we should document how to do this:  Which is why I wrote a demo that does this (basic-ezcomp/spinner-final) - and blogged about it <a href="http://weblogs.java.net/blog/driscoll/archive/2008/11/jsf_20_writinghtml" target="_blank">http://weblogs.java.net/blog/driscoll/archive/2008/11/jsf_20_writing.html</a><br>

<br>
The problem is not solvable the way that you think it is:  I struggled with this too, until Ryan walked me through it.  The problem is one of the web, not one of the JSF, exactly.<br>
<br>
So, look at it this way:  The JavaScript file is served ONCE, from ONE known address.  This is good - it allows us to cache the javascript file.  This is bad - because we do the # variable substitution *before* we serve the file, we can&#39;t do #{cc} substitutions in it, that file could (and will) be shared across views - and even across different websurfing sessions, after all, that&#39;s the whole point of the resource mechanism...  Efficient use of caching for resources.<br>

<br>
So, how to address this?  One way is in the demo - just set the cc.clientId as a context, and use that context in the function calls.<br>
In a different demo (ajax-switchlist) I save that context into state, and use that in each call.  Either way works, and both require about four lines of (javascript) code.<br>
<br>
If you make it so that we make those substitutions into the javascript file, then you also need to output that javascript file with a view unique name  And that&#39;s probably a bad idea for most uses, since that shoots caching in the head.  We could add a &quot;perview&quot; attribute to each resource, I guess, but since the workaround is so easy, once you know it, and the cost is the loss of caching, I&#39;d argue this isn&#39;t a good idea.<br>

<br>
I urge you to run through the demos I wrote (basic-ajax, basic-ezcomp, basic-ajax-edittext, ajax-switchlist)  - they&#39;re all small, and in each of them, I try to tackle one small problem and solve it.  In many of them, I ran into problems just like this, and worked through them. They&#39;re not documented (except in blogs), but they are all small pieces of code.</blockquote>
<div><br>Okay, I&#39;ll do that. Thanks for the insights--I hadn&#39;t stopped to think about caching.<br><br><br>david<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br><font color="#888888">
<br>
Jim<br>
</font></blockquote></div><br>