I've been using seaside with jquery to create quite interactive
interfaces, using the simplest approach of "everything has its own callback". This works well if the dataset you're working with is small, but I'm now venturing into territories where it takes seconds to receive+render a page, which isn't acceptable. For an example of what I'm talking about imagine a page showing a list of emails. Every line (email) has a clickable sender, subject, date, and a bunch of more actions and icons etc. If you're creating anchors/click actions for each field separately, that's easily hundreds or thousands of callbacks per page, each needing to be generated on the server and sent over the wire. So clearly I need to instead write client side javascript that will figure out what the user clicked and do a parametrized request. Which I can do, but I'm wondering if someone has figured out a clever way how to map the information on the page to smalltalk objects on the server (other than using callback registry). Same goes for bulk actions involving multiple items ("delete selected" and the like). rado _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
2011/3/13 radoslav hodnicak <[hidden email]>:
> I've been using seaside with jquery to create quite interactive > interfaces, using the simplest approach of "everything has its own > callback". This works well if the dataset you're working with is > small, but I'm now venturing into territories where it takes seconds > to receive+render a page, which isn't acceptable. > > For an example of what I'm talking about imagine a page showing a list > of emails. Every line (email) has a clickable sender, subject, date, > and a bunch of more actions and icons etc. If you're creating > anchors/click actions for each field separately, that's easily > hundreds or thousands of callbacks per page, each needing to be > generated on the server and sent over the wire. So clearly I need to > instead write client side javascript that will figure out what the > user clicked and do a parametrized request. Which I can do, but I'm > wondering if someone has figured out a clever way how to map the > information on the page to smalltalk objects on the server (other than > using callback registry). Same goes for bulk actions involving > multiple items ("delete selected" and the like). I don't think there's an alternative. Unfortunately callbacks are currently hard wired to read only one request field. In addition if you move the code to a request handler it is hard to access the session from there :-( Cheers Philippe _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by radoslav hodnicak
On Sun, 13 Mar 2011, radoslav hodnicak wrote:
> I've been using seaside with jquery to create quite interactive > interfaces, using the simplest approach of "everything has its own > callback". This works well if the dataset you're working with is > small, but I'm now venturing into territories where it takes seconds > to receive+render a page, which isn't acceptable. > > For an example of what I'm talking about imagine a page showing a list > of emails. Every line (email) has a clickable sender, subject, date, > and a bunch of more actions and icons etc. If you're creating > anchors/click actions for each field separately, that's easily > hundreds or thousands of callbacks per page, each needing to be > generated on the server and sent over the wire. So clearly I need to > instead write client side javascript that will figure out what the > user clicked and do a parametrized request. Which I can do, but I'm > wondering if someone has figured out a clever way how to map the > information on the page to smalltalk objects on the server (other than > using callback registry). Same goes for bulk actions involving > multiple items ("delete selected" and the like). We implemented a hack, that does the following: Instead of Seaside callbacks we implemented our own lightweight callbacks on top of Seaside's. We have a method, that accepts a block and a seaside canvas. The receiver (typically a WAComponent) of the message has an OrderedCollection which stores the callback blocks. When you send the method, it adds the block to the collection and returns a piece of javascript which calls a function with the index of the block in the collection. The returned javascript code is passed to #onClick:, #onChange:, etc. Something like: html button onClick: (self lightweightCallBackOn: html do: [ self buttonClicked ]); with: 'Click me!' The generated html will be something like: <button onclick="c1lc(1)">Click me!</button> The javascript function (c1lc in this case) is built using Seaside's js code generator when the page is rendered and it's added with #addLoadScript: to page. The generated function triggers a Seaside JQuery callback. The callback accepts the index as argument, looks up the block by index and evaluates it. Levente > > rado > _______________________________________________ > seaside mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by radoslav hodnicak
We have encountered a similar issue when generating lists of thousands of elements that each needed interactivity client-side. However, the issue was more related to having a jQuery editable for each of those html elements, which took seconds to register on each element separately. But the issue is identical in the sense that we needed to revert to a single Seaside callback that is triggered by a Javascript function.
The solution boils down to the following: - have a unique identifier for each of the objects that allows a mapping from the identifier back to the object (e.g. we have unique keys for all objects in our db) - define a single seaside callback for the click event inside a javascript function - define the click event on the applicable html entities to use the above javascript function (e.g. using jQuery). The first item depends on how your application works. In the snippets below, I assume that <yourObjectRegistry> is a dictionary that allows a mapping from id to the object. These snippets illustrate how to achieve the second and third item. * Assign the seaside callback to a javascript function upon page load: html document addLoadScript: ((html jQuery ajax callback: [:id | (yourObjectRegistry at: id) doYourAction ] value: (JSStream on: 'id')) asFunction: #(id)) assignTo: 'clickAction' * Register the click events on each applicable html element such that they call the previously defined javascript function: html listItem onClick: (JSStream on: 'clickAction($(this).id)'); with: [ ... ] I hope this helps you out. But I'm not sure if that will really improve page rendering speed or size. The size of the callback url is not that much different from the size of the onClick event script. In our case, by doing the above, we did not need to include the triggering of a jQuery editable for each generated html element. That resulted in a 10 times page rendering speedup because the load script was not registering the +1000 editables anymore. But let us know how it went! Johan On 13 Mar 2011, at 03:21, radoslav hodnicak wrote: > I've been using seaside with jquery to create quite interactive > interfaces, using the simplest approach of "everything has its own > callback". This works well if the dataset you're working with is > small, but I'm now venturing into territories where it takes seconds > to receive+render a page, which isn't acceptable. > > For an example of what I'm talking about imagine a page showing a list > of emails. Every line (email) has a clickable sender, subject, date, > and a bunch of more actions and icons etc. If you're creating > anchors/click actions for each field separately, that's easily > hundreds or thousands of callbacks per page, each needing to be > generated on the server and sent over the wire. So clearly I need to > instead write client side javascript that will figure out what the > user clicked and do a parametrized request. Which I can do, but I'm > wondering if someone has figured out a clever way how to map the > information on the page to smalltalk objects on the server (other than > using callback registry). Same goes for bulk actions involving > multiple items ("delete selected" and the like). > > rado > _______________________________________________ > seaside mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Yes Johan, I've been thinking along similar lines, with the exception
that what I really want to do is to register one seaside callback and one javascript event handler on the parent object. For example, if you have a table/list with 500 cells, you don't attach an event handler to each cell, but one to the table itself, or to a container above it. This will speed up page generation/rendering a lot. The handler will then look at the id/class of the cell that generated the event and figure out what to do/send to seaside. rado On Sun, Mar 13, 2011 at 1:56 PM, Johan Brichau <[hidden email]> wrote: > We have encountered a similar issue when generating lists of thousands of elements that each needed interactivity client-side. However, the issue was more related to having a jQuery editable for each of those html elements, which took seconds to register on each element separately. But the issue is identical in the sense that we needed to revert to a single Seaside callback that is triggered by a Javascript function. > > The solution boils down to the following: > - have a unique identifier for each of the objects that allows a mapping from the identifier back to the object (e.g. we have unique keys for all objects in our db) > - define a single seaside callback for the click event inside a javascript function > - define the click event on the applicable html entities to use the above javascript function (e.g. using jQuery). > > The first item depends on how your application works. In the snippets below, I assume that <yourObjectRegistry> is a dictionary that allows a mapping from id to the object. These snippets illustrate how to achieve the second and third item. > > * Assign the seaside callback to a javascript function upon page load: > > html document addLoadScript: > ((html jQuery ajax > callback: [:id | (yourObjectRegistry at: id) doYourAction ] > value: (JSStream on: 'id')) asFunction: #(id)) > assignTo: 'clickAction' > > * Register the click events on each applicable html element such that they call the previously defined javascript function: > > html listItem > onClick: (JSStream on: 'clickAction($(this).id)'); > with: [ ... ] > > > I hope this helps you out. But I'm not sure if that will really improve page rendering speed or size. The size of the callback url is not that much different from the size of the onClick event script. > In our case, by doing the above, we did not need to include the triggering of a jQuery editable for each generated html element. That resulted in a 10 times page rendering speedup because the load script was not registering the +1000 editables anymore. > But let us know how it went! > > Johan > > On 13 Mar 2011, at 03:21, radoslav hodnicak wrote: > >> I've been using seaside with jquery to create quite interactive >> interfaces, using the simplest approach of "everything has its own >> callback". This works well if the dataset you're working with is >> small, but I'm now venturing into territories where it takes seconds >> to receive+render a page, which isn't acceptable. >> >> For an example of what I'm talking about imagine a page showing a list >> of emails. Every line (email) has a clickable sender, subject, date, >> and a bunch of more actions and icons etc. If you're creating >> anchors/click actions for each field separately, that's easily >> hundreds or thousands of callbacks per page, each needing to be >> generated on the server and sent over the wire. So clearly I need to >> instead write client side javascript that will figure out what the >> user clicked and do a parametrized request. Which I can do, but I'm >> wondering if someone has figured out a clever way how to map the >> information on the page to smalltalk objects on the server (other than >> using callback registry). Same goes for bulk actions involving >> multiple items ("delete selected" and the like). >> >> rado >> _______________________________________________ >> seaside mailing list >> [hidden email] >> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > > _______________________________________________ > seaside mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
I should add that my previous post is not a call for assistance. I
know how to do it :-) On Sun, Mar 13, 2011 at 3:05 PM, radoslav hodnicak <[hidden email]> wrote: > Yes Johan, I've been thinking along similar lines, with the exception that what I really want to do is to register one seaside callback and one javascript event handler on the parent object. For example, if you have a table/list with 500 cells, you don't attach an event handler to each cell, but one to the table itself, or to a container above it. This will speed up page generation/rendering a lot. The handler will then look at the id/class of the cell that generated the event and figure out what to do/send to seaside. > > rado > _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by Johan Brichau-2
Johan Brichau wrote:
> > * Register the click events on each applicable html element such that they call the previously defined javascript function: > > html listItem > onClick: (JSStream on: 'clickAction($(this).id)'); > with: [ ... ] > A was thinking about the same problem just today. A potential problem is that it leaks IDs into HTML. One could easily guess a valid ID which maps to a database object which he normally wouldn't have access to. Hm... unless you take special care to obfuscate the ID. -- Milan Mimica http://sparklet.sf.net _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
2011/3/13 Milan Mimica <[hidden email]>:
> Johan Brichau wrote: >> >> * Register the click events on each applicable html element such that they >> call the previously defined javascript function: >> >> html listItem onClick: (JSStream on: >> 'clickAction($(this).id)'); >> with: [ ... ] >> > > A was thinking about the same problem just today. A potential problem is > that it leaks IDs into HTML. One could easily guess a valid ID which maps to > a database object which he normally wouldn't have access to. Hm... unless > you take special care to obfuscate the ID. Or encrypt them. Cheers Philippe _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by mmimica
Well I don't plan to use database IDs on the page directly - for one
they are like 20+ characters long (UUIDs), so that would defeat some of the reasons for doing this (less data sent over the wire), and yes it's a security hole. I'm just going to have an element id <-> object mapping on the server, which isn't really different from having callback IDs embedded in the html. rado On Sun, Mar 13, 2011 at 6:26 PM, Milan Mimica <[hidden email]> wrote: > Johan Brichau wrote: >> >> * Register the click events on each applicable html element such that they >> call the previously defined javascript function: >> >> html listItem onClick: (JSStream on: >> 'clickAction($(this).id)'); >> with: [ ... ] >> > > A was thinking about the same problem just today. A potential problem is > that it leaks IDs into HTML. One could easily guess a valid ID which maps to > a database object which he normally wouldn't have access to. Hm... unless > you take special care to obfuscate the ID. > > > > -- > Milan Mimica > http://sparklet.sf.net > _______________________________________________ > seaside mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
radoslav hodnicak wrote:
> Well I don't plan to use database IDs on the page directly - for one > they are like 20+ characters long (UUIDs), so that would defeat some > of the reasons for doing this (less data sent over the wire), and yes > it's a security hole. I'm just going to have an element id <-> object > mapping on the server, which isn't really different from having > callback IDs embedded in the html. The ID's are persistent, unlike Seaside callback urls. I think that's even more important. One could reuse ID (encripted or not) later to access objects. I'm just thinking about my aplication. It may not be an issue to some. -- Milan Mimica http://sparklet.sf.net _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by radoslav hodnicak
no pun intended, but is a design issue (and not a seaside one) It sounds like you really need to re-think the UX a strong signal of that is that lists presenting thousands of items to a human being are hardly useful alternatives? think in some kind of aggregation (meaningful to the domain of the app) that can be navigated (drill down) to smaller lists then you'll find out that all those issues are gone (including the security-related ones) and the app's usability gets increased On Mar 12, 2011, at 11:21 PM, radoslav hodnicak wrote:
_______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by radoslav hodnicak
Sebastian wrote
>It sounds like you really need to re-think the UX >a strong signal of that is that lists presenting thousands of items to a human being >are hardly useful Excel has its usability problems, but I think you're being too harsh here :) My OpenOffice spreadsheet shows 1700 cells at 100% in a full screen window. Stephan _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by radoslav hodnicak
Milan wrote:
>A potential problem is that it leaks IDs into HTML. >One could easily guess a valid ID which maps to a database > object which he normally wouldn't have access to. >Hm... unless you take special care to obfuscate the ID. Basic security would be to always use a mapping dictionary and generate IDs. Stephan _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by Stephan Eggermont-3
caution my friend... you're playing with the dark side here
do you really want me to start about excel? give me the signal and I'll merciless unleash all the horses :D On Mar 14, 2011, at 3:32 PM, Stephan Eggermont wrote:
_______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by Levente Uzonyi-2
Levente, that is really clever hack. I have grids that may gain from this
technique. Could you share the code? Thanks _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Free forum by Nabble | Edit this page |