[Bese-devel] Temporarily storing form data
Drew Crampsie
drewc at tech.coop
Fri Nov 4 01:11:08 UTC 2005
Jan Rychter wrote:
> How would I go about saving form data when clicking on action links? I
> have a form-element based form and I'd like to provide a link for the
> user to go somewhere else to choose an image, then return to the
> form. Form data should be preserved.
You have two choices really. Fancy Javascript, or use a button instead
of a link for your image chooser.
Links do not submit forms, so the data is never transfered from the
browser when the link is clicked, and therfore there is no way to save
it serverside.
I have done this sort of thing with AJAX (using the dojo toolkit). Just
send off an async. request when the link is clicked (which submits the
form) to save the data. To do this, you'd have to know how to create
actions programmatically :
(defmacro make-action-url (component action)
"
There has got to be something like this buried in UCW somewhere,
but here's what i use."
`(ucw::print-uri-to-string
(compute-url ,component
:action-id (ucw::make-new-action (ucw::context.current-frame
*context*)
(lambda ()
(arnesi:with-call/cc
,action))))))
and then submit the form to the created action url (this is pretty easy
to do in dojo).
Eventually of course you tire of doing it manually, and come up with
monstrosities like this (And spend a hell of a lot of time counting
backticks):
(defmacro with-ajax ((component) &body args)
(multiple-value-bind (actions callbacks args output)
(loop for arg in args
if (eql (car arg) :action)
nconc (cdr arg) into actions
else if (eql (car arg) :callback)
collect (cdr arg) into callbacks
else if (eql (car arg) :output-to)
nconc (cdr arg) into output
else
nconc arg into args
finally (return (values actions callbacks args output)))
`(js:with-unique-js-names (js-callbacks)
`(progn
(setf ,js-callbacks (array))
,,@(loop for c in callbacks
for i upfrom 0
collect
``(setf (aref ,js-callbacks ,,i)
(lambda () ,,(third c))))
(dojo.io.bind
(create
,@(unless
,(getf args :url)
`(:url
,(lol::make-action-url
,component
(progn
, at actions
(call-component nil (output-component self))))))
,@ (unless
,(getf args :post-content)
`(:post-content (+ ,,@(loop for c in callbacks
for n upfrom 0
nconc `((ucw::make-new-callback
(ucw::context.current-frame *context*)
(lambda (,(car c))
,(second c)))
"="
`(encode-u-r-i-component ((aref ,js-callbacks ,,n)))
"&")))))
,@ (unless
,(or (getf args :load) (not output) )
`(:load
(lambda (evt data)
(setf (slot-value (document.get-element-by-id ,, at output)
inner-h-t-m-l) data))))
,,:method "post"
,, at args))))))
Which gets called in monstrosites like this :
(dojo.event.connect
drop "onDrop"
(lambda ()
(dolist (li list-items)
(new (dojo.dnd.*html-drag-source li ,(input-id self))))
,
(with-ajax (self)
(:action nil)
(:callback d (let ((list-order
(mapcar #'(lambda (x)
(parse-integer (subseq x (length (input-id self)))))
(read-from-string d))))
(setf (mewa::instances self) (reorder-list (mewa::instances self)
list-order)))
`(progn
(setf my-list "(")
(dolist (li list-items)
(setf my-list (+ my-list "\"" li.id "\"" " ")))
(setf my-list (+ my-list ")"))
(return my-list)))
(:load `(lambda (x data)
(setf (slot-value (document.get-element-by-id ,(input-id self))
inner-h-t-m-l) data)
(make-sortable ,(input-id self)))))))))))
I suggest using a button... it's much easier. :)
drewc
>
> --J.
> _______________________________________________
> 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