(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 (