tapestry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Tapestry > JavaScript
Date Sun, 09 Oct 2011 11:14:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/12/_/styles/combined.css?spaceKey=TAPESTRY&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/TAPESTRY/JavaScript">JavaScript</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~bobharner">Bob
Harner</a>
    </h4>
        <div id="versionComment">
        <b>Comment:</b>
        Small tweaks &amp; corrections, clarified that javascript libraries are only combined
if part of a stack<br />
    </div>
        <br/>
                         <h4>Changes (12)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >Alternatively, you can use [JavaScriptSupport|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html]
(for Tapestry 5.2 or later) or [RenderSupport|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/RenderSupport.html]
(for Tapestry 5.0 and 5.1) to include a JavaScript library in your page or component. JavaScriptSupport
and RenderSupport are [environmental services|Environmental Services] that include a number
of methods that will be used by components, or by services that are called from components.
For example: <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >h3. The <span class="diff-changed-words"><span
class="diff-added-chars"style="background-color: #dfd;">{{</span>importJavaScriptLibrary<span
class="diff-added-chars"style="background-color: #dfd;">}}</span></span> method
<br></td></tr>
            <tr><td class="diff-unchanged" > <br>The {{importJavaScriptLibrary}}
method (or {{addScriptLink}} for Tapestry 5.0 and 5.1) adds a link to a JavaScript library.
A component can inject such a script and pass one or more of assets to this method: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >As with the annotation approach, adding
the same asset multiple times does _not_ create duplicate links. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >The <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">setupRender()</span>
<span class="diff-added-words"style="background-color: #dfd;">{{setupRender}}</span>
method (the name is specifically linked to a [render phase|Component Rendering]) is the correct
place to inform the JavaScriptSupport (or RenderSupport) service that the library is needed.
<br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >h3. The <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">addScript()</span>
<span class="diff-added-words"style="background-color: #dfd;">{{addScript}}</span>
method <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >The <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">addScript()</span>
<span class="diff-added-words"style="background-color: #dfd;">{{addScript}}</span>
method is used when you need to add some JavaScript code directly to the page. This will be
inserted at the _bottom of the document_, and will only be executed when the document has
finished loading on the client (i.e., from the window.onload event handler). <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code:java} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >In production mode, Tapestry automatically
_combines_ JavaScript libraries. A single request (for a _virtual asset_) will retrieve the
combined content of all referenced JavaScript library files. <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Note:
starting with Tapestry 5.2, JavaScript libraries are only combined if they are part of a JavaScript
Stack (see below). <br> <br></td></tr>
            <tr><td class="diff-unchanged" >This is a very useful feature, as
it reduces the number of requests needed to present a page to the user. It can be disabled,
however, by setting the SymbolConstants.COMBINE_SCRIPTS [configuration symbol|Configuration]
to false in your application&#39;s module class (normally AppModule.java). By default
it is enabled when in production mode and disabled otherwise. <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{deprecated:since=5.3} <br>
<br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-added-words"style="background-color:
#dfd;">In versions prior to 5.3,</span> Tapestry uses a modified version of the [Blackbird|http://www.gscottolson.com/blackbirdjs/]
JavaScript console. The Tapestry object includes three functions: debug, warn and error. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Each of these functions
take a message and an optional pattern; if the pattern is provided, the message is [interpolated|http://prototypejs.org/api/string/interpolate]
on the pattern. The final message is displayed in the Blackbird console, which will make itself
visible automatically. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The
constant [MarkupConstants.WAIT_FOR_PAGE|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/MarkupConstants.html]
contains this snippet. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The
constant [MarkupConstants.WAIT_FOR_PAGE|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/MarkupConstants.html]
contains the part of this snippet inside the quotes. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h1. The Standard Tapestry
Library <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>  @Environmental <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">
 private RenderSupport renderSupport; <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
 private JavaScriptSupport javaScriptSupport; <br></td></tr>
            <tr><td class="diff-unchanged" > <br>  void setupRender() <br>
 { <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">renderSupport.addScriptLink(dragDropLibrary);</span>
<span class="diff-added-words"style="background-color: #dfd;">javaScriptSupport.addScriptLink(dragDropLibrary);</span>
<br></td></tr>
            <tr><td class="diff-unchanged" >  } <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >A [JavaScriptStack|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptStack.html]
can be thought of as a generalization of Tapestry 5.1&#39;s ClientInfrastructure, which
exists now to define the &quot;core&quot; JavaScript stack. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">A</span>
JavaScript assets of a stack may (when enabled) be exposed to the client as a single URL (identifying
the stack by name). The individual assets are combined into a single virtual asset, which
is then streamed to the client. <br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <div class='navmenu' style='float:right; background:#eee; margin:3px; padding:3px'><table
class="tableview" width="100%">
            <tr><th style="padding: 3px 3px 3px 0px">Related Articles</th></tr>
                        <tr>
            <td>
                                 <span class="icon icon-page" title=Page>Page:</span>
                         <a href="/confluence/display/TAPESTRY/Ajax+and+Zones">Ajax
and Zones</a>
        
                                            </td>
        </tr>
                <tr>
            <td>
                                 <span class="icon icon-page" title=Page>Page:</span>
                         <a href="/confluence/display/TAPESTRY/JavaScript">JavaScript</a>
        
                                            </td>
        </tr>
                <tr>
            <td>
                                 <span class="icon icon-page" title=Page>Page:</span>
                         <a href="/confluence/display/TAPESTRY/Assets">Assets</a>
        
                                            </td>
        </tr>
                <tr>
            <td>
                                 <span class="icon icon-page" title=Page>Page:</span>
                         <a href="/confluence/display/TAPESTRY/JavaScript+FAQ">JavaScript
FAQ</a>
        
                                            </td>
        </tr>
                <tr>
            <td>
                                 <span class="icon icon-page" title=Page>Page:</span>
                         <a href="/confluence/display/TAPESTRY/Component+Cheat+Sheet">Component
Cheat Sheet</a>
        
                                            </td>
        </tr>
                <tr>
            <td>
                                 <span class="icon icon-page" title=Page>Page:</span>
                         <a href="/confluence/display/TAPESTRY/Ajax+Components+FAQ">Ajax
Components FAQ</a>
        
                                            </td>
        </tr>
            </table>
</div>

<p><b>JavaScript</b> is a first-class concept in Tapestry, and sophisticated
JavaScript support is provided right out of the box, including rich <a href="/confluence/display/TAPESTRY/Ajax+and+Zones"
title="Ajax and Zones">AJAX support</a>, download optimization, client-side logging,
and localization.</p>

<p>In production mode, by default, Tapestry will merge JavaScript libraries, add version
numbering, and set a far-future expires header to encourage aggressive browser caching. Starting
with version 5.3, Tapestry will also automatically minify (compress) JavaScript libraries
when in <a href="/confluence/display/TAPESTRY/Configuration#Configuration-ConfigurationConfigurationSymbolNames">production
mode</a></p>

<p>In addition, as will be described in detail later, Tapestry comes with the <a
href="http://www.prototypejs.org/" class="external-link" rel="nofollow">Prototype</a>
and <a href="http://script.aculo.us/" class="external-link" rel="nofollow">Scriptaculous</a>
libraries ... no extra download is required. Tapestry will automatically link into your pages
the prototype.js, scriptaculous.js, and effects.js libraries, as well as the Tapestry library,
tapestry.js.</p>

<h1><a name="JavaScript-AddingCustomJavaScript"></a>Adding Custom JavaScript</h1>

<p>When adding your own custom JavaScript or third-party libraries, just follow the
strategies below to take full advantage of Tapestry's JavaScript support mechanisms.</p>

<p>The recommended practice in Tapestry is to package up any significant amount of JavaScript
as a static JavaScript library, a .js file that can be downloaded to the client. Keep your
in-page JavaScript code to a minimum, just the few statements needed to initialize objects
and reference methods in the JavaScript libraries.</p>

<h2><a name="JavaScript-LinkingtoyourJavaScriptlibraries"></a>Linking to
your JavaScript libraries</h2>

<p>Tapestry provides several ways to add a link to JavaScript library within your page
or component. Although you can use direct <tt>&lt;script type="text/javascript"
src="xxx.js"&gt;&lt;/script&gt;</tt> approach, you ordinarily shouldn't.
Tapestry provides <em>much</em> better ways to do the same thing. Most users choose
the simplest, the @Import annotation approach.</p>

<h2><a name="JavaScript-Approach1%3A@Import"></a>Approach 1: @Import</h2>

<p>Use the @<a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Import.html"
class="external-link" rel="nofollow">Import</a> annotation (or  @<a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/IncludeJavaScriptLibrary.html"
class="external-link" rel="nofollow">IncludeJavaScriptLibrary</a> in Tapestry 5.0
and 5.1) to include links to JavaScript (and CSS) files in your page or component. Tapestry
ensures that each such file is only referenced once in your page.</p>

<table class="sectionMacro" border="0" cellpadding="5" cellspacing="0" width="100%"><tbody><tr>
<td class="confluenceTd" valign="top">
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>For Tapestry 5.2 and later</b></div><div
class="codeContent panelContent">
<pre class="code-java">
@Import(library={<span class="code-quote">"context:js/jquery.js"</span>,
		<span class="code-quote">"context:js/myeffects.js"</span>})
<span class="code-keyword">public</span> class MyComponent
{
 . . .
}
</pre>
</div></div></td>

<td class="confluenceTd" valign="top">
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>For Tapestry 5.0 and 5.1</b></div><div
class="codeContent panelContent">
<pre class="code-java">
@IncludeJavaScriptLibrary(value={<span class="code-quote">"context:js/jquery.js"</span>,
		<span class="code-quote">"context:js/myeffects.js"</span>})
<span class="code-keyword">public</span> class MyComponent
{
 . . .
}
</pre>
</div></div></td></tr></tbody></table>

<p>@Import may also be applied to individual methods, in which case the import operation
only occurs when the method is invoked.</p>

<p>Note: When specifying a file to import, you'll often use the <b>context:</b>
binding prefix to indicate that the file is stored in the web application context, and not
on the classpath. Relative paths will be on the classpath, relative to the Java class. See
<a href="/confluence/display/TAPESTRY/Component+Parameters" title="Component Parameters">Component
Parameters</a> for other binding prefix options.</p>

<p>Adding the same JavaScript library multiple times does <em>not</em> create
duplicate links. The subsequent ones are simply ignored. In this way, each component can add
the libraries it needs, without worrying about conflicts with other components.</p>

<h2><a name="JavaScript-Approach2%3AJavaScriptSupport"></a>Approach 2: JavaScriptSupport</h2>

<p>Alternatively, you can use <a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html"
class="external-link" rel="nofollow">JavaScriptSupport</a> (for Tapestry 5.2 or later)
or <a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/RenderSupport.html"
class="external-link" rel="nofollow">RenderSupport</a> (for Tapestry 5.0 and 5.1)
to include a JavaScript library in your page or component. JavaScriptSupport and RenderSupport
are <a href="/confluence/display/TAPESTRY/Environmental+Services" title="Environmental
Services">environmental services</a> that include a number of methods that will be
used by components, or by services that are called from components. For example:</p>

<h3><a name="JavaScript-The%7B%7BimportJavaScriptLibrary%7D%7Dmethod"></a>The
<tt>importJavaScriptLibrary</tt> method</h3>

<p>The <tt>importJavaScriptLibrary</tt> method (or <tt>addScriptLink</tt>
for Tapestry 5.0 and 5.1) adds a link to a JavaScript library. A component can inject such
a script and pass one or more of assets to this method:</p>

<table class="sectionMacro" border="0" cellpadding="5" cellspacing="0" width="100%"><tbody><tr>
<td class="confluenceTd" valign="top">
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Tapestry 5.2 and later</b></div><div
class="codeContent panelContent">
<pre class="code-java">
  @Inject @Path(<span class="code-quote">"${context:/js/myeffects.js"</span>)
  <span class="code-keyword">private</span> Asset myEffects;

  @Environmental
  <span class="code-keyword">private</span> JavaScriptSupport javaScriptSupport;

  void setupRender()
  {
    javaScriptSupport.importJavaScriptLibrary(myEffects);
  }
</pre>
</div></div></td>

<td class="confluenceTd" valign="top">
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Tapestry 5.1 and earlier</b></div><div
class="codeContent panelContent">
<pre class="code-java">
  @Inject @Path(<span class="code-quote">"${context:/js/myeffects.js"</span>)
  <span class="code-keyword">private</span> Asset myEffects;

  @Environmental
  <span class="code-keyword">private</span> RenderSupport renderSupport;

  void setupRender()
  {
    renderSupport.addScriptLink(myEffects);
  }
</pre>
</div></div></td></tr></tbody></table>

<p>Tapestry will ensure that the necessary &lt;link&gt; elements are added to
the <em>top</em> of the document (in the &lt;head&gt; element). With Tapestry
5.3 and later the new elements are inserted at the bottom of the &lt;head&gt; element;
in versions before 5.3 they appear at the top of the &lt;head&gt; element).</p>

<p>As with the annotation approach, adding the same asset multiple times does <em>not</em>
create duplicate links.</p>

<p>The <tt>setupRender</tt> method (the name is specifically linked to a
<a href="/confluence/display/TAPESTRY/Component+Rendering" title="Component Rendering">render
phase</a>) is the correct place to inform the JavaScriptSupport (or RenderSupport) service
that the library is needed.</p>

<h3><a name="JavaScript-The%7B%7BaddScript%7D%7Dmethod"></a>The <tt>addScript</tt>
method</h3>

<p>The <tt>addScript</tt> method is used when you need to add some JavaScript
code directly to the page. This will be inserted at the <em>bottom of the document</em>,
and will only be executed when the document has finished loading on the client (i.e., from
the window.onload event handler).</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
void addScript(<span class="code-object">String</span> format, <span class="code-object">Object</span>...
arguments);
</pre>
</div></div>

<p>When calling the method, the format string can include standard substitutions (such
as '%s') for arguments. This saves you the trouble of calling String.format() yourself. In
any case, the formatting JavaScript is added to the script block.</p>

<h3><a name="JavaScript-InjectingJavaScriptSupport"></a>Injecting JavaScriptSupport</h3>

<p>JavaScriptSupport (like RenderSupport before it) is an <em>environmental</em>
object, so you will normally inject it via the @<a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Environmental.html"
class="external-link" rel="nofollow">Environmental</a> annotation:</p>

<table class="sectionMacro" border="0" cellpadding="5" cellspacing="0" width="100%"><tbody><tr>
<td class="confluenceTd" valign="top">
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>For Tapestry 5.2 and later</b></div><div
class="codeContent panelContent">
<pre class="code-java">
  @Environmental
  <span class="code-keyword">private</span> JavaScriptSupport javaScriptSupport;
</pre>
</div></div></td>

<td class="confluenceTd" valign="top">
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>For Tapestry 5.0 and 5.1</b></div><div
class="codeContent panelContent">
<pre class="code-java">
  @Environmental
  <span class="code-keyword">private</span> RenderSupport renderSupport;
</pre>
</div></div></td></tr></tbody></table>

<p>The @Environmental annotation only works inside components, but occasionally a service
may want to inject JavaScriptSupport. Fortunately, a proxy of RenderSupport has been set up.
The upshot of this is that you may also:</p>

<table class="sectionMacro" border="0" cellpadding="5" cellspacing="0" width="100%"><tbody><tr>
<td class="confluenceTd" valign="top">
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>For Tapestry 5.2 and later</b></div><div
class="codeContent panelContent">
<pre class="code-java">
  @Inject
  <span class="code-keyword">private</span> JavaScriptSupport javaScriptSupport;
</pre>
</div></div></td>

<td class="confluenceTd" valign="top">
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>For Tapestry 5.0 and 5.1</b></div><div
class="codeContent panelContent">
<pre class="code-java">
  @Inject
  <span class="code-keyword">private</span> RenderSupport renderSupport;
</pre>
</div></div></td></tr></tbody></table>

<p>... or, in a service implementation constructor:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
  <span class="code-keyword">public</span> MyServiceImpl(RenderSupport support)
  {
    . . .
  }
</pre>
</div></div>

<p>Inside a component, you should use @Environmental, to highlight the fact that RenderSupport
(like most environmental objects) is only available during rendering, not during action requests.</p>

<h1><a name="JavaScript-CombiningJavaScriptlibraries"></a>Combining JavaScript
libraries</h1>



<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Added in
5.1.0.2</b><br /></td></tr></table></div>
<div style="border-right: 20px solid #D8E4F1;border-left: 20px solid #D8E4F1;"></div>
<p>In production mode, Tapestry automatically <em>combines</em> JavaScript
libraries. A single request (for a <em>virtual asset</em>) will retrieve the combined
content of all referenced JavaScript library files.</p>

<p>Note: starting with Tapestry 5.2, JavaScript libraries are only combined if they
are part of a JavaScript Stack (see below).</p>

<p>This is a very useful feature, as it reduces the number of requests needed to present
a page to the user. It can be disabled, however, by setting the SymbolConstants.COMBINE_SCRIPTS
<a href="/confluence/display/TAPESTRY/Configuration" title="Configuration">configuration
symbol</a> to false in your application's module class (normally AppModule.java). By
default it is enabled when in production mode and disabled otherwise.</p>

<p>As elsewhere, if the client browser supports gzip compression, the combined JavaScript
will be compressed.</p>

<h1><a name="JavaScript-MinifyingJavaScriptlibraries"></a>Minifying JavaScript
libraries</h1>



<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Added in
5.3</b><br /></td></tr></table></div>
<div style="border-right: 20px solid #D8E4F1;border-left: 20px solid #D8E4F1;"></div>
<p>In production mode, Tapestry automatically <em>minifies</em> (intelligently
compresses) JavaScript libraries (and CSS) when the application starts up. This can significantly
decrease the size of static content that the browser needs to download.</p>

<p>Minification is accomplished using the ResourceMinimizer service. By default a YUI
Compressor-based implementation is used, but this can be overridden.</p>

<p>Minification can be disabled by setting the SymbolConstants.MINIFICATION_ENABLED
<a href="/confluence/display/TAPESTRY/Configuration" title="Configuration">configuration
symbol</a> to false in your application's module class (usually AppModule.java). By
default it is enabled when in production mode and disabled otherwise.</p>

<h1><a name="JavaScript-ClientsideLogging"></a>Client-side Logging</h1>



<div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/forbidden.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Deprecated
since 5.3</b><br /></td></tr></table></div>
<div style="border-right: 20px solid #ffcccc;border-left: 20px solid #ffcccc;"></div>

<p>In versions prior to 5.3, Tapestry uses a modified version of the <a href="http://www.gscottolson.com/blackbirdjs/"
class="external-link" rel="nofollow">Blackbird</a> JavaScript console. The Tapestry
object includes three functions: debug, warn and error.</p>

<p>Each of these functions take a message and an optional pattern; if the pattern is
provided, the message is <a href="http://prototypejs.org/api/string/interpolate" class="external-link"
rel="nofollow">interpolated</a> on the pattern. The final message is displayed in
the Blackbird console, which will make itself visible automatically.</p>

<p>In production mode, debug messages will be filtered out (they will not be visible
until the user presses F2 to display the console, and then clicks the grayed out icon for
debug messages). In development mode, debug messages are not filtered out.</p>

<p>Example usage:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

 Tapestry.debug(<span class="code-quote">"Field id is #{id}, value is #{value}"</span>,
field);

 Tapestry.error(<span class="code-quote">"Server is not available."</span>);

</pre>
</div></div>

<h1><a name="JavaScript-HandlingSlowPageLoads"></a>Handling Slow Page Loads</h1>

<p>If your page loads slowly (typically, because of scripts loaded from external sites),
you may see a race condition where the user can click on a link before an event handler for
that link has been wired up.</p>

<p>The client-side function <tt>Tapestry.waitForPage()</tt> can be used
in an element's onclick handler to force a wait for the page to fully load. In this race condition,
the screen will dim and a message will appear advising the user to wait a moment; once the
page is fully loaded, this modal dialog will be removed.</p>

<p>The correct usage is:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
  &lt;a href=<span class="code-quote">"..."</span> onclick=<span class="code-quote">"javascript:Tapestry.waitForPage(event);"</span>&gt;
... &lt;/a&gt;
</pre>
</div></div>

<p>The constant <a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/MarkupConstants.html"
class="external-link" rel="nofollow">MarkupConstants.WAIT_FOR_PAGE</a> contains the
part of this snippet inside the quotes.</p>

<h1><a name="JavaScript-TheStandardTapestryLibrary"></a>The Standard Tapestry
Library</h1>

<p>Tapestry's client-side support, the standard Tapestry library, consists of <tt>tapestry.js</tt>,
which has dependencies on Prototype and on Scriptaculous Effects. tapestry.js, along with
its dependencies. The tapestry.js library is automatically added to the page when your code
adds any other JavaScript or JavaScript library.</p>

<h2><a name="JavaScript-TapestryNamespace"></a>Tapestry Namespace</h2>

<p>Tapestry defines a number of object and classes inside the Tapestry namespace.</p>

<p>It also adds a handful of methods to the Form class, and to Form elements. These
are mostly related to input validation and determining element visibility.</p>

<h2><a name="JavaScript-TheTapestryObject%24T%28%29"></a>The Tapestry Object
$T()</h2>



<div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/forbidden.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Deprecated
since 5.2 (no replacement)</b><br /></td></tr></table></div>
<div style="border-right: 20px solid #ffcccc;border-left: 20px solid #ffcccc;"></div>

<p>The standard library adds a new function, <tt>$T()</tt>. This function
is used much like Prototype's <tt>$()</tt>, except that instead of returning a
DOM object, it returns a hash (an initially empty JavaScript object) that is associated with
the DOM object. This hash is known as <em>the Tapestry object</em>.</p>

<p>You may pass in an object id (as a string) or an object reference. The Tapestry Object
is created on first invocation. Note: you'll see it as a property name _tapestry on the DOM
object (which may be useful when debugging).</p>

<p>When Tapestry adds information to a DOM object, it does so in the Tapestry object.
This helps avoid name conflicts, and groups all Tapestry-added properties into one place which
is much easier to debug.</p>

<p>For example, you might store a value for an element in one place:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
  $T(myid).fadeDuration = .5;
</pre>
</div></div>

<p>Then use it somewhere else:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
  <span class="code-keyword">new</span> Effect.Fade($(myId), { duration: $T(myid).fadeDuration
});
</pre>
</div></div>


<h1><a name="JavaScript-AjaxComponentsandMixins"></a>Ajax Components and
Mixins</h1>

<p>Tapestry provides easy-to-use support for <em>Ajax</em>, the technique
of using JavaScript to dynamically updating parts of a web page with content from the server
without redrawing the whole page. See <a href="/confluence/display/TAPESTRY/Ajax+and+Zones"
title="Ajax and Zones">Ajax and Zones</a> for details.</p>

<div class='navmenu' style='float:right; width:30%; background:#eee; margin:3px; padding:3px'><p><font
color="green"><b>Alternatives to Prototype</b></font><br/>
There are both immediate and long-term efforts underway to allow Tapestry to work better with
other JavaScript libraries, such as JQuery and ExtJS:</p>
<ul>
	<li><a href="http://wiki.apache.org/tapestry/Tapestry5HowToIntegrateJQuery" class="external-link"
rel="nofollow">Tapestry5HowToIntegrateJQuery</a> &#8211; Using JQuery <em>in
addition to</em> Prototype</li>
	<li><a href="http://tapestry.ioko.com/tapestry-jquery/" class="external-link" rel="nofollow">Tapestry-Jquery
module</a> &#8211; Using JQuery <em>in addition to</em> Prototype</li>
	<li><a href="https://github.com/got5/tapestry5-jquery" class="external-link" rel="nofollow">Tapestry5-Jquery
module</a> &#8211; Using JQuery <em>instead of</em> Prototype</li>
	<li><a href="https://issues.apache.org/jira/browse/TAP5-999" class="external-link"
rel="nofollow">TAP5-999</a> proposes an agnostic tapestry.js layer to allow switching
from Prototype to JQuery</li>
	<li><a href="https://issues.apache.org/jira/browse/TAP5-1364" class="external-link"
rel="nofollow">TAPS-1364</a> lists some starting points for ExtJS integration</li>
</ul>
</div>

<h1><a name="JavaScript-BuiltinLibraries"></a>Built-in Libraries</h1>

<h2><a name="JavaScript-PrototypeandScriptaculousVersions"></a>Prototype
and Scriptaculous Versions</h2>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Tapestry 5.2.6 </th>
<td class='confluenceTd'> Prototype 1.7 </td>
<td class='confluenceTd'> Scriptaculous 1.9</td>
</tr>
<tr>
<th class='confluenceTh'> Tapestry 5.2 </th>
<td class='confluenceTd'> Prototype 1.6.1 </td>
<td class='confluenceTd'> Scriptaculous 1.8.2</td>
</tr>
<tr>
<th class='confluenceTh'> Tapestry 5.1 </th>
<td class='confluenceTd'> Prototype 1.6.0.3 </td>
<td class='confluenceTd'> Scriptaculous 1.8.2</td>
</tr>
<tr>
<th class='confluenceTh'> Tapestry 5.0 </th>
<td class='confluenceTd'> Prototype 1.6.0 </td>
<td class='confluenceTd'> Scriptaculous 1.8.0</td>
</tr>
</tbody></table>
</div>


<p>Tapestry uses a modified version of the main Scriptaculous library, scriptaculous.js,
with the library's default <a href="http://wiki.script.aculo.us/scriptaculous/show/Usage"
class="external-link" rel="nofollow">autoloading</a> behavior turned off. This lets
Tapestry and Tapestry components control which Scriptaculus scripts are loaded, rather than
having <em>all</em> of them loaded unnecessarily.</p>

<p>Note that the Prototype, Scriptaculous main and effects libraries, and the standard
Tapestry library (which largely consists of support for form input validation) are included
automatically.</p>

<p>If you need access to other Scriptaculous libraries, you can provide them as follows:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

  @Inject @Path(<span class="code-quote">"${tapestry.scriptaculous}/dragdrop.js"</span>)
  <span class="code-keyword">private</span> Asset dragDropLibrary;

  @Environmental
  <span class="code-keyword">private</span> JavaScriptSupport javaScriptSupport;

  void setupRender()
  {
    javaScriptSupport.addScriptLink(dragDropLibrary);
  }

</pre>
</div></div>

<p>The Asset is injected, using the ${tapestry.scriptaculous} <a href="/confluence/display/TAPESTRY/Symbols"
title="Symbols">symbol</a> to reference the location of the Scriptaculous library.</p>

<p>Even though the dragdrop.js library is stored inside a JAR file, Tapestry ensures
that it can be accessed from the client web browser. A Tapestry URL within the virtual folder
"/assets" is created; the file will be given a version number (the application version number
if not specified more specifically) and will be sent to the browser with a far-future expires
header (to encourage the browser to cache the file aggressively).</p>

<h1><a name="JavaScript-JavaScriptStacks"></a>JavaScript Stacks</h1>


<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Added in
5.2</b><br /></td></tr></table></div>
<div style="border-right: 20px solid #D8E4F1;border-left: 20px solid #D8E4F1;"></div>

<p>Tapestry allows you to define groups of related JavaScript libraries and stylesheets
as "stacks". The built-in "core" stack is used to define the core JavaScript libraries needed
by Tapestry (currently, this includes Prototype and Scriptaculous, as well as Tapestry-specific
libraries). Other component libraries may define additional stacks for related sets of resources,
for example, to bundle together some portion of the ExtJS or YUI libraries.</p>

<p>A <a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptStack.html"
class="external-link" rel="nofollow">JavaScriptStack</a> can be thought of as a generalization
of Tapestry 5.1's ClientInfrastructure, which exists now to define the "core" JavaScript stack.</p>

<p>JavaScript assets of a stack may (when enabled) be exposed to the client as a single
URL (identifying the stack by name). The individual assets are combined into a single virtual
asset, which is then streamed to the client.</p>



    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/TAPESTRY/JavaScript">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=21792074&revisedVersion=32&originalVersion=31">View
Changes</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message