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