conditional attributes in html-generator
authorHenrik Hjelte <henrik@evahjelte.com>
Mon, 15 Jan 2007 14:19:48 +0000 (14:19 +0000)
committerHenrik Hjelte <henrik@evahjelte.com>
Mon, 15 Jan 2007 14:19:48 +0000 (14:19 +0000)
docs/manual.pdf
docs/reference.lisp
src/js-html.lisp

index 97b4146..bad6b98 100644 (file)
Binary files a/docs/manual.pdf and b/docs/manual.pdf differ
index eaa45f3..ed1d405 100644 (file)
@@ -894,6 +894,23 @@ a-variable  => aVariable
   => document.write
      ('<a href=\"#\" onclick=\"' + 'javascript:transport();' + '\">link</a>')
 
+;;; Forms may be used in attribute lists to conditionally generate
+;;; the next attribute. In this example the textarea is sometimes disabled.
+
+(let ((disabled nil)
+      (authorized t))
+   (setf element.inner-h-t-m-l
+         (html ((:textarea (or disabled (not authorized)) :disabled "disabled")
+                "Edit me"))))
+  =>  {
+        var disabled = null;
+        var authorized = true;
+        element.innerHTML =
+        '<textarea'
+        + (disabled || !authorized ? ' disabled=\"' + 'disabled' + '\"' : '')
+        + '>Edit me</textarea>';
+      }
+
 ; (CSS-INLINE css-expression)
 
 ;;; Stylesheets can also be created in ParenScript.
index 5bfda60..3c068a2 100644 (file)
 (defun process-html-forms (forms)
   (let (res)
     (labels ((handle-form (form)
-            (cond ((keywordp form)
-                   (push (format nil "<~A/>"
-                                 (string-downcase (symbol-name form))) res))
+               (cond ((keywordp form)
+                      (push (format nil "<~A/>"
+                                    (string-downcase (symbol-name form))) res))
 
-                  ((atom form)
-                   (push form res))
+                     ((atom form)
+                      (push form res))
 
-                  ((and (consp form)
-                        (keywordp (first form)))
-                   (let ((node-name (string-downcase (symbol-name (first form)))))
-                     (push (format nil "<~A>" node-name) res)
-                     (map nil #'handle-form (cdr form))
-                     (push (format nil "</~A>" node-name) res)))
+                     ((and (consp form)
+                           (keywordp (first form)))
+                      (let ((node-name (string-downcase (symbol-name (first form)))))
+                        (push (format nil "<~A>" node-name) res)
+                        (map nil #'handle-form (cdr form))
+                        (push (format nil "</~A>" node-name) res)))
 
-                  ((and (consp form)
-                        (consp (first form))
-                        (keywordp (caar form)))
-                   (let ((node-name (string-downcase (symbol-name (caar form)))))
-                     (push (format nil "<~A" node-name) res)
-                     (loop for (attr-name attr-val) on (cdar form) by #'cddr
-                           do (unless (keywordp attr-name)
-                                (error "~A is not a node attribute" attr-name))
-                           (push (format nil " ~A=\"" (string-downcase (symbol-name attr-name)))
-                                 res)
-                           (push attr-val res)
-                           (push "\"" res))
-                     (push ">" res)
-                     (map nil #'handle-form (cdr form))
-                     (push (format nil "</~A>" node-name) res)))
+                     ((and (consp form)
+                           (consp (first form))
+                           (keywordp (caar form)))
+                      (let ((node-name (string-downcase (symbol-name (caar form)))))
+                        (push (format nil "<~A" node-name) res)
 
-                  ((consp form)
-                   (push form res)))))
+                        (loop with attrs = (cdar form)
+                              while attrs
+                              for attr-name = (pop attrs)
+                              for attr-test = (when (not (keywordp attr-name))
+                                                (let ((test attr-name))
+                                                  (setf attr-name (pop attrs))
+                                                  test))
+                              for attr-val = (pop attrs)
+                              do
+                              (if attr-test
+                                  (push `(if ,attr-test
+                                          (+ ,(format nil " ~A=\"" (string-downcase (symbol-name attr-name)))
+                                           ,attr-val
+                                           "\"")
+                                          "")
+                                        res)
+                                  (progn 
+                                    (push (format nil " ~A=\"" (string-downcase (symbol-name attr-name)))
+                                          res)
+                                    (push attr-val res)
+                                    (push "\"" res))))
+                        (push ">" res)
+                        (map nil #'handle-form (cdr form))
+                        (push (format nil "</~A>" node-name) res)))
+
+                     ((consp form)
+                      (push form res)))))
       (map nil #'handle-form forms))
     (cons '+ (optimize-string-list (nreverse res)))))