Hi Tobias, Unfortunately I can't think of a clean workaround for that. The issues are all in the javascript and how events are dispatched and handled. Basically it comes down to 2 problems:
1) The W3C does not mandate even handler ordering, so if you register a handler before another there is no guarantee that it will actually fire before the other. Lame. 2) Stopping the DOM event only stops it's propagation to subsequent DOM elements and not subsequent handlers. So that means that even if you knew your handler would fire first, stopping the event will not stop the zone handler from firing. Coincidentally my tests show that the mixin's JS handler is fired first, but that's no guarantee. If it was then you could override the Tapestry.linkZone method to make an explicit check on the event to see if has been stopped (event.stopped), and if so cancel the operation. Not really a nice option, unfortunately. You could take it further to force ordering using some function reference replacement voodoo, but that's a tad nasty. Perhaps this logic would be better factored into the components. Any other thoughts, anyone? Tobias Wehrum wrote: > Hi Chris, > > first let me please thank you for the example you've written. It's > quite informative. > > I've discovered a problem with updating a zone - I think it's no > problem of your mixin, but you may have an idea how to fix it. > > The problem is: When I use have an actionlink with the confirm mixin > and a t:zone, it doesn't matter whether I click "ok" or "cancel": The > function updating the zone will called anyway. Short example: > > ---------------------------------------------------------------------------------------------------------------------------- > > <t:zone t:id="testArea"> > </t:zone> > <t:actionlink t:id="test" t:zone="testArea" > t:mixins="confirm">Test 1</t:actionlink><br/> > <t:actionlink t:id="test2" t:mixins="confirm">Test 2</t:actionlink> > ---------------------------------------------------------------------------------------------------------------------------- > > > ---------------------------------------------------------------------------------------------------------------------------- > > @Component > private Zone testArea; > @OnEvent(component="test", value="action") > Zone onActionFromTest() > { > System.out.println("onActionFromTest!"); > return testArea; > } > > @OnEvent(component="test2", value="action") > void onActionFromTest2() > { > System.out.println("onActionFromTest2!"); > } > ---------------------------------------------------------------------------------------------------------------------------- > > > Now when you click on "Test 1", the console will output > "onActionFromTest!", regardless of which choice I make in the confirm > dialog. > "Test 2" works without problems. > > Do you - or anybody else - have any idea why this is the case, or even > better, a possible solution for it? > > Thanks in advance, > Tobias > > Chris Lewis schrieb: >> Hi Lucca, >> >> I'd been looking for a good example to use to write a wiki explaining >> the integration javascript by Tapestry, and your request gave me what I >> was looking for. Check out the article here: >> http://wiki.apache.org/tapestry/Tapestry5AndJavaScriptExplained (project >> source: http://thegodcode.net/tapestry5/jsclarity-project.zip). Apart >> from discussing in detail how T5 integrates JS, it shows how to create a >> mixin that can be added to link components. The mixin attaches js code >> to the component, so that when the link is clicked the user is presented >> with a confirmation box. Canceling the box cancels the click, while OK >> allows it to proceed as normal. This should be useful for those looking >> to add click confirmation functionality, but in your case I'm not sure >> if it will help. I ask you to try and see, but the problem will be how >> T5 attaches the js handlers for the ajax code (that is, they may fire >> before the confirmation code). >> >> Anyway, I think it will be helpful to those looking for such an >> explanation, and I hope it helps you. >> >> chris >> >> Luca Fossato wrote: >> >>> Hi all, >>> >>> I'm playing with actionlink and zones to understand T5 ajax functions >>> (Tapestry 5.0.11). >>> I'd like to define an actionlink like this one: >>> >>> <t:actionlink t:id="deleteLink" context="myContext" >>> t:zone="zoneToUpdate" onclick="confirm('are you sure to delete this >>> record ?');">delete</t:actionlink> >>> >>> where the onclick handler uses a javascript confirmation dialog to ask >>> to the user if he/she wants to delete the selected record. >>> It seems to me the Tapestry.linkZone js function "eats" the user >>> onclick handler and set its own - so it is not possible to execute any >>> js code prior to invoke the ajax call. >>> >>> Is it correct or am I missing something ? >>> >>> I tried to "fix" this behaviour, modifying a bit the Tapestry.linkZone >>> function (just an experiment): >>> >>> --- cut here --- >>> >>> /** Convert a form or link into a trigger of an Ajax update that >>> * updates the indicated Zone. >>> */ >>> linkZone : function(element, zoneDiv) >>> { >>> // ... original code until "Otherwise, assume it's just an ordinary >>> link." comment... >>> >>> // Otherwise, assume it's just an ordinary link. >>> var onClickValue = element.getAttribute("onclick"); >>> if (onClickValue != null) >>> { >>> element.setAttribute("tapestry5_onbeforeajax", onClickValue); >>> } >>> >>> var handler = function(event) >>> { >>> var onBeforeAjaxRes = true; >>> var onBeforeAjaxValue = >>> element.getAttribute("tapestry5_onbeforeajax"); >>> if (onBeforeAjaxValue != null) >>> { >>> onBeforeAjaxRes = eval(onBeforeAjaxValue); >>> } >>> >>> // execute the Ajax request only if the original onclick >>> attribute was not set or if the evaluation >>> // of the related function returned true; >>> if (onBeforeAjaxRes === undefined || onBeforeAjaxRes) >>> new Ajax.Request(element.href, { onSuccess : successHandler }); >>> >>> return false; >>> }; >>> >>> element.onclick = handler; >>> }, // end of linkZone function >>> >>> --- cut here --- >>> >>> that is a 10 minutes "fix", so probably it's not the best solution. >>> Anyway it seems to work fine for my experiment ;^) >>> To block the execution of the ajax call, do NOT use a return statement >>> inside the onclick handler. Example: >>> >>> <t:actionlink t:id="deleteLink" t:zone="zoneToUpdate" onclick="return >>> myFunction(myParam);">delete</t:actionlink> >>> >>> use this instead: >>> >>> <t:actionlink t:id="deleteLink" t:zone="zoneToUpdate" >>> onclick="myFunction(myParam);">delete</t:actionlink> >>> >>> because eval() returns the value of the last expression evaluated. >>> http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Functions:eval >>> >>> >>> Does this stuff make sense for you ?? ;^) >>> >>> Thank you, >>> Luca Fossato >>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: [EMAIL PROTECTED] >>> For additional commands, e-mail: [EMAIL PROTECTED] >>> >>> >>> >> >> > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > -- http://thegodcode.net --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]