Hi,<br><br>Following is a field class for select elements that allow you to select more than one options. Unless I missed something, there is no class yet for select elements like that. This could be added to components/form.lisp to implement that. BUT, you'll probably notice the really ugly hack with the hidden input whose callback grabs all the values for the select input out of the parameters. If there is a better way to run code when a request is made I'd like to hear about it, so I can make a prettier implementation.
<br><br>Maybe the callback mechanism needs some rethinking anyway? The (setf (client-value field) nil) in the render method of checkbox-field is also a case of code that should always be run before the parameters are handled, and does not really belong in a render method. Maybe add a way to register special callbacks for a form that allways run before the other callbacks? It seems forms already add a hidden variable to identify themselves, that could be used to decide which form-specific callbacks are run.
<br><br>Currently normal callbacks are not form-specific, are they? I mean, if there are two forms on a page, and both have a field called 'name', will the two callbacks for those fields coexist peacefully or will they override each other?
<br><br>Also, did you know that many xxx-field classes ignore the :name slot and just generate a random name (though make-new-callback)? Is this a bug or a feature?<br><br>Well, here's the code, for what it's worth:<br><br>
(defclass multiple-select-field (select-field)<br>  ()<br>  (:default-initargs :name (random-string 8) :client-value ()))<br><br>(defmethod render ((field multiple-select-field))<br>  (<:ai (value field))<br>  (<:input :type "hidden" :value "x"
<br>           :name (make-new-callback<br>                  (lambda (value)<br>                    (declare (ignore value))<br>                    (do ((vars (slot-value (context.request *context*) 'parameters) (cdr vars))
<br>                         (result ()))<br>                        ((null vars) (setf (client-value field) result))<br>                      (if (string= (caar vars) (name field))<br>                          (push (cdar vars) result))))))
<br>  (<:select :name (name field) :tabindex (tabindex field) :multiple t<br>            (setf (data-map field) (build-data-map field))<br>            (render-options field)))<br><br>(defmethod render-options ((field multiple-select-field))
<br>  (dolist* ((key-string . value) (data-map field))<br>    (<:option :value key-string<br>              :selected  (member key-string (client-value field) :test #'string=)<br>              (render-value field value))))
<br><br>(defmethod value ((field multiple-select-field))<br>  (mapcar (lambda (x)<br>            (cdr (assoc x (data-map field) :test #'string=)))<br>          (client-value field)))<br><br>