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]
>>
>>
>>
>>     
>
>   

Reply via email to