Awesome!

Sorry, I overlooked that one ... I'm just a noob :P

Thanks for sharing HugoPalma.

All that I want now is the ability do away with the currentZoneId property.
Could someone explain the component prefix of a binding expression. The
Component Parameters page of the tapestry-core guide simply says:

'The id of another component within the same template'

Could someone provide an example of how it's used?


HugoPalma wrote:
> 
> Regarding your request for the event attribute in ActionLink. Doesn't
> the component EventLink solve your problem ?
> 
> http://tapestry.apache.org/tapestry5/tapestry-core/ref/org/apache/tapestry/corelib/components/EventLink.html
> 
> Corin Lawson wrote:
>> Hi All,
>>
>> I admire Travis' ambition, but he's forgetting an ancient programming
>> maxim:
>> be lazy! By that I mean there no need to implement your own Zone
>> component
>> (or sub-component). I actually got this to work, but I'm not %100
>> satisfied.
>>
>> So the id attribute of zone doesn't allow property expansion; don't
>> despair,
>> use the default. The Loop component does 'unique-ify' the ids in a
>> predictable manner, so let's take advantage of that! All we need is a
>> method
>> to compute what the zone id is expected to be for that iteration. This
>> would
>> be possible with render variables, if it weren't the fact that the second
>> iteration starts at zero!
>>
>> .tml snippet:
>>     <t:loop t:source="..." t:index="currentIndex" t:value="currentValue">
>>         <t:zone t:id="myZone">...${currentValue}...</t:zone>
>>         <t:actionlink t:id="myAction" t:zone="prop:currentZoneId"
>> t:context="currentValue">...</t:actionlink>
>>     </t:loop>
>>
>> .java snippet:
>>     @Component
>>     private Zone _myZone;
>>
>>     private int _currentIndex; // Getters and Setters...
>>     private Object _currentValue; // Getters and Setters...
>>
>>     public String getCurrentZoneId() {
>>         if(_currentIndex == 0)
>>             return "myZone";
>>         return "myZone_" + (_currentIndex - 1);
>>     }
>>
>>     Object onAction(_currentValue) {
>>         setCurrentValue(_currentValue);
>>         return _myZone;
>>     }
>>
>> Note that it is important to pass the currentValue through the context
>> because I have used it's value inside the zone. Any property expansion
>> inside the zone needs to passed through the context otherwise Tapestry
>> (or
>> more specifically the Zone component) doesn't know what iteration it is.
>>
>> Limitations:
>>
>>  (*) We are stuck with Loop's unique-ifation.
>>  (*) We must use the generic onAction event handler (unless the OnEvent
>> annotation does property expansion in the component attribute(?))
>>  (*) Don't go crazy with the currentValue, stick to the primitives.
>> Having
>> said that you can always pass the currentIndex through the context and
>> use
>> that to set the currentValue.
>>
>> There is a work-around these limitations. If with define an upper limit
>> to
>> the size of the Loop's source list (not an unreasonable thing to do) then
>> we
>> could ditch the context and be verbose to the event handler methods like
>> so:
>>
>>     Object onActionFromMyAction() {
>>         _currentIndex = 0;
>>         _currentValue = ...;
>>         return _myZone;
>>     }
>>
>>     Object onActionFromMyAction_0() {
>>         _currentIndex = 1;
>>         _currentValue = ...;
>>         return _myZone;
>>     }
>>
>>     Object onActionFromMyAction_1() {
>>         _currentIndex = 2;
>>         _currentValue = ...;
>>         return _myZone;
>>     }
>>
>> etc.
>>
>> In fact, it would be a fairly simple task to do this with java
>> instrumentation. It would be even better to have a event type attribute
>> on
>> ActionLink, so that we can specify something other than action, like:
>>
>>     Object onMyEventFromMyLink(currentIndex) {
>>         ...
>>         return _myZone;
>>     }
>>
>> Dear Commiters, please add an event attribute to ActionLink.
>>
>> Cheers,
>> Corin.
>>
>>
>> Travis McLeskey wrote:
>>   
>>> (I wasn't subscribed to the list, so I'm sorry I'm not quoting the  
>>> rest of the thread here.)
>>>
>>> I ran into the same problem as Adriaan: it wouldn't let me use a  
>>> property expansion for the zone's id attribute. The only way around  
>>> this that I found was to create my own MyZone component (based on  
>>> Tapestry's Zone.java) and add a "customId" attribute. Then, in  
>>> MyZone.beginRender(), I replaced this:
>>>
>>>          _clientId =  
>>> _pageRenderSupport.allocateClientId(_resources.getId());
>>>
>>> with something like:
>>>
>>>          if( _resources.isBound("customId") )
>>>              _clientId = _customId;
>>>          else
>>>              _clientId =  
>>> _pageRenderSupport.allocateClientId(_resources.getId());
>>>
>>> Then, I made my loop look more like this:
>>>
>>> <t:loop source="items" value="item">
>>>   <t:actionlink zone="myzone:${item.id}">go!</t:actionlink>
>>>   <t:myzone customid="myzone:${item.id}">in the zone?</t:zone>
>>>   <br />
>>> </t:loop>
>>>
>>> Which worked quite nicely, and it let me make a few other tweaks to  
>>> how the Zone was rendered, like making it a  instead of a <div>.
>>>
>>>
>>>
>>> However, that was only the first Zone-related hurdle. The next was  
>>> that I couldn't find any examples in the documentation of how to  
>>> actually provide the new content for the zone when the user clicks the  
>>> link. After a lot of time digging through the code (and learning  
>>> javascript!), I found the (or at least *a*) way to do it. I added this  
>>> method to my class:
>>>
>>>      public Object onActionFromUpdatezone(final long id) {
>>>          JSONObject result = new JSONObject();
>>>          result.put("content", "The new content for the Zone's <div>.  
>>> Fresh from the server!");
>>>          return result;
>>>      }
>>>
>>> (Note: I gave the ActionLink an id: "updatezone")
>>>
>>>
>>>
>>> The next problem was that Zones in Tapestry currently can't do much  
>>> other than query the server for new content, put that content in the  
>>> <div>, and then call your "show" or "update" methods, if you specified  
>>> them. You can't have it do something other than hit the server when  
>>> the link is clicked, and you can't process the content before putting  
>>> it in the <div>. Well, at least you can't do these things without the  
>>> magic of javascript. My eventual solution is probably going to break  
>>> in some future release of Tapestry, and it may provoke some frowns,  
>>> but I circumvented all of the Zone-specific javascript code in  
>>> Tapestry be redefining Tapestry.initializeZones. The javascript below  
>>> is for an ActionLink that works as an expand/collapse button for the  
>>> Zone. The first time you expand the zone, it downloads the content  
>>> from the server and stores it in memory. After that, it doesn't need  
>>> to hit the server again. Note that this code doesn't support the inner  
>>> "t-zone-update" <div> that Tapestry's built-in javascript supports.
>>>
>>>
>>> MyObj = {
>>>    linkZone: function (link, zone) {
>>>      zone = $(zone);
>>>      link = $(link);
>>>      var expanded = false;
>>>      var origHTML = zone.innerHTML;
>>>      var fullHTML;
>>>
>>>      link.onclick = function(event) {
>>>        if( expanded ) {
>>>          zone.innerHTML = origHTML;
>>>          link.innerHTML = "expand";
>>>          expanded = false;
>>>        } else {
>>>          if( !zone.everPopulated ) {
>>>            var successHandler = function(transport) {
>>>              var response = transport.responseText;
>>>              fullHTML = eval("(" + response + ")").content;
>>>              zone.innerHTML = fullHTML;
>>>            };
>>>            var request = new Ajax.Request(link.href, { onSuccess :  
>>> successHandler });
>>>            zone.everPopulated = true;
>>>          } else {
>>>            zone.innerHTML = fullHTML;
>>>          }
>>>          link.innerHTML = "collapse"
>>>          expanded = true;
>>>        }
>>>        return false;
>>>      };
>>>    }
>>> };
>>>
>>> Tapestry.initializeZones = function(zoneSpecs, linkSpecs) {
>>>    $A(linkSpecs).each(function (spec)
>>>    {
>>>        MyObj.linkZone(spec[0],spec[1]);
>>>    });
>>> };
>>>
>>>
>>>
>>> Hope that helps!
>>> Travis
>>>
>>>
>>>
>>>
>>>
>>> On Feb 8, 2008, at 11:40 PM, Travis McLeskey wrote:
>>>
>>>     
>>>> When an ActionLink and Zone appear together in a loop like this:
>>>>
>>>> <t:loop source="items" value="item">
>>>>  <t:actionlink zone="myzone">go!</t:actionlink>
>>>>  <t:zone t:id="myzone">in the zone?</t:zone>
>>>>  <br />
>>>> </t:loop>
>>>>
>>>> Clicking the "go!" link from any iteration only affects the Zone  
>>>> from the first iteration. How do I connect each ActionLink to its  
>>>> corresponding Zone? I tried injecting the Zone into the java class  
>>>> and then using zone="${thezone.id}" in the actionlink, but then each  
>>>> ActionLink was connected to the Zone from the *previous* iteration.
>>>>
>>>> Thanks!
>>>> Travis
>>>>
>>>>       
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>>> For additional commands, e-mail: [EMAIL PROTECTED]
>>>
>>>
>>>
>>>     
>>
>>   
> 
> 

-- 
View this message in context: 
http://www.nabble.com/T5%3A-ActionLink-Zone-components-inside-a-loop-tp15374193p15469723.html
Sent from the Tapestry - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to