[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