Commit fa458f1e authored by Gail Zacharias's avatar Gail Zacharias

update Customer User Interfaces chapter

parent 5e921167
(in-package :gwl-user)
(define-object president (base-html-sheet)
:input-slots
((name "Carter") (term 1976) (table-border 1))
:functions
((write-html-sheet
() (with-cl-who (:indent t)
(:html (:head (:title (fmt "Info on President: ~a"
(the name))))
(:body ((:table :border (the table-border))
(:tr (:th "Name") (:th "Term"))
(:tr (:td (str (the name)))
(:td (str (the term)))))))))))
;;
;; Access the above example with
;; http://localhost:9000/make?object=gwl-user::president
;;
<html>
<head>
<title>Info on President: Carter
</title>
</head>
<body>
<table border="1">
<tr> <th>Name</th>
<th>Term</th>
</tr>
<tr> <td>Carter</td>
<td>1976</td>
</tr>
</table>
</body></html>
(in-package :gwl-user)
(define-object presidents (base-html-sheet)
:input-slots
((presidents (list (list :name "Ford"
:term 1974)
(list :name "Carter"
:term 1976)
(list :name "Clinton"
:term 1992)
(list :name "Bush"
:term 2000)
(list :name "Obama"
:term 2008)))
(table-border 1))
:functions
((write-html-sheet
()
(with-cl-who (:indent t)
(let ((title (format nil "Info on ~a Presidents:"
(length (the presidents)))))
(htm
(:html
(:head (:title (str title)))
(:body
(:p (:c (:h3 (str title))))
((:table :border (the table-border))
(:tr (:th "Name") (:th "Term"))
(dolist (president (the presidents))
(htm
(:tr (:td (str (getf president :name)))
(:td (str (getf president :term)))))))))))))))
;;
;; Access the above example with
;; http://localhost:9000/make?object=gwl-user::presidents
;;
(in-package :gwl-user)
(define-object presidents-with-pages (base-html-sheet)
:input-slots
((presidents (list (list :name "Ford" :term 1974)
(list :name "Carter" :term 1976)
(list :name "Clinton" :term 1992)
(list :name "Bush" :term 2000)
(list :name "Obama" :term 2008)))
(table-border 1))
:objects
((president-pages :type 'president-page
:sequence (:size (length (the presidents)))
:name (getf (nth (the-child index) (the presidents))
:name)
:term (getf (nth (the-child index) (the presidents))
:term)))
:functions
((write-html-sheet
()
(with-cl-who (:indent t)
(let ((title (format nil "Info on ~a Presidents:"
(length (the presidents)))))
(htm
(:html
(:head (:title (str title)))
(:body
(:p (:c (:h3 (str title))))
(:ol
(dolist (page (list-elements (the president-pages)))
(htm
(:li
(the-object
page
(write-self-link :display-string
(the-object page name)))))))))))))))
;;
;; Access the above example with
;; http://localhost:9000/make?object=gwl-user::presidents-with-pages
;;
(in-package :gwl-user)
(define-object president-page (base-html-sheet)
:input-slots
(name term)
:functions
((write-html-sheet
()
(with-cl-who ()
(let ((title (format nil "Term for President ~a:"
(the name))))
(htm
(:html
(:head (:title (str title)))
(:body
(the (write-back-link :display-string "&lt;Back"))
(:p (:c (:h3 (str title))))
(:p (str (the term)))))))))))
(in-package :gwl-user)
(define-object revenue-lookup (base-ajax-sheet)
:input-slots
((revenue-data '(2003 25000
2004 34000
2005 21000
2006 37000
2007 48000
2008 54000
2009 78000)))
:computed-slots
((main-sheet-body
(with-cl-who-string ()
(str (the main-section main-div)))))
:objects
((table-border :type 'menu-form-control
:size 1
:choice-list '(0 1)
:default 0
:ajax-submit-on-change? t)
(cell-padding :type 'menu-form-control
:size 1
:choice-list '(0 3 6 9 12)
:default 0
:ajax-submit-on-change? t)
(selected-year :type 'menu-form-control
:size 1
:choice-list (plist-keys (the revenue-data))
:default (first (the-child choice-list))
:ajax-submit-on-change? t)
(main-section
:type 'sheet-section
:inner-html (with-cl-who-string ()
(:p (str (the development-links)))
(:p (str (the table-border html-string)))
(:p (str (the cell-padding html-string)))
(:p (str (the selected-year html-string)))
(:p ((:table :border (the table-border value)
:cellpadding (the cell-padding value))
(:tr (:th (fmt "Revenue for Year ~a:"
(the selected-year value)))
(:td (str (getf (the revenue-data)
(the selected-year value)))))))))))
(publish-gwl-app "/revenue-lookup"
"gwl-user::revenue-lookup")
(in-package :gwl-user)
(define-object x3dom-basic (base-ajax-sheet)
:computed-slots
((use-raphael? t)
(use-x3dom? t)
(main-sheet-body
(with-cl-who-string ()
(:p (when *developing?* (str (the development-links))))
(:p (str (the inputs-section main-div)))
(:table
(:tr
(dolist (viewport (list (the (viewport-sections 1))))
(htm (:td (:td (str (the-object viewport main-div)))))))))))
:objects
((box :type 'box
:display-controls (list :color :blue :transparency 0.2)
:height (the inputs-section box-height value)
:width (the inputs-section box-width value)
:length (the inputs-section box-length value))
(inputs-section :type 'inputs-section)
(viewport-sections
:type 'base-ajax-graphics-sheet
:sequence (:size 2)
:view-direction-default (ecase (the-child index)
(0 :top) (1 :trimetric))
:image-format-default :raphael
:display-list-objects (list (the box))
:length 500 :width 500)))
(define-object inputs-section (sheet-section)
:computed-slots
((inner-html (with-cl-who-string ()
(:p (str (the box-length html-string)))
(:p (str (the box-width html-string)))
(:p (str (the box-height html-string))))))
:objects
((box-length :type 'text-form-control
:default 25
:ajax-submit-on-change? t)
(box-width :type 'text-form-control
:default 35
:ajax-submit-on-change? t)
(box-height :type 'text-form-control
:default 45
:ajax-submit-on-change? t)))
(publish-gwl-app "/x3dom-basic"
"gwl-user::box-one-viewport")
;;
;; Access the above example with
;; http://localhost:9000/make?object=gwl-user::box-with-inputs
;;
(in-package :gwl-user)
;; http://localhost:9000/make?object=gwl-user::hello-world-ajax
(define-object hello-world-ajax (base-ajax-sheet)
:input-slots
((greetings '("Hello"
"Hola"
"Bonjour"
"Habari"
"Namaste"
"Aloha"
"Ciao")))
:objects
((username-control :type 'text-form-control
:prompt "Enter new name: "
:default "World"
:ajax-submit-on-change? t)
(greeting-control :type 'menu-form-control
:prompt "Select Greeting: "
:size 1 :choice-list (the greetings)
:default (first (the greetings))
:ajax-submit-on-change? t)
(main-section
:type 'sheet-section
:inner-html (with-cl-who-string ()
(:p (fmt "~a ~a!" (the greeting-control value) (the username-control value)))
(:hr)
(with-html-form (:cl-who? t)
(:p (str (the greeting-control html-string)))
(:p (str (the username-control html-string)))))))
:computed-slots
((title (format nil "Greeting for ~a" (the username-control value)))
(main-sheet-body
(with-cl-who-string ()
(str (the main-section main-div))))))
(in-package :gwl-user)
;; http://localhost:9000/make?object=gwl-user::hello-world-controls
(define-object hello-world-controls (base-ajax-sheet)
:input-slots
((greetings '("Hello"
"Hola"
"Bonjour"
"Habari"
"Namaste"
"Aloha"
"Ciao")))
:objects
((username-control :type 'text-form-control
:prompt "Enter new name: "
:default "World")
(greeting-control :type 'menu-form-control
:prompt "Select Greeting: "
:size 1 :choice-list (the greetings)
:default (first (the greetings))))
:computed-slots
((title (format nil "Greeting for ~a" (the username-control value)))
(main-sheet-body
(with-cl-who-string ()
(:p (fmt "~a ~a!" (the greeting-control value) (the username-control value)))
(:hr)
(with-html-form (:cl-who? t)
(:p (str (the greeting-control html-string)))
(:p (str (the username-control html-string)))
(:p (:button :type :submit "UPDATE")))))))
(in-package :gwl-user)
;; http://localhost:9000/make?object=gwl-user::hello-world-form
(define-object hello-world-form (base-ajax-sheet)
:input-slots
((greetings '("Hello"
"Hola"
"Bonjour"
"Habari"
"Namaste"
"Aloha"
"Ciao")))
:computed-slots
((username "World" :settable)
(greeting (first (the greetings)) :settable)
(title (format nil "Greeting for ~a" (the username)))
(main-sheet-body
(with-cl-who-string ()
(:p (fmt "~a ~a!" (the greeting) (the username)))
(:hr)
(with-html-form (:cl-who? t)
(:p
(:label :for 'greeting "Select greeting: ")
((:select :name 'greeting)
(dolist (val (the greetings))
(with-cl-who ()
((:option :value val
:selected (and (equalp val (the greeting)) "selected"))
(esc val))))))
(:p
(:label :for 'username "Enter new name: ")
(:input :type :text :name 'username :value (the username)))
(:p (:button :type :submit "UPDATE")))))))
\ No newline at end of file
(in-package :gwl-user)
;; http://localhost:9000/make?object=gwl-user::hello-world
(define-object hello-world (base-ajax-sheet)
:computed-slots
((main-sheet-body
(with-cl-who-string ()
(:p "Hello World!")))))
(in-package :gwl-user)
(define-object president-page (base-ajax-sheet)
:input-slots
(name term)
:computed-slots
((title
(format nil "Term for President ~a:" (the name)))
(main-sheet-body
(with-cl-who-string (:indent t)
(the (write-back-link :display-string "&lt;Back"))
(:p (:c (:h3 (the title))))
(:p (str (the term)))))))
;; http://localhost:9000/make?object=gwl-user::presidents-with-links
(define-object presidents-with-links (base-ajax-sheet)
:input-slots
((data (list (list :name "Carter" :term 1976)
(list :name "Reagan" :term 1980)
(list :name "Bush" :term 1988)
(list :name "Clinton" :term 1992)))
(table-border 1))
:objects
((presidents :type 'president-page
:sequence (:size (length (the data)))
:name (getf (nth (the-child index) (the data)) :name)
:term (getf (nth (the-child index) (the data)) :term)))
:computed-slots
((title (format nil "Links to ~a Presidents:"
(length (list-elements (the presidents)))))
(main-sheet-body
(with-cl-who-string (:indent t)
(htm
(:p (:c (:h3 (the title))))
((:table :border (the table-border))
(:tr (:th "Name"))
(dolist (president (list-elements (the presidents)))
(htm
(:tr (:td (the-object
president
(write-self-link :display-string
(the-object president name)))))))))))))
(in-package :gwl-user)
(define-object president ()
:input-slots
(name term))
;; http://localhost:9000/make?object=gwl-user::presidents
(define-object presidents (base-ajax-sheet)
:input-slots
((data (list (list :name "Carter" :term 1976)
(list :name "Reagan" :term 1980)
(list :name "Bush" :term 1988)
(list :name "Clinton" :term 1992))))
:objects
((presidents :type 'president
:sequence (:size (length (the data)))
:name (getf (nth (the-child index) (the data)) :name)
:term (getf (nth (the-child index) (the data)) :term)))
:computed-slots
((main-sheet-body
(with-cl-who-string (:indent t)
(htm
(:p (:c (:h3 (fmt "Info on ~a Presidents:"
(length (list-elements (the presidents)))))))
((:table :border 1)
(:tr (:th "Name") (:th "Term"))
(dolist (president (list-elements (the presidents)))
(htm
(:tr (:td (str (the-object president name)))
(:td (str (the-object president term))))))))))))
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -37,520 +37,309 @@ GDL does not provide specific support for them.")
". Using the same "
(:texttt "define-object")
" syntax which you have already encountered, you can define
web pages, sections of web pages, and "
(:emph "form control")
" elements such as type-in fields, checkboxes, and choice
lists [using this capability does require a basic working knowledge of
the HTML language]."
(:footnote "We will not cover HTML in this manual, but
plentiful resources are available online and in print.")
".")
(:p "Any web extensions such as custom JavaScript and JavaScript libraries
can also be used, as with any standard web application.")
web pages, sections of web pages, and form elements.
Your UI elements generate standard HTML, CSS, JavaScript, and can use
any external client-side libraries as with any standard web application. AJAX support is
built-in, making it easy for server and UI elements to communicate asynchronously."
)
(:p "In order to create a web application in GDL, you should have a working
knowledge of the semantics of HTML, for which many explanations are available
online and in print. For syntax, you can use an HTML-generation library such as "
(:href "http://weitz.de/cl-who" "CL-WHO") (:footnote "http://weitz.de/cl-who")
" or "
(:href "http://www.franz.com/support/documentation/current/doc/aserve/htmlgen.html" "HTMLGen")
(:footnote "http://www.franz.com/support/documentation/current/doc/aserve/htmlgen.html")
", both of which are built into GDL. In this tutorial we will use CL-WHO, so in what folows,
we will assume that you are already familiar with its features as documented in "
(:href "http://weitz.de/cl-who" "http://weitz.de/cl-who") ".")
(:p "With the primitive objects and functions in its "
(:texttt ":gwl")
" package, GDL supports both the traditional ``Web 1.0''
interfaces (with fillout forms, page submittal, and complete page
refresh) as well as so-called ``Web 2.0'' interaction with AJAX.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
((:section :title "Package and Environment for Web Development")
(:p "The "(:texttt ":gwl")" package"(:footnote "The acronym \"GWL\" stands
for Generative Web Language")" contains a set of primitive objects and functions provided by
GDL for building web applications.")
((:section :title "Package and Environment for Web Development")
(:p "Similarly to " (:texttt "gdl:define-package") ", you can use "
(:texttt "gwl:define-package") " in order to create a working
package which has access to the symbols you will need for building a
(:p "Similarly to "(:texttt "gdl:define-package")", you can use "(:texttt "gwl:define-package")"
to create a working package which has access to the symbols you will need for building a
web application (in addition to the other GDL symbols).")
(:p "The " (:texttt ":gwl-user") " package is pre-defined and may be used for practice
work. For real projects, you should define your own package using "
(:texttt "gwl:define-package") ".")
(:p "The acronym ``GWL'' stands for Generative Web Language,
which is not a separate language from GDL itself, but rather is a set
of primitive objects and functions available within GDL for building
web applications. The YADD reference documentation for package
``Generative Web Language'' provides detailed specifications for all
the primitive objects and functions."))
((:section :title "Traditional Web Pages and Applications")
(:p "To make a GDL object presentable as a web page, the following two
steps are needed:"
((:list :style :enumerate)
(:item "Mix " (:texttt "base-html-sheet") " into the object definition.")
(:item "define a GDL function called " (:texttt "main-sheet") " within the object definition."))
"The " (:texttt "main-sheet") " function should return valid
HTML for the page. The easiest way to produce HTML is with the use of
an HTML generating library, such as "
(:href "http://weitz.de/cl-who" "CL-WHO")
(:footnote "http://weitz.de/cl-who")
" or "
(:href "http://www.franz.com/support/documentation/current/doc/aserve/htmlgen.html" "HTMLGen")
(:footnote "http://www.franz.com/support/documentation/current/doc/aserve/htmlgen.html")
", both of which are built into GDL.")
(:p "For our examples we will use cl-who, which is currently the
standard default HTML generating library used internally by GDL. Here
we will make note of the major features of cl-who while introducing
the examples. For complete documentation on cl-who, please visit the
page at Edi Weitz' website linked above and listed in the footnote
below.")
((:subsection :title "A Simple Static Page Example")
(:p "In Figure "
(:ref "fig:gwl-1")
", GWL convenience macro "
(:texttt "with-cl-who")
" is used; this sets up a standard default environment for outputting HTML
within a GWL application."
((:boxed-figure :caption "Simple Static Page Example" :label "fig:gwl-1")
(:verbatim
(:include "~/gendl/documentation/tutorial/examples/gwl-1.gdl"))))
(:p "The code in Figure "
(:ref "fig:gwl-1")
" produces HTML output as shown in Figure "
(:ref "fig:gwl-1-html")
" which looks similar to Figure "
(:ref "fig:gwl-1-image")
" in a web browser."
((:boxed-figure :caption "Simple Static Page Example" :label "fig:gwl-1-html")
(:verbatim
(:include "~/gendl/documentation/tutorial/examples/gwl-1.html")))
((:image-figure :image-file "gwl-1.png" :caption "Simple Static Page Example"
:width "4in" :height "3in"
:label "fig:gwl-1-image")))
(:p "Several important concepts are lumped into this
example. Note the following:"
((:list :style :itemize)
(:p "The "(:texttt ":gwl-user")" package is pre-defined and may be used for practice
work. For real projects, you should define your own package using "(:texttt "gwl:define-package")".")
(:item "Our convenience macro "
(:texttt "with-cl-who")
" is used to wrap the native "
(:texttt "with-html-output")
" macro which comes with the cl-who library.")
(:item "We use the keyword argument "
(:texttt ":indent t")
" in order to pretty-print the generated HTML. This does
not affect the browser display but can make the generated HTML
easier to read and debug. This option should be left as nil (the
default) for production deployments.")
(:item "The " (:texttt "fmt") " symbol has special meaning
within the cl-who environment and works the same as a Common
Lisp " (:texttt "(format nil ...)") " in order to evaluate a format
string together with matching arguments, and produce a string at
runtime.")
(:item "The " (:texttt "str") " symbol has special meaning
within the cl-who environment and works by evaluating an
expression at runtime to return a string or other printable
object, which is then included at that point in the HTML output.")
(:item "Expressions within the "
(:texttt "body") " of an
HTML tag have to be evaluated, usually by use of the "
(:texttt "fmt")
" or "
(:texttt "str")
" in cl-who. There are three examples of this in the
above sample: one "
(:texttt "fmt")
" and two "
(:texttt "str")