diff --git a/README.md b/README.md index d49a885..a03edf4 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ Tutorial Summary - 14-tutorial.lisp - Local (persistent) and Session client-side storage - 15-tutorial.lisp - Multi-media - 16-tutorial.lisp - Bootstrap 4, Loading css files and javascript +- 17-tutorial.lisp - W3.CSS layout example and Form submit methods Demo Summary diff --git a/clog-form.lisp b/clog-form.lisp index 1180167..4330e48 100644 --- a/clog-form.lisp +++ b/clog-form.lisp @@ -21,7 +21,9 @@ ;; create-form ;; ;;;;;;;;;;;;;;;;; -(defgeneric create-form (clog-obj &key action method target auto-place) +(deftype from-method-type () '(members :get :post :none)) + +(defgeneric create-form (clog-obj &key action method target class auto-place) (:documentation "Create a new CLOG-Form as child of CLOG-OBJ that organizes a collection of form elements in to a single form if :AUTO-PLACE (default t) place-inside-bottom-of CLOG-OBJ. In CLOG a form's on-submit handler should be @@ -32,12 +34,20 @@ set an on-submit handler or call (submit CLOG-FORM) to perform the form action.")) (defmethod create-form ((obj clog-obj) - &key (action "") - (method "get") + &key (action "#") + (method :none) (target "_self") + (class nil) (auto-place t)) - (create-child obj (format nil "
" - action method target) + (create-child obj (format nil "" + action + (if (eq method :none) + "onSubmit='return false;'" + (format nil "method='~A'" method)) + target + (if class + (format nil " class='~A'" (escape-string class)) + "")) :clog-type 'clog-form :auto-place auto-place)) ;;;;;;;;;;;;;;;;;;;;;;;; @@ -346,7 +356,8 @@ group called NAME.")) ;;;;;;;;;;;;;;;; (defgeneric name-value (clog-obj name) - (:documentation "Returns the value of input item called NAME.")) + (:documentation "Returns the value of input item called NAME and must +be unique name on entire document.")) (defmethod name-value ((obj clog-obj) name) (cc:query (connection-id obj) @@ -629,7 +640,7 @@ virtual keyboards.")) (:documentation "Set label is for ELEMENT.")) (defmethod label-for ((obj clog-label) element) - (setf (attribute obj "for") element)) + (setf (attribute obj "for") (html-id element))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/clog.lisp b/clog.lisp index 96565dd..843b212 100644 --- a/clog.lisp +++ b/clog.lisp @@ -379,6 +379,7 @@ embedded in a native template application.)" (defsection @clog-form (:title "CLOG Form Objects") "CLOG-Form - Class for organizing Form Elements in to a From" + (form-method-type type) (clog-form class) (create-form generic-function) diff --git a/tutorial/11-tutorial.lisp b/tutorial/11-tutorial.lisp index a488d00..8fa01f3 100644 --- a/tutorial/11-tutorial.lisp +++ b/tutorial/11-tutorial.lisp @@ -50,7 +50,13 @@ ;; Bootstrap specific markup (setf (css-class-name alert-div) "alert alert-success") (setf (attribute alert-div "role") "alert") - + + ;; We collect the data from the hidden form elements + ;; using radio-value and name-value (for other types if + ;; input other than radio buttons) or we could bind each + ;; control (using ATTACH-AS-CHILD)and seek their value + ;; directly. See tutorial 17 and to deal with forms in + ;; the old html page model of "put" and "get" (setf (inner-html alert-div) (format nil "
radios value : ~A

textinput value : ~A

" diff --git a/tutorial/16-tutorial.lisp b/tutorial/16-tutorial.lisp index 8f3b6f7..8fe8bec 100644 --- a/tutorial/16-tutorial.lisp +++ b/tutorial/16-tutorial.lisp @@ -6,9 +6,6 @@ ;; In previous tutorials we attached to an html file using bootstrap. For this tutorial we ;; are going to create a bootstrap 4.0 page just using CLOG. -;; -;; You should also check out a CSS only alternative to bootsrap - -;; https://www.w3schools.com/w3css/default.asp (defun on-index (body) (load-css (html-document body) "https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css") diff --git a/tutorial/17-tutorial.lisp b/tutorial/17-tutorial.lisp new file mode 100644 index 0000000..eaa8411 --- /dev/null +++ b/tutorial/17-tutorial.lisp @@ -0,0 +1,90 @@ +(defpackage #:clog-user + (:use #:cl #:clog) + (:export start-tutorial)) + +(in-package :clog-user) + +;; In this tutorial we will use a CSS only alternative to bootsrap - +;; https://www.w3schools.com/w3css/default.asp +;; +;; In this case we will use the mobile themes + +(defun on-index (body) + (load-css (html-document body) "https://www.w3schools.com/w3css/4/w3pro.css") + (load-css (html-document body) "https://www.w3schools.com/lib/w3-theme-teal.css") + (setf (title (html-document body)) "Hello W3.CSS") + + (let* ((header (create-section body :header :class "w3-container w3-card w3-theme")) + (tmp (create-section header :h1 :content "Explore Forms")) + + (tmp (create-hr body)) + + ;; This is a traditional "post" form that will submit data + ;; to a server. + (fcontainer (create-div body :class "w3-container")) + (tmp (create-section fcontainer :h2 :content "Post Form")) + (tmp (create-br fcontainer)) + (form1 (create-form fcontainer :method :post :action "/page2")) + (finput (create-form-element form1 :input :name "yourname" :label + (create-label form1 :content "Enter name:"))) + (fsubmit (create-form-element form1 :submit)) + (tmp (create-br fcontainer)) + + (tmp (create-hr body)) + + ;; This is a traditional "put" form that will submit data + ;; to a server. + (fcontainer (create-div body :class "w3-container")) + (tmp (create-section fcontainer :h2 :content "Get Form")) + (tmp (create-br fcontainer)) + (form2 (create-form fcontainer :method :get :action "/page3")) + (finput (create-form-element form2 :input :name "yourname" :label + (create-label form2 :content "Enter name:"))) + (fsubmit (create-form-element form2 :submit)) + (tmp (create-br fcontainer)) + + (tmp (create-hr body)) + + ;; This is a CLOG style form, instead of submitting data + ;; to another page it is dealt with in place. + (fcontainer (create-div body :class "w3-container")) + (tmp (create-section fcontainer :h2 :content "CLOG Style Form")) + (tmp (create-br fcontainer)) + (form3 (create-form fcontainer)) + (finput3 (create-form-element form3 :input :name "yourname3" :label + (create-label form3 :content "Enter name:"))) + (fsubmit3 (create-form-element form3 :submit)) + (tmp (create-br fcontainer)) + + (tmp (create-hr body)) + + (footer (create-section body :footer :class "w3-container w3-theme")) + (tmp (create-section footer :p :content "(c) All's well that ends well"))) + + (set-on-click fsubmit3 + (lambda (obj) + (place-before footer + (create-div body :content (format nil "yourname3 = ~A or ~A" + (name-value form3 "yourname3") + (value finput3))))))) + + (run body)) + +(defun on-page2 (body) + (create-db body :content "POST currently unsupported to a CLOG server app.") + (run body)) + +(defun on-page3 (body) + (let ((params (quri:uri-query-params (quri:uri (url (location body)))))) + (create-div body :content params) + (create-div body :content (format nil "yourname = ~A" + (cdr (assoc "yourname" params :test #'equalp))))) + (run body)) + +(defun start-tutorial () + "Start turtorial." + + (initialize #'on-index) + (set-on-new-window #'on-page2 :path "/page2") + (set-on-new-window #'on-page3 :path "/page3") + (open-browser)) diff --git a/tutorial/README.md b/tutorial/README.md index bf0a6db..9510b36 100644 --- a/tutorial/README.md +++ b/tutorial/README.md @@ -49,3 +49,4 @@ Tutorial Summary - 14-tutorial.lisp - Local (persistent) and Session client side storage - 15-tutorial.lisp - Multi-media - 16-tutorial.lisp - Bootstrap 4, Loading css files and javascript +- 17-tutorial.lisp - W3.CSS layout example and Form submit methods