[CONF] Apache Tapestry Ajax Components FAQ

2014-01-18 Thread Bob Harner (Confluence)














  


Bob Harner edited the page:
 


Ajax Components FAQ   




 Comment: fixed language param of code macro 


...
Where does that content come from? You inject it into your page.



 Code Block








controls
true


linenumberslanguage
truexml


 




 

t:zone id=search t:id=searchZone
  t:form t:id=searchForm zone=searchZone
t:textfield t:id=query size=20/
input type=submit value=Search/
  /t:form
/t:zone

t:block id=searchResults
  ul
li t:type=loop source=searchHits value=searchHit${searchHit}/li
  /ul
/t:block
 






 Code Block








controls
true


linenumberslanguage
truejava

  

[CONF] Apache Tapestry Ajax Components FAQ

2011-09-01 Thread confluence







Ajax Components FAQ
Page edited by Howard M. Lewis Ship


Comment:
document AjaxResponseRenderer as replacement for MultiZoneUpdate


 Changes (3)
 




...
From the event handler method, instead of returning a Block or a Component, return a multi-zone update:  
{code:controls=true|linenumbers=true} 
{code:title=Multiple Zone Update (5.2)|controls=true|linenumbers=true} 
  @Inject   private Block searchResults; 
...
{code}  
The above will work in Tapestry 5.3, but MultiZoneUpdate is deprecated and replaced:  {code:title=Multiple Zone Update (5.2)|controls=true|linenumbers=true}   @Inject   private Block searchResults;@Inject   private Block statusBlock;@Inject   private AjaxResponseRenderer ajaxResponseRenderer;void onSuccessFromSearchForm()   { searchHits = searchService.performSearch(query);  message = String.format(Found %,d matching documents, searchHits.size());  ajaxResponseRenderer.addRender(results, searchResults).addRender(status, statusBlock);   } {code}  AjaxResponseRenderer adds other useful commands as well.  It also has the advantage that a simple return value can be returned to render content for the Zone that triggered the request.  
h3. Whats that weird number in the middle of the client ids after a Zone is updated?  
...


Full Content

_javascript_ FAQFrequently Asked QuestionsInjection FAQ

Ajax Components

Main article: Ajax and Zones

Do I have to specify both id and t:id for Zone components?

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

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

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.

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

How do I update the content of a Zone from an event handler method?

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 div element.

Where does that content come from?  You inject it into your page.



t:zone id="search" t:id="searchZone"
  t:form t:id="searchForm" zone="searchZone"
t:textfield t:id="query" size="20"/
input type="submit" value="Search"/
  /t:form
/t:zone

t:block id="searchResults"
  ul
li t:type="loop" source="searchHits" value="searchHit"${searchHit}/li
  /ul
/t:block





  @Inject
  private Block searchResults;

  Object onSuccessFromSearchForm()
  {
searchHits = searchService.performSearch(query);

return searchResults;
  }



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 div is replaced with the list of hits.

In many cases, you just want to re-render the Zone itself, to display updated content.  In that case, you don't need a separate t:block, instead you can use @InjectComponent to inject the Zone object itself, and return the Zone's body:



  @InjectComponent
  private Zone statusZone;

  Object onActionFromUpdateStatus()
  {
return statusZone.getBody();
  }



How to I update multiple zones in a single event handler?

To do this, you must know, on the server, the client ids of each Zone. That's one of the reasons that you will generally set the Zone's client id (via the Zone's id parameter), rather than let Tapestry assign a client id for you.

From the event handler method, instead of returning a Block or a Component, return a multi-zone update:

Multiple Zone Update (5.2)

  @Inject
  private Block searchResults;

  @Inject
  private Block statusBlock;

  Object onSuccessFromSearchForm()
  {
searchHits = searchService.performSearch(query);

message = String.format("Found %,d matching documents", searchHits.size());

return new MultiZoneUpdate("results", searchResults).add("status", statusBlock);
  }



The above will work in Tapestry 5.3, but MultiZoneUpdate is deprecated and replaced:

Multiple Zone 

[CONF] Apache Tapestry Ajax Components FAQ

2011-07-05 Thread confluence







Ajax Components FAQ
Page edited by Howard M. Lewis Ship


 Changes (2)
 




...
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.  
h3. Why do I sometimes get the exception The rendered content did not include any elements that allow for the positioning of the hidden form fields element. when rendering an empty Zone? 
 
As part of Tapestrys form processing, it must write a hidden input element with information needed when the form is submitted. Since the content of a Zone may be changed or removed, a hidden field is created just for the Zone, separate from the rest of the enclosing form.At the same time, Tapestry wants to position the input field in a valid location, and HTML defines some constraints for that; an input field must appear inside a p or div element. In your empty Zone, theres no place to put the hidden element.  The solution is to add the following to the body of your Zone:  {code} div class=t-invisible/ {code}  This ensures that theres a place for the hidden input field. The t-invisible CSS class ensures that the div does not display or otherwise affect layout.   
{scrollbar} 


Full Content

_javascript_ FAQFrequently Asked QuestionsInjection FAQ

Ajax Components

Main article: Ajax and Zones

Do I have to specify both id and t:id for Zone components?

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

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

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.

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

How do I update the content of a Zone from an event handler method?

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 div element.

Where does that content come from?  You inject it into your page.



t:zone id="search" t:id="searchZone"
  t:form t:id="searchForm" zone="searchZone"
t:textfield t:id="query" size="20"/
input type="submit" value="Search"/
  /t:form
/t:zone

t:block id="searchResults"
  ul
li t:type="loop" source="searchHits" value="searchHit"${searchHit}/li
  /ul
/t:block





  @Inject
  private Block searchResults;

  Object onSuccessFromSearchForm()
  {
searchHits = searchService.performSearch(query);

return searchResults;
  }



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 div is replaced with the list of hits.

In many cases, you just want to re-render the Zone itself, to display updated content.  In that case, you don't need a separate t:block, instead you can use @InjectComponent to inject the Zone object itself, and return the Zone's body:



  @InjectComponent
  private Zone statusZone;

  Object onActionFromUpdateStatus()
  {
return statusZone.getBody();
  }



How to I update multiple zones in a single event handler?

To do this, you must know, on the server, the client ids of each Zone. That's one of the reasons that you will generally set the Zone's client id (via the Zone's id parameter), rather than let Tapestry assign a client id for you.

From the event handler method, instead of returning a Block or a Component, return a multi-zone update:



  @Inject
  private Block searchResults;

  @Inject
  private Block statusBlock;

  Object onSuccessFromSearchForm()
  {
searchHits = searchService.performSearch(query);

message = String.format("Found %,d matching documents", searchHits.size());

return new MultiZoneUpdate("results", searchResults).add("status", statusBlock);
  }



What's that weird number in the middle of the client ids after a Zone is updated?

You might start with markup in your template for a component such as a TextField:



  t:textfield t:id="firstName"/



When the 

[CONF] Apache Tapestry Ajax Components FAQ

2011-02-21 Thread confluence







Ajax Components FAQ
Page edited by Howard M. Lewis Ship


 Changes (2)
 




{scrollbar}  
h2. Ajax Components  
...
 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. 
  {scrollbar} 


Full Content

_javascript_ FAQFrequently Asked QuestionsInjection FAQ

Ajax Components

Main article: Ajax and Zones

Do I have to specify both id and t:id for Zone components?

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

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

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.

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

How do I update the content of a Zone from an event handler method?

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 div element.

Where does that content come from?  You inject it into your page.



t:zone id="search" t:id="searchZone"
  t:form t:id="searchForm" zone="searchZone"
t:textfield t:id="query" size="20"/
input type="submit" value="Search"/
  /t:form
/t:zone

t:block id="searchResults"
  ul
li t:type="loop" source="searchHits" value="searchHit"${searchHit}/li
  /ul
/t:block





  @Inject
  private Block searchResults;

  Object onSuccessFromSearchForm()
  {
searchHits = searchService.performSearch(query);

return searchResults;
  }



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 div is replaced with the list of hits.

In many cases, you just want to re-render the Zone itself, to display updated content.  In that case, you don't need a separate t:block, instead you can use @InjectComponent to inject the Zone object itself, and return the Zone's body:



  @InjectComponent
  private Zone statusZone;

  Object onActionFromUpdateStatus()
  {
return statusZone.getBody();
  }



How to I update multiple zones in a single event handler?

To do this, you must know, on the server, the client ids of each Zone. That's one of the reasons that you will generally set the Zone's client id (via the Zone's id parameter), rather than let Tapestry assign a client id for you.

From the event handler method, instead of returning a Block or a Component, return a multi-zone update:



  @Inject
  private Block searchResults;

  @Inject
  private Block statusBlock;

  Object onSuccessFromSearchForm()
  {
searchHits = searchService.performSearch(query);

message = String.format("Found %,d matching documents", searchHits.size());

return new MultiZoneUpdate("results", searchResults).add("status", statusBlock);
  }



What's that weird number in the middle of the client ids after a Zone is updated?

You might start with markup in your template for a component such as a TextField:



  t:textfield t:id="firstName"/



When the component initially renders as part of a full page render, you get a sensible bit of markup:



  input id="firstName" name="firstName" type="text"



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



   input id="firstName_12a820cc40e" name="firstName" type="text"



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 id is expected to be unique; most _javascript_ is keyed off of the id field, for instance.

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

When the component is inside a loop, a suffix is appended:  firstName, firstName_0, firstName_1, etc.

When the component is rendered as part of an Ajax 

[CONF] Apache Tapestry Ajax Components FAQ

2011-01-02 Thread confluence







Ajax Components FAQ
Page edited by Bob Harner


Comment:
Renamed


 Changes (0)
 



...

Full Content

Ajax Components

Main article: Ajax  _javascript_

Do I have to specify both id and t:id for Zone components?

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

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

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.

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

How do I update the content of a Zone from an event handler method?

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 div element.

Where does that content come from?  You inject it into your page.



t:zone id="search" t:id="searchZone"
  t:form t:id="searchForm" zone="searchZone"
t:textfield t:id="query" size="20"/
input type="submit" value="Search"/
  /t:form
/t:zone

t:block id="searchResults"
  ul
li t:type="loop" source="searchHits" value="searchHit"${searchHit}/li
  /ul
/t:block





  @Inject
  private Block searchResults;

  Object onSuccessFromSearchForm()
  {
searchHits = searchService.performSearch(query);

return searchResults;
  }



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 div is replaced with the list of hits.

In many cases, you just want to re-render the Zone itself, to display updated content.  In that case, you don't need a separate t:block, instead you can use @InjectComponent to inject the Zone object itself, and return the Zone's body:



  @InjectComponent
  private Zone statusZone;

  Object onActionFromUpdateStatus()
  {
return statusZone.getBody();
  }



How to I update multiple zones in a single event handler?

To do this, you must know, on the server, the client ids of each Zone. That's one of the reasons that you will generally set the Zone's client id (via the Zone's id parameter), rather than let Tapestry assign a client id for you.

From the event handler method, instead of returning a Block or a Component, return a multi-zone update:



  @Inject
  private Block searchResults;

  @Inject
  private Block statusBlock;

  Object onSuccessFromSearchForm()
  {
searchHits = searchService.performSearch(query);

message = String.format("Found %,d matching documents", searchHits.size());

return new MultiZoneUpdate("results", searchResults).add("status", statusBlock);
  }



What's that weird number in the middle of the client ids after a Zone is updated?

You might start with markup in your template for a component such as a TextField:



  t:textfield t:id="firstName"/



When the component initially renders as part of a full page render, you get a sensible bit of markup:



  input id="firstName" name="firstName" type="text"



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



   input id="firstName_12a820cc40e" name="firstName" type="text"



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 id is expected to be unique; most _javascript_ is keyed off of the id field, for instance.

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

When the component is inside a loop, a suffix is appended:  firstName, firstName_0, firstName_1, etc.

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 rendered onto the page previously, it can't use its normal tricks to ensure that ids are unique.

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