From: Drew Crampsie Date: Fri, 2 Sep 2005 22:25:54 +0000 (-0700) Subject: added ajax component X-Git-Url: https://git.hcoop.net/clinton/lisp-on-lines.git/commitdiff_plain/3b18c6893106d2ed7f7bfc175210a3cca12088d4 added ajax component darcs-hash:20050902222554-5417e-537718734a739e6ed97a7311f5898c5eabe85714.gz --- diff --git a/src/components/ajax.lisp b/src/components/ajax.lisp new file mode 100644 index 0000000..fa9f2d6 --- /dev/null +++ b/src/components/ajax.lisp @@ -0,0 +1,188 @@ +(in-package :lisp-on-lines) + +;;;; for when there is nothing left to display. +(defcomponent empty-page (window-component) + ()) + +(defmethod render-on ((res response) (self empty-page)) + "didnt find a thing") + +(defcomponent auto-complete () + ((input-id :accessor input-id :initform (arnesi:random-string 10 arnesi:+ascii-alphabet+)) + (output-id :accessor output-id :initform (arnesi:random-string 10 arnesi:+ascii-alphabet+)) + (index-id :accessor index-id :initform (arnesi:random-string 10 arnesi:+ascii-alphabet+)) + (client-value :accessor client-value :initform "" :documentation "The string the user has, so far, insterted.") + (selected-value-index :accessor selected-value-index :initform nil :documentation "The index in value-list of the item selected via Ajax") + (value-list :accessor value-list :initform '()) + (values-generator :accessor values-generator :initarg :values-generator + :documentation "Function which, when passed the auto-complete component, returns a list of objects.") + (as-value :accessor as-value :initarg :as-value + :documentation "Function which, when passed a value, returns the string to put in the text box.") + (render :accessor render :initarg :render + :documentation "Function which, when passed the component and one of the values render it (the value).") + (input-size :accessor input-size :initarg :input-size :initform 20) + (submit-on-click-p :accessor submit-on-click-p :initarg :submit-on-click-p :initform t) + (output-component :accessor output-component :initarg :output-component :initform 'auto-complete-output))) + +(defmethod js-on-complete ((l auto-complete)) + `(lambda (transport) + (setf (slot-value (document.get-element-by-id ,(output-id l)) + 'inner-h-t-m-l) + transport.response-text))) + +(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)))))) + +(defmethod generate-ajax-request-for-action ((l auto-complete) &key (action-url "index.ucw")) + `(new + (*Ajax.*Request + ,action-url + (create)))) + +(defmacro with-ajax-action ((component) &body action) + `(generate-ajax-request-for-action ,component + :action-url (make-action-url ,component (progn ,@action)))) + + +(defaction call-auto-complete ((self t) auto-complete-id value) + (let ((auto-complete (get-session-value (intern auto-complete-id)))) + (if auto-complete + (call-auto-complete-from-output auto-complete auto-complete-id value self) + (call 'empty-page :message (error "ASD"))))) + +(defaction call-auto-complete-from-output ((auto-complete auto-complete) auto-complete-id value output) + (setf (client-value auto-complete) value) + (let ((self output)) + (call (output-component auto-complete) :auto-complete auto-complete) + (call 'empty-page :message (error "ASD")))) + + + +(defmethod js-on-select ((l auto-complete))) + +(defmethod render-on ((res response) (l auto-complete)) + ;; session-values are stored in an eql hash table. + (let ((input-key (intern (input-id l)))) + ;; We are storing the input components in the session, + ;; keyed on the string that we also use as the id for + ;; the input field. + + (unless (get-session-value input-key) + (setf (get-session-value input-key) l)) + + ;; A hidden field to hold the index number selected via javascript + (