« Chat Review | Main | Computing HTML on... »

20050414 Thursday April 14, 2005

Dynamic JavaScript

In one of my recent blogs I talked about using JavaScript in your page to do client-side textfield input masking. The JavaScript in that example was completely static - the JavaScript code itself is entered into the page (or a separate JavaScript file) and is not affected by anything happening on the server.

But what if you want to modify your JavaScript to use data from some computation you've performed in your Java code on the server? That's essentially what somebody asked on the forum the other day:

How can my JavaScript reference a field in my Java page bean?

One way to do this would be to use a InputHidden component. In your Java code, you can set the value of the InputHidden, and then you can reference this value from JavaScript. Specifically, if you drop an InputHidden on your page, such that its id is hiddenField1, then your JSP can look like this:

  ...
  <h:inputHidden binding="#{Page1.hiddenField1}" id="hiddenField1"/>
  <script>
     document.write("Message = " + document.getElementById("form1:hiddenField1").value);
  </script>
  ...
Obviously, in your Java code on the server you'd do something like this:
   ...
   hiddenField1.setValue("Hello World");
   ...
If you now run you'll see "Message: Hello World" in the page.

However, there's an even simpler way, using the Output Text component. Normally, if you set the value of an Output Text component to Hello <b>World<b> then the component will display exactly that value to the user. But the Output Text has an "Escape" property which is normally set to true. This is what is ensuring that the < in the text is properly escaped to the html entity for the less than sign, &lt;. You can however turn off the Escape property, and pass through HTML directly to your page!! If you do that, your output text will display the rendered HTML instead: "Hello World".

Thus, we can create the JavaScript code itself on the server and send it to the page by just binding an output text to a property which returns javascript, and turning off escape. Or better yet, keep the JavaScript mostly in the JSP and reference the data within the script string using one or more value binding expressions. To do this, first create a property in your Page, such as foo, which returns the data you want to insert into your JavaScript:

    public String getFoo() {
       return "Hello World";
    }
Now drop an Output Text, set it to the following value, and then turn off its Escape property:
<script>document.write("Message: #{Page1.foo}");</script>

More on this shortly.

(2005-04-14 08:57:26.0) Permalink Comments [4]

Comments:

So, You mean to say if I want to set the JSP variable to jsp component then I need to do something like this document.getElementById("form1:hiddenField1").value=<%=myJspVaraible%> is that right?

Posted by Sudhakar Chavali on July 11, 2005 at 04:57 AM PDT #

No, that's not what I meant. First of all, you cannot use the old-style JSP syntax (<% %>) in Creator, you must use the XML format of JSP. However, what I meant above is that all you need to do is drop a Hidden Input component on your page, and then in your Java code (such as in the beforeRenderResponse, or in Creator 2, "prerender"), call something like inputHidden1.setValue(yourOwnCodeHere());. Now JavaScript in the page can reference this server-side computed value by simply referencing it as shown in the JavaScript above.

Posted by 192.18.101.5 on July 11, 2005 at 09:47 AM PDT #

wertyui

Posted by 213.229.144.2 on September 29, 2005 at 07:49 AM PDT #

So what about something like this? I need to dynamically assign a value to a javascript array like this: <ui:script binding="#{appStartSaa.script3}" id="script3"> var repList = new Array(#{RepListBuilder.repList}) </ui:script> But this gets rendered in the browser as: <script id="script3" type="text/javascript"> var repList = new Array(#{RepListBuilder.repList}) </script> Is there a way to do this?

Posted by David Piersol-Freedman on May 04, 2006 at 06:01 PM PDT #

Post a Comment:

Comments are closed for this entry.