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]