[Bese-devel] AJAX teaser
Drew Crampsie
drewc at tech.coop
Tue Jan 24 03:29:35 UTC 2006
Hey Hoan,
Hoan Ton-That wrote:
>These macros allow us to execute actions on the server side,
>and reload the changes on the client side. They were written
>to be as similar as possible to the <ucw macros. Unlike <ucw
>macros, actions can be attached to multiple DOM events and
>can be used with callbacks.
>
>
Nice Work! I had implemented something similar at one point, but dropped
it in favour of a more programmatic approach. Now i just generate
'normal' html, and add the ajax functionality afterwards. It ends up
being a little (ok a lot) more verbose, but degrades better.
That being said, if one were doing a pure ajax application, this would
be very useful indeed!
I'd love to see the source, even if it's unfinished, just to see how you
solved the same problems i did :). I did notice you chose Dojo, which
is, IMO, the best JS library by far.
>At the moment, the implementation isn't quite there yet.
>Some things are still not implemented yet like back-button
>support, updating every single component that has changed
>(not just the current place), and many other things.
>
>
Both of those are tough problems. for updating multiple components, what
i did was have the ajax call return to the browser a javascript function
which would perform the subsequent http-requests for each updated
component. I don't think this is best, as with too many requests it ends
up faster to just reload the page, but it works well with the way i
implemented the ajax-component.
>I know that Drew and probably many others are working on something similar.
>I'd like to see everyone else's approaches too. And please comment.
>
>
I use my with-ajax macro, an older version of which is available for
your viewing here : http://paste.lisp.org/display/15113. This is, by
far, the hairiest macro i've ever written, but it was so worth it :)
using it looks something like this (longhand and untested) :
(<:div :id (output-id component)
;; First 'standard' ucw html.
(<ucw:input :id (input-id component) :type "text" :accessor (number
component) :value 1)
(<ucw:input :type "submit" :id (action-id component) :action
(frob-thing-using-number component)
(<:as-html "Frob it!"))
;; Then, attach the Ajax stuff
(<ucw:script
`(progn
(setf action (document.get-element-by-id ,(action-id component)))
(action.remove-attribute "onClick")
(dojo.event.connect action "onClick"
,(with-ajax (component)
(:action (frob-thing-using-number component))
(:callback n
(setf (number component) (parse-integer n))
`(slot-value (document.get-element-by-id
,(input-id component)) value))
(:output-to (output-id component))))))
I've included a macroexpansion of the with-ajax call at the end of the
message for your reference.
I have a few convenience macros for dealing with the verbosity, and for
the most part the complexity is hidden far in generated code, but after
writing that out i think i again see the merits of the custom tag
approach as in your example, and i think i can combine the two methods
(simple tags w/ graceful degradation) without too much trouble.
I hate to see the duplication of work, so i'm wondering if you would
like to collaborate on a CL-UCW-DOJO library. I'd like to have a UCW
component/tag for each of Dojos widgets, and nice lispy functions and
macros for dealing with it in general. As it is, I think UCW is getting
too big, so i'm of the opinion that it should be a seperate library,
especially if i/you/we plan on including Dojo itself with the code.
Feel free to email me or pop into #tech.coop on freenode if you want to
talk more about this.
Cheers,
drewc
the WITH-AJAX call above macroexpands to :
(JS:WITH-UNIQUE-JS-NAMES (JS-CALLBACKS)
`(PROGN
(SETF ,JS-CALLBACKS (ARRAY))
(SETF (AREF ,JS-CALLBACKS ,0)
(LAMBDA ,NIL
(SLOT-VALUE
(DOCUMENT.GET-ELEMENT-BY-ID
,(INPUT-ID COMPONENT))
VALUE)))
(DOJO.IO.BIND
(CREATE
,@(UNLESS NIL
`(:URL
,(LISP-ON-LINES::MAKE-ACTION-URL
COMPONENT
(PROGN
(FROB-THING-USING-NUMBER
COMPONENT)
(CALL-COMPONENT
NIL
(OUTPUT-COMPONENT
SELF))))))
,@(UNLESS NIL
`(:POST-CONTENT
(+
,(IT.BESE.UCW::MAKE-NEW-CALLBACK
(LAMBDA (N)
(SETF (NUMBER COMPONENT)
(PARSE-INTEGER N))))
,"="
(ENCODE-U-R-I-COMPONENT
((AREF ,JS-CALLBACKS ,0)))
,"&")))
,@(UNLESS NIL
`(:LOAD
(LAMBDA (EVT DATA)
(SETF (SLOT-VALUE
(DOCUMENT.GET-ELEMENT-BY-ID
,(OUTPUT-ID COMPONENT))
INNER-H-T-M-L)
DATA))))
,:METHOD
,"post"))))
>Hoan
>_______________________________________________
>bese-devel mailing list
>bese-devel at common-lisp.net
>http://common-lisp.net/cgi-bin/mailman/listinfo/bese-devel
>
>
More information about the bese-devel
mailing list