You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Brian Farrar <br...@hotmail.com> on 2004/03/27 11:57:52 UTC

insert javascript dynamically

Hello, 

There have been other posts related to this subject but I still don't really understand how to go about doing it. The Script component documentation, from what I can understand, does not address this issue. Maybe this is covered in the book ? (I am waiting for my copy! yippie!)

I know how to use the Script component. What I don't know how to do is dynamically create a .script file. Actually, I want to do more that that...I want to add javascript content to a .script file after it has already been parsed. Just to be clear, this content doesn't have anything to do with symbols (at least I don't see how it could). I want to build a DHTML menu and need to consult the visit object at runtime to understand which menu widgets the user has the rights to see. Let's say I have this .script file:

(I'll leave the header stuff out).
<body>
function init{
    var menu = new Menu(arg1, arg2, ...);
    menu.formatCenter();
    menu.add3DEffects();

    var menuItemStyle = menuItemStyle(arg1, arg2,...);

    buildMenu(menu, menuItemStyle);
}
</body>
<initialization>
    init()
</initialization>

Now, I want to generate the javascript code for the buildMenu function "on the fly" and append it to the contents of what has already been read from the body tag. So I would like to create a Menu component and implement renderComponent() something like this:

protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
{
  if (!cycle.isRewinding())
  {
    Body body = Body.get(cycle);

   StringBuffer generatedScript = new StringBuffer();
   generatedScript.append("function buildMenu(menu, menuStyle){...}"):

    body.appendToBodyScript(generatedScript);

    _symbols = getInputSymbols();

    getParsedScript(cycle).execute(cycle, body, _symbols);
  }

  // Render the body of the Script;
  renderBody(writer, cycle);
}

Of course, this is not possibile, clearly, as Body has no such method, the script file has yet to be parsed (correct?) and goes against the entire architecture, but I hope it conveys what I want to do conceptually. So is there some elegant way to dynamically generate javascript and stir it in with the contents of a .script file?

Thanks, 

Brian


Re: insert javascript dynamically

Posted by Reinier Mostert <re...@clabo.co.za>.
Hi Brian,

I also got no joy from messages on the list concerning DHTML menus, but
in the end I got it right.  I'm using brainmenu www.brainjar.com, which
puts the definition into css markup, but the principle should be the
same.

The start of my PageWrapper.html looks like this:
<span jwcid="@Shell" title="ognl:page.pageTitle"/>
<LINK REL="stylesheet" TYPE="text/css" href="css/brainmenu.css"
TITLE="default">

<body jwcid="@Body">
<span jwcid="@Script" script="/scripts/brainmenu.noclick.js"/>
	<span jwcid="@Insert" value="ognl:menu" raw="true"/>
	
This link to the brainmenu javascript file, and inserts the menu
definition afterwards.  The definition is generated in my tapestry java
file like this:

public String getMenu() {
    String menu +=	"<a class=\"menuItem\" href=\"href\">name</a>";
    menu += "<a class=\"menuButton\" href=\"\" onclick=\"return
buttonClick(event, 'fileMenu');\" 
    menu += "onmouseover=\"buttonMouseover(event,
'fileMenu');\">name</a>"
	return menu;
}

To use the script, I modified it by placing the following around it:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script PUBLIC "-//Howard Lewis Ship//Tapestry Script 1.2//EN" 
"http://tapestry.sf.net/dtd/Script_1_2.dtd">
<script>
  <body>
<![CDATA[

here goes the normal script contents

]]>
  </body>
  <initialization>
  </initialization>
</script>

This works for me using brainjar, but YMMV.

Good luck
reinier

On Sat, 2004-03-27 at 12:57, Brian Farrar wrote:
> Hello, 
> 
> There have been other posts related to this subject but I still don't really understand how to go about doing it. The Script component documentation, from what I can understand, does not address this issue. Maybe this is covered in the book ? (I am waiting for my copy! yippie!)
> 
> I know how to use the Script component. What I don't know how to do is dynamically create a .script file. Actually, I want to do more that that...I want to add javascript content to a .script file after it has already been parsed. Just to be clear, this content doesn't have anything to do with symbols (at least I don't see how it could). I want to build a DHTML menu and need to consult the visit object at runtime to understand which menu widgets the user has the rights to see. Let's say I have this .script file:
> 
> (I'll leave the header stuff out).
> <body>
> function init{
>     var menu = new Menu(arg1, arg2, ...);
>     menu.formatCenter();
>     menu.add3DEffects();
> 
>     var menuItemStyle = menuItemStyle(arg1, arg2,...);
> 
>     buildMenu(menu, menuItemStyle);
> }
> </body>
> <initialization>
>     init()
> </initialization>
> 
> Now, I want to generate the javascript code for the buildMenu function "on the fly" and append it to the contents of what has already been read from the body tag. So I would like to create a Menu component and implement renderComponent() something like this:
> 
> protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
> {
>   if (!cycle.isRewinding())
>   {
>     Body body = Body.get(cycle);
> 
>    StringBuffer generatedScript = new StringBuffer();
>    generatedScript.append("function buildMenu(menu, menuStyle){...}"):
> 
>     body.appendToBodyScript(generatedScript);
> 
>     _symbols = getInputSymbols();
> 
>     getParsedScript(cycle).execute(cycle, body, _symbols);
>   }
> 
>   // Render the body of the Script;
>   renderBody(writer, cycle);
> }
> 
> Of course, this is not possibile, clearly, as Body has no such method, the script file has yet to be parsed (correct?) and goes against the entire architecture, but I hope it conveys what I want to do conceptually. So is there some elegant way to dynamically generate javascript and stir it in with the contents of a .script file?
> 
> Thanks, 
> 
> Brian
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: insert javascript dynamically

Posted by Harish Krishnaswamy <hk...@comcast.net>.
My point was not to pass the method as a parameter but rather pass only 
the data required by the method as a parameter. So you would have a 
static generateMenu method that takes a bunch of parameters and builds 
the menu from them. So you will have all the logic for determining the 
menu items in Java and simply use Javascript to render them.

For you to add a Javascript method to the body you don't need the script 
processor. The script processor is simply to parse the .script 
specification. Take a look at the LinkSubmit component.

Also take a look at the 
http://personales.ya.com/juriver/tapestry/pfcTapestrySrc.zip. Its got 
some menu examples that might suit your need.

-Harish

Brian Farrar wrote:

>Thanks for your reply.
>
>I want to generate the whole method/function because I don't know how the
>menu is going to be built until runtime. It is going to be different
>depending on which authorizations a user has. In the current application I
>am working on there are 22 possible versions of the menu. Perhaps the code
>example was misleading. Perhaps a clearer code example would be
>
>protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
>{
>  if (!cycle.isRewinding())
>  {
>    Body body = Body.get(cycle);
>
>   StringBuffer generatedScript
>        = MenuBuilder.generateMenu(getUserFromVisitObject());
>
>    body.appendToBodyScript(generatedScript);
>
>    _symbols = getInputSymbols();
>
>    getParsedScript(cycle).execute(cycle, body, _symbols);
>  }
>
>  // Render the body of the Script;
>  renderBody(writer, cycle);
>}
>
>You suggest that the generated script can be passed in as a parameter to the
>component and this idea certainly has merits. However, I think the problem
>is still the same, how do I inject the generated javascript into the content
>parsed from the .script file so it will be rendered together?
>
>As for using the IScriptProcessor methods on the Body class, I had also
>considered using them. Although it seems that the Script subsystem expects
>an ILocation in many places (representing the .script location?). If I am
>not mistaken, to get the script to render, IScript.execute() must be called
>and so in some way I would need an IScript implementation. Perhaps a new one
>could be written, so instead of ParsedScript (which takes an ILocation in
>the constructor) there could be a GeneratedScript class (or something like
>that).
>
>At any rate, I would like to leave any static javascript in the .script file
>and only generate the content which needs runtime information.
>
>Thoughts?
>
>-Brian
>
>
>----- Original Message ----- 
>From: "Harish Krishnaswamy" <hk...@comcast.net>
>To: "Tapestry users" <ta...@jakarta.apache.org>
>Sent: Saturday, March 27, 2004 4:41 PM
>Subject: Re: insert javascript dynamically
>
>
>  
>
>>I don't see why you want to generate the entire method. If you know
>>prior to the render cycle what menu items needs to be rendered, you can
>>simply pass them as paramaters to your script component. But if you do
>>want to generate the script, you can use the body.addBodyScript(script),
>>body.addInitializationScript(script) and body.addExternalScript(script)
>>methods.
>>
>>-Harish
>>
>>Brian Farrar wrote:
>>
>>    
>>
>>>Hello,
>>>
>>>There have been other posts related to this subject but I still don't
>>>      
>>>
>really understand how to go about doing it. The Script component
>documentation, from what I can understand, does not address this issue.
>Maybe this is covered in the book ? (I am waiting for my copy! yippie!)
>  
>
>>>I know how to use the Script component. What I don't know how to do is
>>>      
>>>
>dynamically create a .script file. Actually, I want to do more that that...I
>want to add javascript content to a .script file after it has already been
>parsed. Just to be clear, this content doesn't have anything to do with
>symbols (at least I don't see how it could). I want to build a DHTML menu
>and need to consult the visit object at runtime to understand which menu
>widgets the user has the rights to see. Let's say I have this .script file:
>  
>
>>>(I'll leave the header stuff out).
>>><body>
>>>function init{
>>>   var menu = new Menu(arg1, arg2, ...);
>>>   menu.formatCenter();
>>>   menu.add3DEffects();
>>>
>>>   var menuItemStyle = menuItemStyle(arg1, arg2,...);
>>>
>>>   buildMenu(menu, menuItemStyle);
>>>}
>>></body>
>>><initialization>
>>>   init()
>>></initialization>
>>>
>>>Now, I want to generate the javascript code for the buildMenu function
>>>      
>>>
>"on the fly" and append it to the contents of what has already been read
>from the body tag. So I would like to create a Menu component and implement
>renderComponent() something like this:
>  
>
>>>protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
>>>{
>>> if (!cycle.isRewinding())
>>> {
>>>   Body body = Body.get(cycle);
>>>
>>>  StringBuffer generatedScript = new StringBuffer();
>>>  generatedScript.append("function buildMenu(menu, menuStyle){...}"):
>>>
>>>   body.appendToBodyScript(generatedScript);
>>>
>>>   _symbols = getInputSymbols();
>>>
>>>   getParsedScript(cycle).execute(cycle, body, _symbols);
>>> }
>>>
>>> // Render the body of the Script;
>>> renderBody(writer, cycle);
>>>}
>>>
>>>Of course, this is not possibile, clearly, as Body has no such method,
>>>      
>>>
>the script file has yet to be parsed (correct?) and goes against the entire
>architecture, but I hope it conveys what I want to do conceptually. So is
>there some elegant way to dynamically generate javascript and stir it in
>with the contents of a .script file?
>  
>
>>>Thanks,
>>>
>>>Brian
>>>
>>>
>>>
>>>
>>>      
>>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>>For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>>
>>
>>    
>>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>
>  
>

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: insert javascript dynamically

Posted by Brian Farrar <br...@hotmail.com>.
Thanks for your reply.

I want to generate the whole method/function because I don't know how the
menu is going to be built until runtime. It is going to be different
depending on which authorizations a user has. In the current application I
am working on there are 22 possible versions of the menu. Perhaps the code
example was misleading. Perhaps a clearer code example would be

protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
{
  if (!cycle.isRewinding())
  {
    Body body = Body.get(cycle);

   StringBuffer generatedScript
        = MenuBuilder.generateMenu(getUserFromVisitObject());

    body.appendToBodyScript(generatedScript);

    _symbols = getInputSymbols();

    getParsedScript(cycle).execute(cycle, body, _symbols);
  }

  // Render the body of the Script;
  renderBody(writer, cycle);
}

You suggest that the generated script can be passed in as a parameter to the
component and this idea certainly has merits. However, I think the problem
is still the same, how do I inject the generated javascript into the content
parsed from the .script file so it will be rendered together?

As for using the IScriptProcessor methods on the Body class, I had also
considered using them. Although it seems that the Script subsystem expects
an ILocation in many places (representing the .script location?). If I am
not mistaken, to get the script to render, IScript.execute() must be called
and so in some way I would need an IScript implementation. Perhaps a new one
could be written, so instead of ParsedScript (which takes an ILocation in
the constructor) there could be a GeneratedScript class (or something like
that).

At any rate, I would like to leave any static javascript in the .script file
and only generate the content which needs runtime information.

Thoughts?

-Brian


----- Original Message ----- 
From: "Harish Krishnaswamy" <hk...@comcast.net>
To: "Tapestry users" <ta...@jakarta.apache.org>
Sent: Saturday, March 27, 2004 4:41 PM
Subject: Re: insert javascript dynamically


> I don't see why you want to generate the entire method. If you know
> prior to the render cycle what menu items needs to be rendered, you can
> simply pass them as paramaters to your script component. But if you do
> want to generate the script, you can use the body.addBodyScript(script),
> body.addInitializationScript(script) and body.addExternalScript(script)
> methods.
>
> -Harish
>
> Brian Farrar wrote:
>
> >Hello,
> >
> >There have been other posts related to this subject but I still don't
really understand how to go about doing it. The Script component
documentation, from what I can understand, does not address this issue.
Maybe this is covered in the book ? (I am waiting for my copy! yippie!)
> >
> >I know how to use the Script component. What I don't know how to do is
dynamically create a .script file. Actually, I want to do more that that...I
want to add javascript content to a .script file after it has already been
parsed. Just to be clear, this content doesn't have anything to do with
symbols (at least I don't see how it could). I want to build a DHTML menu
and need to consult the visit object at runtime to understand which menu
widgets the user has the rights to see. Let's say I have this .script file:
> >
> >(I'll leave the header stuff out).
> ><body>
> >function init{
> >    var menu = new Menu(arg1, arg2, ...);
> >    menu.formatCenter();
> >    menu.add3DEffects();
> >
> >    var menuItemStyle = menuItemStyle(arg1, arg2,...);
> >
> >    buildMenu(menu, menuItemStyle);
> >}
> ></body>
> ><initialization>
> >    init()
> ></initialization>
> >
> >Now, I want to generate the javascript code for the buildMenu function
"on the fly" and append it to the contents of what has already been read
from the body tag. So I would like to create a Menu component and implement
renderComponent() something like this:
> >
> >protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
> >{
> >  if (!cycle.isRewinding())
> >  {
> >    Body body = Body.get(cycle);
> >
> >   StringBuffer generatedScript = new StringBuffer();
> >   generatedScript.append("function buildMenu(menu, menuStyle){...}"):
> >
> >    body.appendToBodyScript(generatedScript);
> >
> >    _symbols = getInputSymbols();
> >
> >    getParsedScript(cycle).execute(cycle, body, _symbols);
> >  }
> >
> >  // Render the body of the Script;
> >  renderBody(writer, cycle);
> >}
> >
> >Of course, this is not possibile, clearly, as Body has no such method,
the script file has yet to be parsed (correct?) and goes against the entire
architecture, but I hope it conveys what I want to do conceptually. So is
there some elegant way to dynamically generate javascript and stir it in
with the contents of a .script file?
> >
> >Thanks,
> >
> >Brian
> >
> >
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: insert javascript dynamically

Posted by Harish Krishnaswamy <hk...@comcast.net>.
I don't see why you want to generate the entire method. If you know 
prior to the render cycle what menu items needs to be rendered, you can 
simply pass them as paramaters to your script component. But if you do 
want to generate the script, you can use the body.addBodyScript(script), 
body.addInitializationScript(script) and body.addExternalScript(script) 
methods.

-Harish

Brian Farrar wrote:

>Hello, 
>
>There have been other posts related to this subject but I still don't really understand how to go about doing it. The Script component documentation, from what I can understand, does not address this issue. Maybe this is covered in the book ? (I am waiting for my copy! yippie!)
>
>I know how to use the Script component. What I don't know how to do is dynamically create a .script file. Actually, I want to do more that that...I want to add javascript content to a .script file after it has already been parsed. Just to be clear, this content doesn't have anything to do with symbols (at least I don't see how it could). I want to build a DHTML menu and need to consult the visit object at runtime to understand which menu widgets the user has the rights to see. Let's say I have this .script file:
>
>(I'll leave the header stuff out).
><body>
>function init{
>    var menu = new Menu(arg1, arg2, ...);
>    menu.formatCenter();
>    menu.add3DEffects();
>
>    var menuItemStyle = menuItemStyle(arg1, arg2,...);
>
>    buildMenu(menu, menuItemStyle);
>}
></body>
><initialization>
>    init()
></initialization>
>
>Now, I want to generate the javascript code for the buildMenu function "on the fly" and append it to the contents of what has already been read from the body tag. So I would like to create a Menu component and implement renderComponent() something like this:
>
>protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
>{
>  if (!cycle.isRewinding())
>  {
>    Body body = Body.get(cycle);
>
>   StringBuffer generatedScript = new StringBuffer();
>   generatedScript.append("function buildMenu(menu, menuStyle){...}"):
>
>    body.appendToBodyScript(generatedScript);
>
>    _symbols = getInputSymbols();
>
>    getParsedScript(cycle).execute(cycle, body, _symbols);
>  }
>
>  // Render the body of the Script;
>  renderBody(writer, cycle);
>}
>
>Of course, this is not possibile, clearly, as Body has no such method, the script file has yet to be parsed (correct?) and goes against the entire architecture, but I hope it conveys what I want to do conceptually. So is there some elegant way to dynamically generate javascript and stir it in with the contents of a .script file?
>
>Thanks, 
>
>Brian
>
>
>  
>

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org