> I am trying to get a clickable map type effect
> using scriptaculous. I have a graph rendered > by GraphViz, I need scriptaculous to tell me the > click co-ordinates so that I can work out what in > the graph was clicked upon. > > It wouldn't be the first time that I didnt know what > I was doing, but I wondered if you could look at > this code for me. > > The containing div id is 'workflow'. > The problem is that callback "B" works, and callback > "A" doesnt. If I swap them around only the second > one works. Is this to be expected? I tried to reproduce the problem, but it works for me (see my file-out). My code evaluates all 4 callbacks correctly and I get the two co-ordinates displayed. I had to refactor your code a bit as it was missing some pieces, so maybe the problem is hidden there. Two comments: 1. The offset co-ordinates you get are probably not those you expect. offsetTop and offsetLeft answer the offset [1] up to the next absolute or relative positioned div, generally not those relative to the upper left corner of the document. In you case you probably need to use something like cumulativeOffset [2]. It also depends on your styles of course, so I don't know if that is a problem in your case. [1] http://developer.mozilla.org/en/docs/DOM:element.offsetLeft [2] http://prototypejs.org/api/position/cumulativeoffset 2. You can improve the performance of your example by combining the two #updater together. The first of your #updater is not really an #updater, it does not update anything. The #requestor would do here as well. I suggest to combine them to something like: html updater id: 'co-ordinates'; callback: [ :v | ... ] value: ...; callback: [ :v | ... ] value: ...; callback: [ :v | ... ] value: ...; callback: [ :v | ... ] value: ...; on: #renderCoordinatesOn: of: self Cheers, Lukas >renderImageOn: html > | offsetX offsetY | > > offsetX := ValueHolder new. > offsetY := ValueHolder new. > self generateGraphForm. > html image > id: 'workflow-image'; > onClick: (html updater > "A" callback: [ :v | offsetY contents: v asNumber ] value: (((SUElement on: html) id: 'workflow') property:'offsetTop'); > "B" callback: [ :v | offsetX contents: v asNumber ] value: (((SUElement on: html) id: 'workflow') property:'offsetLeft'); > callback: [ :v | graphFormClickX := v asNumber - offsetX contents ] value: SUEvent new x; > callback: [ :v | graphFormClickY := v asNumber - offsetY contents ] value: SUEvent new y); > onClick: (html updater id: 'co-ordinates'; on: #renderCoordinatesOn: of: self ); > form: graphForm "; height: (form height // self scaleDownFactor); width: (form width // self scaleDownFactor)" > "] " -- Lukas Renggli http://www.lukas-renggli.ch _______________________________________________ Seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
> 2. You can improve the performance of your example by combining the
> two #updater together. The first of your #updater is not really an > #updater, it does not update anything. The #requestor would do here as > well. I suggest to combine them to something like: > > html updater > id: 'co-ordinates'; > callback: [ :v | ... ] value: ...; > callback: [ :v | ... ] value: ...; > callback: [ :v | ... ] value: ...; > callback: [ :v | ... ] value: ...; > on: #renderCoordinatesOn: of: self Sorry, I just noticed that this is even required to make it correct. Since all AJAX actions are synchronous (the A in AJAX), there is no guarantee that the first #updater will finish before the second one. So you have to combine the two into one, or use the completion event of the first to trigger the second. Lukas -- Lukas Renggli http://www.lukas-renggli.ch _______________________________________________ Seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by Lukas Renggli
> Looking at the resultant javascript I worked out roughly what was going on.
> > ((SUElement on: html) id: 'workflow'_ property:' offsetTop') > > was generating something like Element('workflow').toggle['offsetTop'] > > The first time it would not work (well it would not get the correct > answer), the second time it did. Does this make any sense? Oups, I missed that. In this case it makes sense. The first time you toggle it gets hidden and therefor returns the wrong result (a hidden element has offset 0). The second time it gets shown again and the new offset is read. I just wonder why I didn't observe that yesterday when I tried it out :-/ > I could not find a way to get rid of the call to toggle, and even when I > hacked the code to allow SUElement-#method to return nil, > Element('workflow)['offsetTop'] didnt seem to work. So I ended up using Yes these default methods are nasty. This is not the first time I got bitten. These methods date back to the very first versions of Scriptaculous, where the JavaScript framework was not that composable at all. Nowadays this sort of contradicts the free composability of the elements. I will try to refactor that, let's see if this can be done without breaking some older code. The problem is that offsetTop is not a Scriptaculous method, but one from DOM. Therefor it cannot be written the same way other Scriptaculous functions can. The shortest form would probably be: $('id1').offsetTop > I didnt receive a fileOut with your email. Sorry, I forgot to attach it and now I don't have it anymore. Anyway, I described my changes in the mail. > I do want to update several things perhaps 5 items, not just the > co-ordinates, is that achievable using this scheme? > > e.g. > > onClick: (html updater id: 'co-ordinates'; on: > #renderCoordinatesOn: of: self ); > onClick: (html updater id: 'workflow-focus'; on: #renderFocusOn: > of: self ); Yes that's possible but highly inefficient (5 independent requests) and there is no guarantee of the order in which all these updates will be performed. So I suggest that you use the evaluator, that is made to do such complicated things in one go (one single request): onClick: (html evaluator " data pushed to the server " callback: [ :v | ... ] value: ...; callback: [ :v | ... ] value: ...; callback: [ :v | ... ] value: ...; ... " response script s sent back to the client (in this case the contents of id1..id3 is updated) " callback: [ :s | s element id: 'id1'; render: [ :r | ... ]. s element id: 'id2'; render: [ :r | ... ]. s element id: 'id3'; render: [ :r | ... ]. ... ]) HTH, Lukas -- Lukas Renggli http://www.lukas-renggli.ch _______________________________________________ Seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
> > I could not find a way to get rid of the call to toggle, and even when I
> > hacked the code to allow SUElement-#method to return nil, > > Element('workflow)['offsetTop'] didnt seem to work. So I ended up using > > Yes these default methods are nasty. This is not the first time I got > bitten. These methods date back to the very first versions of > Scriptaculous, where the JavaScript framework was not that composable > at all. Nowadays this sort of contradicts the free composability of > the elements. I will try to refactor that, let's see if this can be > done without breaking some older code. I published a first try at this refactoring. If you are on Seaside 2.8 you can give it a try, it should be now much simpler to do what you want. Also the generated JavaScript is simpler and the overal design, so I think it is a good thing. Name: Scriptaculous-lr.198 Author: lr Time: 11 June 2007, 8:10:32 am UUID: 8a051271-9d8f-4ade-a25e-f499d5c569a8 Ancestors: Scriptaculous-lr.197 - refactored Element, Form and FormElement to be more extensible and to better match the new way of prototype programming - fixed and updated some tests - added some missing actions - WARNING: these elements don't have default actions anymore -- Lukas Renggli http://www.lukas-renggli.ch _______________________________________________ Seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
> I published a first try at this refactoring. If you are on Seaside 2.8
> you can give it a try, it should be now much simpler to do what you > want. Also the generated JavaScript is simpler and the overal design, > so I think it is a good thing. > > Name: Scriptaculous-lr.198 Excellent - I was attempting to do something similar myself. I've published changes (Scriptaculous-srh.199) based on that version to enable the Enumerable methods on SUElement, plus refactor SUSelector so as to avoid duplication. Regards, Stuart. _______________________________________________ Seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Free forum by Nabble | Edit this page |