tapestry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Tapestry > Ajax Components
Date Tue, 17 Aug 2010 22:04:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1810/9/8/_/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/Ajax+Components">Ajax
Components</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~hlship">Howard
M. Lewis Ship</a>
    </h4>
        <br/>
                         <h4>Changes (1)</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" >  } <br>{code}  <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
<br>h3. What&#39;s that weird number in the middle of the client ids after a Zone
is updated? <br> <br>You might start with markup in your template for a component
such as a TextField: <br> <br>{code} <br>  &lt;t:textfield t:id=&quot;firstName&quot;/&gt;
<br>{code} <br> <br>When the component initially renders as part of a full
page render, you get a sensible <br>bit of markup: <br> <br>{code} <br>
 &lt;input id=&quot;firstName&quot; name=&quot;firstName&quot; type=&quot;text&quot;&gt;
<br>{code} <br> <br>But when the form is inside a Zone and rendered as part
of a zone update, the ids get weird: <br> <br>{code} <br>   &lt;input
id=&quot;firstName_12a820cc40e&quot; name=&quot;firstName&quot; type=&quot;text&quot;&gt;
<br>{code} <br> <br>What&#39;s happening here is that Tapestry is working
to prevent unwanted id clashes as part of the page update.  In an HTML document, each {{id}}
is <br>expected to be unique; most JavaScript is keyed off of the {{id}} field, for
instance. <br> <br>In a full page render, components don&#39;t just use their
component id ({{t:id}}) as their client id; instead they use the {{JavaScriptSupport}} environmental
to allocate a unique id. When there&#39;s no loops or conflicts, the client id matches
the component id. <br> <br>When the component is inside a loop, a suffix is appended:
 {{firstName}}, {{firstName_0}}, {{firstName_1}}, etc. <br> <br>When the component
is rendered as part of an Ajax partial page update, the rules are different. Since Tapestry
doesn&#39;t know what content has been <br>rendered onto the page previously, it
can&#39;t use is normal tricks to ensure that ids are unique. <br> <br>Instead,
Tapestry creates a random-ish unique id suffix, such as &quot;12a820cc40e&quot; in
the example; this suffix is appended to all allocated ids to ensure that they do not conflict
with previously rendered ids. <br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="AjaxComponents-AjaxComponents"></a>Ajax Components</h2>

<h3><a name="AjaxComponents-DoIhavetospecifyboth%7B%7Bid%7D%7Dand%7B%7Bt%3Aid%7D%7DforZonecomponents%3F"></a>Do
I have to specify both <tt>id</tt> and <tt>t:id</tt> for Zone components?</h3>

<p>The examples for the Zone component (in the Component Reference) consistently specify
both <tt>id</tt> and <tt>t:id</tt> and this is probably a good idea.</p>

<p>Generally speaking, if you don't specify the client-side id (the <tt>id</tt>
attribute), it will be the same as the Tapestry component id (<tt>t:id</tt>).</p>

<p>However, there are any number of exceptions to this rule. The Zone may be rendering
inside a Loop (in which case, each rendering will have a unique client side id). The Zone
may be rendering as part of a partial page render, in which case, a random unique id is inserted
into the id. There are other examples where Tapestry component ids in nested components may
also clash.</p>

<p>The point is, to be sure, specify the exact client id.  This will be the value for
the <tt>zone</tt> parameter of the triggering component (such as a Form, PageLink,
ActionLink, etc.).</p>

<h3><a name="AjaxComponents-HowdoupdatethecontentofaZonefromaneventhandlermethod%3F"></a>How
do update the content of a Zone from an event handler method?</h3>

<p>When a client-side link or form triggers an update, the return value from the event
handler method is used to construct a partial page response; this partial page response includes
markup content that is used to update the Zone's client-side <tt>&lt;div&gt;</tt>
element.</p>

<p>Where does that content come from?  You inject it into your page.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
&lt;t:zone id=<span class="code-quote">"search"</span> t:id=<span class="code-quote">"searchZone"</span>&gt;
  &lt;t:form t:id=<span class="code-quote">"searchForm"</span> zone=<span
class="code-quote">"searchZone"</span>&gt;
    &lt;t:textfield t:id=<span class="code-quote">"query"</span> size=<span
class="code-quote">"20"</span>/&gt;
    &lt;input type=<span class="code-quote">"submit"</span> value=<span
class="code-quote">"Search"</span>/&gt;
  &lt;/t:form&gt;
&lt;/t:zone&gt;

&lt;t:block id=<span class="code-quote">"searchResults"</span>&gt;
  &lt;ul&gt;
    &lt;li t:type=<span class="code-quote">"loop"</span> source=<span class="code-quote">"searchHits"</span>
value=<span class="code-quote">"searchHit"</span>&gt;${searchHit}&lt;/li&gt;
  &lt;/ul&gt;
&lt;/t:block&gt;
</pre>
</div></div>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
  @Inject
  <span class="code-keyword">private</span> Block searchResults;

  <span class="code-object">Object</span> onSuccessFromSearchForm()
  {
    searchHits = searchService.performSearch(query);

    <span class="code-keyword">return</span> searchResults;
  }
</pre>
</div></div> 

<p>So, when the search form is submitted, the resulting search hits are collected. 
In the same request, the searchResults block is rendered, package, and sent to the client.
 The form inside the client-side Zone <tt>&lt;div&gt;</tt> is replaced
with the list of hits.</p>


<h3><a name="AjaxComponents-HowtoIupdatemultiplezonesinasingleeventhandler%3F"></a>How
to I update multiple zones in a single event handler?</h3>

<p>To do this, you must know, on the server, the client ids of each Zone.</p>

<p>Instead of returning a Block or a Component, return a multi-zone update:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
  @Inject
  <span class="code-keyword">private</span> Block searchResults;

  @Inject
  <span class="code-keyword">private</span> Block statusBlock;

  <span class="code-object">Object</span> onSuccessFromSearchForm()
  {
    searchHits = searchService.performSearch(query);

    message = <span class="code-object">String</span>.format(<span class="code-quote">"Found
%,d matching documents"</span>, searchHits.size());

    <span class="code-keyword">return</span> <span class="code-keyword">new</span>
MultiZoneUpdate(<span class="code-quote">"results"</span>, searchResults).add(<span
class="code-quote">"status"</span>, statusBlock);
  }
</pre>
</div></div> 

<h3><a name="AjaxComponents-What%27sthatweirdnumberinthemiddleoftheclientidsafteraZoneisupdated%3F"></a>What's
that weird number in the middle of the client ids after a Zone is updated?</h3>

<p>You might start with markup in your template for a component such as a TextField:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
  &lt;t:textfield t:id=<span class="code-quote">"firstName"</span>/&gt;
</pre>
</div></div>

<p>When the component initially renders as part of a full page render, you get a sensible<br/>
bit of markup:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
  &lt;input id=<span class="code-quote">"firstName"</span> name=<span class="code-quote">"firstName"</span>
type=<span class="code-quote">"text"</span>&gt;
</pre>
</div></div>

<p>But when the form is inside a Zone and rendered as part of a zone update, the ids
get weird:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   &lt;input id=<span class="code-quote">"firstName_12a820cc40e"</span> name=<span
class="code-quote">"firstName"</span> type=<span class="code-quote">"text"</span>&gt;
</pre>
</div></div>

<p>What's happening here is that Tapestry is working to prevent unwanted id clashes
as part of the page update.  In an HTML document, each <tt>id</tt> is<br/>
expected to be unique; most JavaScript is keyed off of the <tt>id</tt> field,
for instance.</p>

<p>In a full page render, components don't just use their component id (<tt>t:id</tt>)
as their client id; instead they use the <tt>JavaScriptSupport</tt> environmental
to allocate a unique id. When there's no loops or conflicts, the client id matches the component
id.</p>

<p>When the component is inside a loop, a suffix is appended:  <tt>firstName</tt>,
<tt>firstName_0</tt>, <tt>firstName_1</tt>, etc.</p>

<p>When the component is rendered as part of an Ajax partial page update, the rules
are different. Since Tapestry doesn't know what content has been<br/>
rendered onto the page previously, it can't use is normal tricks to ensure that ids are unique.</p>

<p>Instead, Tapestry creates a random-ish unique id suffix, such as "12a820cc40e" in
the example; this suffix is appended to all allocated ids to ensure that they do not conflict
with previously rendered ids.</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/Ajax+Components">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=23334985&revisedVersion=5&originalVersion=4">View
Changes</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message