picolisp

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/picolisp.git/
Log | Files | Refs | README | LICENSE

app.html (96992B)


      1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/1998/REC-html40-19980424/loose.dtd">
      2 <html lang="en">
      3 <head>
      4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      5 <title>PicoLisp Application Development</title>
      6 <link rel="stylesheet" href="doc.css" type="text/css">
      7 </head>
      8 <body>
      9 <a href="mailto:abu@software-lab.de">abu@software-lab.de</a>
     10 
     11 <h1>PicoLisp Application Development</h1>
     12 
     13 <p align=right>(c) Software Lab. Alexander Burger
     14 
     15 <p>This document presents an introduction to writing browser-based applications
     16 in PicoLisp.
     17 
     18 <p>It concentrates on the XHTML/CSS GUI-Framework (as opposed to the previous
     19 Java-AWT, Java-Swing and Plain-HTML frameworks), which is easier to use, more
     20 flexible in layout design, and does not depend on plug-ins, JavaScript, cookies
     21 or CSS.
     22 
     23 <p>A plain HTTP/HTML GUI has various advantages: It runs on any browser, and can
     24 be fully driven by scripts ("@lib/scrape.l").
     25 
     26 <p>To be precise: CSS <i>can</i> be used to enhance the layout. And browsers
     27 <i>with</i> JavaScript will respond faster and smoother. But this framework
     28 works just fine in browsers which do not know anything about CSS or JavaScript.
     29 All examples were also tested using the w3m text browser.
     30 
     31 <p>For basic informations about the PicoLisp system please look at the <a
     32 href="ref.html">PicoLisp Reference</a> and the <a href="tut.html">PicoLisp
     33 Tutorial</a>. Knowledge of HTML, and a bit of CSS and HTTP is assumed.
     34 
     35 <p>The examples assume that PicoLisp was started from a global installation (see
     36 <a href="ref.html#inst">Installation</a>).
     37 
     38 <p><ul>
     39 <li><a href="#static">Static Pages</a>
     40    <ul>
     41    <li><a href="#hello">Hello World</a>
     42       <ul>
     43       <li><a href="#server">Start the application server</a>
     44       <li><a href="#how">How does it work?</a>
     45       </ul>
     46    <li><a href="#urlSyntax">URL Syntax</a>
     47    <li><a href="#security">Security</a>
     48       <ul>
     49       <li><a href="#pw">The ".pw" File</a>
     50       </ul>
     51    <li><a href="#htmlFoo">The <code>html</code> Function</a>
     52    <li><a href="#cssAttr">CSS Attributes</a>
     53    <li><a href="#tags">Tag Functions</a>
     54       <ul>
     55       <li><a href="#simple">Simple Tags</a>
     56       <li><a href="#lists">(Un)ordered Lists</a>
     57       <li><a href="#tables">Tables</a>
     58       <li><a href="#menus">Menus and Tabs</a>
     59       </ul>
     60    </ul>
     61 <li><a href="#forms">Interactive Forms</a>
     62    <ul>
     63    <li><a href="#sessions">Sessions</a>
     64    <li><a href="#actionForms">Action Forms</a>
     65       <ul>
     66       <li><a href="#guiFoo">The <code>gui</code> Function</a>
     67       <li><a href="#ctlFlow">Control Flow</a>
     68       <li><a href="#switching">Switching URLs</a>
     69       <li><a href="#dialogs">Alerts and Dialogs</a>
     70       <li><a href="#calc">A Calculator Example</a>
     71       </ul>
     72    <li><a href="#charts">Charts</a>
     73       <ul>
     74       <li><a href="#scrolling">Scrolling</a>
     75       <li><a href="#putGet">Put and Get Functions</a>
     76       </ul>
     77    </ul>
     78 <li><a href="#guiClasses">GUI Classes</a>
     79    <ul>
     80    <li><a href="#inputFields">Input Fields</a>
     81       <ul>
     82       <li><a href="#numberFields">Numeric Input Fields</a>
     83       <li><a href="#timeDateFields">Time &amp; Date</a>
     84       <li><a href="#telFields">Telephone Numbers</a>
     85       <li><a href="#checkboxes">Checkboxes</a>
     86       </ul>
     87    <li><a href="#fieldPrefix">Field Prefix Classes</a>
     88       <ul>
     89       <li><a href="#initPrefix">Initialization</a>
     90       <li><a href="#ablePrefix">Disabling and Enabling</a>
     91       <li><a href="#formatPrefix">Formatting</a>
     92       <li><a href="#sideEffects">Side Effects</a>
     93       <li><a href="#validPrefix">Validation</a>
     94       <li><a href="#linkage">Data Linkage</a>
     95       </ul>
     96    <li><a href="#buttons">Buttons</a>
     97       <ul>
     98       <li><a href="#dialogButtons">Dialog Buttons</a>
     99       <li><a href="#jsButtons">Active JavaScript</a>
    100       </ul>
    101    </ul>
    102 <a name="minAppRef"></a>
    103 <li><a href="#minApp">A Minimal Complete Application</a>
    104    <ul>
    105    <li><a href="#getStarted">Getting Started</a>
    106       <ul>
    107       <li><a href="#localization">Localization</a>
    108       <li><a href="#navigation">Navigation</a>
    109       <li><a href="#choosing">Choosing Objects</a>
    110       <li><a href="#editing">Editing</a>
    111       <li><a href="#btnLinks">Buttons vs. Links</a>
    112       </ul>
    113    <li><a href="#dataModel">The Data Model</a>
    114    <li><a href="#usage">Usage</a>
    115       <ul>
    116       <li><a href="#cuSu">Customer/Supplier</a>
    117       <li><a href="#item">Item</a>
    118       <li><a href="#order">Order</a>
    119       <li><a href="#reports">Reports</a>
    120       </ul>
    121    <li><a href="#bugs">Bugs</a>
    122    </ul>
    123 </ul>
    124 
    125 
    126 <p><hr>
    127 <h2><a name="static">Static Pages</a></h2>
    128 
    129 <p>You can use PicoLisp to generate static HTML pages. This does not make much
    130 sense in itself, because you could directly write HTML code as well, but it
    131 forms the base for interactive applications, and allows us to introduce the
    132 application server and other fundamental concepts.
    133 
    134 <p><hr>
    135 <h3><a name="hello">Hello World</a></h3>
    136 
    137 <p>To begin with a minimal application, please enter the following two lines
    138 into a generic source file named "project.l" in the PicoLisp installation
    139 directory.
    140 
    141 <pre><code>
    142 ########################################################################
    143 (html 0 "Hello" "@lib.css" NIL
    144    "Hello World!" )
    145 ########################################################################
    146 </code></pre>
    147 
    148 <p>(We will modify and use this file in all following examples and experiments.
    149 Whenever you find such a program snippet between hash ('#') lines, just copy and
    150 paste it into your "project.l" file, and press the "reload" button of your
    151 browser to view the effects)
    152 
    153 
    154 <h4><a name="server">Start the application server</a></h4>
    155 
    156 <p>Open a second terminal window, and start a PicoLisp application server
    157 
    158 <pre><code>
    159 $ pil @lib/http.l @lib/xhtml.l @lib/form.l  --server 8080 project.l  +
    160 </code></pre>
    161 
    162 <p>No prompt appears. The server just sits, and waits for connections. You can
    163 stop it later by hitting <code>Ctrl-C</code> in that terminal, or by executing
    164 '<code>killall pil</code>' in some other window.
    165 
    166 <p>(In the following, we assume that this HTTP server is up and running)
    167 
    168 <p>Now open the URL '<code><a
    169 href="http://localhost:8080">http://localhost:8080</a></code>' with your
    170 browser. You should see an empty page with a single line of text.
    171 
    172 
    173 <h4><a name="how">How does it work?</a></h4>
    174 
    175 <p>The above line loads the debugger (via the '+' switch), the HTTP server code
    176 ("@lib/http.l"), the XHTML functions ("@lib/xhtml.l") and the input form
    177 framework ("@lib/form.l", it will be needed later for <a
    178 href="#forms">interactive forms</a>).
    179 
    180 <p>Then the <code>server</code> function is called with a port number and a
    181 default URL. It will listen on that port for incoming HTTP requests in an
    182 endless loop. Whenever a GET request arrives on port 8080, the file "project.l"
    183 will be <code><a href="refL.html#load">(load)</a></code>ed, causing the
    184 evaluation (= execution) of all its Lisp expressions.
    185 
    186 <p>During that execution, all data written to the current output channel is sent
    187 directly to to the browser. The code in "project.l" is responsible to produce
    188 HTML (or anything else the browser can understand).
    189 
    190 
    191 <p><hr>
    192 <h3><a name="urlSyntax">URL Syntax</a></h3>
    193 
    194 <p>The PicoLisp application server uses a slightly specialized syntax when
    195 communicating URLs to and from a client. The "path" part of an URL - which
    196 remains when
    197 
    198 <p><ul>
    199 <li>the preceding protocol, host and port specifications,
    200 <li>and the trailing question mark plus arguments
    201 </ul>
    202 
    203 are stripped off - is interpreted according so some rules. The most prominent
    204 ones are:
    205 
    206 <p><ul>
    207 <li>If a path starts with an exclamation-mark ('!'), the rest (without the '!')
    208 is taken as the name of a Lisp function to be called. All arguments following
    209 the question mark are passed to that function.
    210 
    211 <li>If a path ends with ".l" (a dot and a lower case 'L'), it is taken as a Lisp
    212 source file name to be <code><a href="refL.html#load">(load)</a></code>ed. This
    213 is the most common case, and we use it in our example "project.l".
    214 
    215 <li>If the extension of a file name matches an entry in the global mime type
    216 table <code>*Mimes</code>, the file is sent to the client with mime-type and
    217 max-age values taken from that table.
    218 
    219 <li>Otherwise, the file is sent to the client with a mime-type of
    220 "application/octet-stream" and a max-age of 1 second.
    221 
    222 </ul>
    223 
    224 <p>An application is free to extend or modify the <code>*Mimes</code> table with
    225 the <code>mime</code> function. For example
    226 
    227 <pre><code>
    228 (mime "doc" "application/msword" 60)
    229 </code></pre>
    230 
    231 <p>defines a new mime type with a max-age of one minute.
    232 
    233 <p>Argument values in URLs, following the path and the question mark, are
    234 encoded in such a way that Lisp data types are preserved:
    235 
    236 <p><ul>
    237 <li>An internal symbol starts with a dollar sign ('$')
    238 <li>A number starts with a plus sign ('+')
    239 <li>An external (database) symbol starts with dash ('-')
    240 <li>A list (one level only) is encoded with underscores ('_')
    241 <li>Otherwise, it is a transient symbol (a plain string)
    242 
    243 </ul>
    244 
    245 <p>In that way, high-level data types can be directly passed to functions
    246 encoded in the URL, or assigned to global variables before a file is loaded.
    247 
    248 
    249 <p><hr>
    250 <h3><a name="security">Security</a></h3>
    251 
    252 <p>It is, of course, a huge security hole that - directly from the URL - any
    253 Lisp source file can be loaded, and any Lisp function can be called. For that
    254 reason, applications must take care to declare exactly which files and functions
    255 are to be allowed in URLs. The server checks a global variable <code><a
    256 href="refA.html#*Allow">*Allow</a></code>, and - when its value is
    257 non-<code>NIL</code> - denies access to anything that does not match its
    258 contents.
    259 
    260 <p>Normally, <code>*Allow</code> is not manipulated directly, but set with the
    261 <code><a href="refA.html#allowed">allowed</a></code> and <code><a
    262 href="refA.html#allow">allow</a></code> functions
    263 
    264 <pre><code>
    265 (allowed ("app/")
    266    "!start" "!stop" "@lib.css" "!psh" )
    267 </code></pre>
    268 
    269 <p>This is usually called at the beginning of an application, and allows access
    270 to the directory "app/", to the functions 'start', 'stop' and 'psh', and to the
    271 file "@lib.css".
    272 
    273 <p>Later in the program, <code>*Allow</code> may be dynamically extended with
    274 <code>allow</code>
    275 
    276 <pre><code>
    277 (allow "!foo")
    278 (allow "newdir/" T)
    279 </code></pre>
    280 
    281 <p>This adds the function 'foo', and the directory "newdir/", to the set of
    282 allowed items.
    283 
    284 
    285 <h4><a name="pw">The ".pw" File</a></h4>
    286 
    287 <p>For a variety of security checks (most notably for using the <code>psh</code>
    288 function, as in some later examples) it is necessary to create a file named
    289 ".pw" in the PicoLisp installation directory. This file should contain a single
    290 line of arbitrary data, to be used as a password for identifying local
    291 resources.
    292 
    293 <p>The recommeded way to create this file is to call the <code>pw</code>
    294 function, defined in "@lib/http.l"
    295 
    296 <pre><code>
    297 $ pil @lib/http.l -'pw 12' -bye
    298 </code></pre>
    299 
    300 <p>Please execute this command.
    301 
    302 
    303 <p><hr>
    304 <h3><a name="htmlFoo">The <code>html</code> Function</a></h3>
    305 
    306 <p>Now back to our "Hello World" example. In principle, you could write
    307 "project.l" as a sequence of print statements
    308 
    309 <pre><code>
    310 ########################################################################
    311 (prinl "HTTP/1.0 200 OK^M")
    312 (prinl "Content-Type: text/html; charset=utf-8")
    313 (prinl "^M")
    314 (prinl "&lt;html&gt;")
    315 (prinl "Hello World!")
    316 (prinl "&lt;/html&gt;")
    317 ########################################################################
    318 </code></pre>
    319 
    320 <p>but using the <code>html</code> function is much more convenient.
    321 
    322 <p>Moreover, <code>html</code> <b>is</b> nothing more than a printing function.
    323 You can see this easily if you connect a PicoLisp Shell (<code>psh</code>) to
    324 the server process (you must have generated a <a href="#pw">".pw" file</a> for
    325 this), and enter the <code>html</code> statement
    326 
    327 <pre><code>
    328 $ /usr/lib/picolisp/bin/psh 8080
    329 : (html 0 "Hello" "@lib.css" NIL "Hello World!")
    330 HTTP/1.0 200 OK
    331 Server: PicoLisp
    332 Date: Fri, 29 Dec 2006 07:28:58 GMT
    333 Cache-Control: max-age=0
    334 Cache-Control: no-cache
    335 Content-Type: text/html; charset=utf-8
    336 
    337 &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
    338 &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
    339 &lt;head&gt;
    340 &lt;title&gt;Hello&lt;/title&gt;
    341 &lt;base href="http://localhost:8080/"/&gt;
    342 &lt;link rel="stylesheet" type="text/css" href="http://localhost:8080/@lib.css"/&gt;
    343 &lt;/head&gt;
    344 &lt;body&gt;Hello World!&lt;/body&gt;
    345 &lt;/html&gt;
    346 -&gt; &lt;/html&gt;
    347 :  # (type Ctrl-D here to terminate PicoLisp)
    348 </code></pre>
    349 
    350 <p>These are the arguments to <code>html</code>:
    351 
    352 <ol>
    353 
    354 <li><code>0</code>: A max-age value for cache-control (in seconds, zero means
    355 "no-cache"). You might pass a higher value for pages that change seldom, or
    356 <code>NIL</code> for no cache-control at all.
    357 
    358 <li><code>"Hello"</code>: The page title.
    359 
    360 <li><code>"@lib.css"</code>: A CSS-File name. Pass <code>NIL</code> if you do
    361 not want to use any CSS-File, or a list of file names if you want to give more
    362 than one CSS-File.
    363 
    364 <li><code>NIL</code>: A CSS style attribute specification (see the description
    365 of <a href="#cssAttr">CSS Attributes</a> below). It will be passed to the
    366 <code>body</code> tag.
    367 
    368 </ol>
    369 
    370 <p>After these four arguments, an arbitrary number of expressions may follow.
    371 They form the body of the resulting page, and are evaluated according to a
    372 special rule. <a name="tagRule">This rule</a> is slightly different from the
    373 evaluation of normal Lisp expressions:
    374 
    375 <p><ul>
    376 
    377 <li>If an argument is an atom (a number or a symbol (string)), its value is
    378 printed immediately.
    379 
    380 <li>Otherwise (a list), it is evaluated as a Lisp function (typically some form
    381 of print statement).
    382 
    383 </ul>
    384 
    385 <p>Therefore, our source file might as well be written as:
    386 
    387 <pre><code>
    388 ########################################################################
    389 (html 0 "Hello" "@lib.css" NIL
    390    (prinl "Hello World!") )
    391 ########################################################################
    392 </code></pre>
    393 
    394 <p>The most typical print statements will be some HTML-tags:
    395 
    396 <pre><code>
    397 ########################################################################
    398 (html 0 "Hello" "@lib.css" NIL
    399    (&lt;h1&gt; NIL "Hello World!")
    400    (&lt;br&gt; "This is some text.")
    401    (ht:Prin "And this is a number: " (+ 1 2 3)) )
    402 ########################################################################
    403 </code></pre>
    404 
    405 <p><code>&lt;h1&gt;</code> and <code>&lt;br&gt;</code> are tag functions.
    406 <code>&lt;h1&gt;</code> takes a CSS attribute as its first argument.
    407 
    408 <p>Note the use of <code>ht:Prin</code> instead of <code>prin</code>.
    409 <code>ht:Prin</code> should be used for all direct printing in HTML pages,
    410 because it takes care to escape special characters.
    411 
    412 
    413 <p><hr>
    414 <h3><a name="cssAttr">CSS Attributes</a></h3>
    415 
    416 <p>The <a href="#htmlFoo"><code>html</code> function</a> above, and many of the
    417 HTML <a href="#tags">tag functions</a>, accept a CSS attribute specification.
    418 This may be either an atom, a cons pair, or a list of cons pairs. We demonstrate
    419 the effects with the <code>&lt;h1&gt;</code> tag function.
    420 
    421 <p>An atom (usually a symbol or a string) is taken as a CSS class name
    422 
    423 <pre><code>
    424 : (&lt;h1&gt; 'foo "Title")
    425 &lt;h1 class="foo"&gt;Title&lt;/h1&gt;
    426 </code></pre>
    427 
    428 <p>For a cons pair, the CAR is taken as an attribute name, and the CDR as the
    429 attribute's value
    430 
    431 <pre><code>
    432 : (&lt;h1&gt; '(id . bar) "Title")
    433 &lt;h1 id="bar"&gt;Title&lt;/h1&gt;
    434 </code></pre>
    435 
    436 <p>Consequently, a list of cons pairs gives a set of attribute-value pairs
    437 
    438 <pre><code>
    439 : (&lt;h1&gt; '((id . "abc") (lang . "de")) "Title")
    440 &lt;h1 id="abc" lang="de"&gt;Title&lt;/h1&gt;
    441 </code></pre>
    442 
    443 
    444 <p><hr>
    445 <h3><a name="tags">Tag Functions</a></h3>
    446 
    447 <p>All pre-defined XHTML tag functions can be found in "@lib/xhtml.l". We
    448 recommend to look at their sources, and to experiment a bit, by executing them
    449 at a PicoLisp prompt, or by pressing the browser's "Reload" button after editing
    450 the "project.l" file.
    451 
    452 <p>For a suitable PicoLisp prompt, either execute (in a separate terminal
    453 window) the PicoLisp Shell (<code>psh</code>) command (works only if the
    454 application server is running, and you did generate a <a href="#pw">".pw"
    455 file</a>)
    456 
    457 <pre><code>
    458 $ /usr/lib/picolisp/bin/psh 8080
    459 :
    460 </code></pre>
    461 
    462 <p>or start the interpreter stand-alone, with "@lib/xhtml.l" loaded
    463 
    464 <pre><code>
    465 $ pil @lib/http.l @lib/xhtml.l +
    466 :
    467 </code></pre>
    468 
    469 <p>Note that for all these tag functions the above <a href="#tagRule">tag body
    470 evaluation rule</a> applies.
    471 
    472 
    473 <h4><a name="simple">Simple Tags</a></h4>
    474 
    475 <p>Most tag functions are simple and straightforward. Some of them just print
    476 their arguments
    477 
    478 <pre><code>
    479 : (&lt;br&gt; "Hello world")
    480 Hello world&lt;br/&gt;
    481 
    482 : (&lt;em&gt; "Hello world")
    483 &lt;em&gt;Hello world&lt;/em&gt;
    484 </code></pre>
    485 
    486 <p>while most of them take a <a href="#cssAttr">CSS attribute specification</a>
    487 as their first argument (like the <code>&lt;h1&gt;</code> tag above)
    488 
    489 <pre><code>
    490 : (&lt;div&gt; 'main "Hello world")
    491 &lt;div class="main"&gt;Hello world&lt;/div&gt;
    492 
    493 : (&lt;p&gt; NIL "Hello world")
    494 &lt;p&gt;Hello world&lt;/p&gt;
    495 
    496 : (&lt;p&gt; 'info "Hello world")
    497 &lt;p class="info"&gt;Hello world&lt;/p&gt;
    498 </code></pre>
    499 
    500 <p>All of these functions take an arbitrary number of arguments, and may nest to
    501 an arbitrary depth (as long as the resulting HTML is legal)
    502 
    503 <pre><code>
    504 : (&lt;div&gt; 'main
    505    (&lt;h1&gt; NIL "Head")
    506    (&lt;p&gt; NIL
    507       (&lt;br&gt; "Line 1")
    508       "Line"
    509       (&lt;nbsp&gt;)
    510       (+ 1 1) ) )
    511 &lt;div class="main"&gt;&lt;h1&gt;Head&lt;/h1&gt;
    512 &lt;p&gt;Line 1&lt;br/&gt;
    513 Line&nbsp;2&lt;/p&gt;
    514 &lt;/div&gt;
    515 </code></pre>
    516 
    517 
    518 <h4><a name="lists">(Un)ordered Lists</a></h4>
    519 
    520 <p>HTML-lists, implemented by the <code>&lt;ol&gt;</code> and
    521 <code>&lt;ul&gt;</code> tags, let you define hierarchical structures. You might
    522 want to paste the following code into your copy of "project.l":
    523 
    524 <pre><code>
    525 ########################################################################
    526 (html 0 "Unordered List" "@lib.css" NIL
    527    (&lt;ul&gt; NIL
    528       (&lt;li&gt; NIL "Item 1")
    529       (&lt;li&gt; NIL
    530          "Sublist 1"
    531          (&lt;ul&gt; NIL
    532             (&lt;li&gt; NIL "Item 1-1")
    533             (&lt;li&gt; NIL "Item 1-2") ) )
    534       (&lt;li&gt; NIL "Item 2")
    535       (&lt;li&gt; NIL
    536          "Sublist 2"
    537          (&lt;ul&gt; NIL
    538             (&lt;li&gt; NIL "Item 2-1")
    539             (&lt;li&gt; NIL "Item 2-2") ) )
    540       (&lt;li&gt; NIL "Item 3") ) )
    541 ########################################################################
    542 </code></pre>
    543 
    544 <p>Here, too, you can put arbitrary code into each node of that tree, including
    545 other tag functions.
    546 
    547 
    548 <h4><a name="tables">Tables</a></h4>
    549 
    550 <p>Like the hierarchical structures with the list functions, you can generate
    551 two-dimensional tables with the <code>&lt;table&gt;</code> and
    552 <code>&lt;row&gt;</code> functions.
    553 
    554 <p>The following example prints a table of numbers and their squares:
    555 
    556 <pre><code>
    557 ########################################################################
    558 (html 0 "Table" "@lib.css" NIL
    559    (&lt;table&gt; NIL NIL NIL
    560       (for N 10                                    # A table with 10 rows
    561          (&lt;row&gt; NIL N (prin (* N N))) ) ) )     # and 2 columns
    562 ########################################################################
    563 </code></pre>
    564 
    565 <p>The first argument to <code>&lt;table&gt;</code> is the usual CSS attribute,
    566 the second an optional title ("caption"), and the third an optional list
    567 specifying the column headers. In that list, you may supply a list for a each
    568 column, with a CSS attribute in its CAR, and a tag body in its CDR for the
    569 contents of the column header.
    570 
    571 <p>The body of <code>&lt;table&gt;</code> contains calls to the
    572 <code>&lt;row&gt;</code> function. This function is special in that each
    573 expression in its body will go to a separate column of the table. If both for
    574 the column header and the row function an CSS attribute is given, they will be
    575 combined by a space and passed to the HTML <code>&lt;td&gt;</code> tag. This
    576 permits distinct CSS specifications for each column and row.
    577 
    578 <p>As an extension of the above table example, let's pass some attributes for
    579 the table itself (not recommended - better define such styles in a CSS file and
    580 then just pass the class name to <code>&lt;table&gt;</code>), right-align both
    581 columns, and print each row in an alternating red and blue color
    582 
    583 <pre><code>
    584 ########################################################################
    585 (html 0 "Table" "@lib.css" NIL
    586    (&lt;table&gt;
    587       '((width . "200px") (style . "border: dotted 1px;"))    # table style
    588       "Square Numbers"                                        # caption
    589       '((align "Number") (align "Square"))                    # 2 headers
    590       (for N 10                                                  # 10 rows
    591          (&lt;row&gt; (xchg '(red) '(blue))                         # red or blue
    592             N                                                 # 2 columns
    593             (prin (* N N) ) ) ) ) )
    594 ########################################################################
    595 </code></pre>
    596 
    597 <p>If you wish to concatenate two or more cells in a table, so that a single
    598 cell spans several columns, you can pass the symbol '<code>-</code>' for the
    599 additional cell data to <code>&lt;row&gt;</code>. This will cause the data given
    600 to the left of the '<code>-</code>' symbols to expand to the right.
    601 
    602 <p>You can also directly specify table structures with the simple
    603 <code>&lt;th&gt;</code>, <code>&lt;tr&gt;</code> and <code>&lt;td&gt;</code> tag
    604 functions.
    605 
    606 <p>If you just need a two-dimensional arrangement of components, the even
    607 simpler <code>&lt;grid&gt;</code> function might be convenient:
    608 
    609 <pre><code>
    610 ########################################################################
    611 (html 0 "Grid" "@lib.css" NIL
    612    (&lt;grid&gt; 3
    613       "A" "B" "C"
    614       123 456 789 ) )
    615 ########################################################################
    616 </code></pre>
    617 
    618 <p>It just takes a specification for the number of columns (here: 3) as its
    619 first argument, and then a single expression for each cell. Instead of a number,
    620 you can also pass a list of CSS attributes. Then the length of that list will
    621 determine the number of columns. You can change the second line in the above
    622 example to
    623 
    624 <pre><code>
    625    (&lt;grid&gt; '(NIL NIL right)
    626 </code></pre>
    627 
    628 <p>Then the third column will be right aligned.
    629 
    630 
    631 <h4><a name="menus">Menus and Tabs</a></h4>
    632 
    633 <p>The two most powerful tag functions are <code>&lt;menu&gt;</code> and
    634 <code>&lt;tab&gt;</code>. Used separately or in combination, they form a
    635 navigation framework with
    636 
    637 <p><ul>
    638 <li>menu items which open and close submenus
    639 <li>submenu items which switch to different pages
    640 <li>tabs which switch to different subpages
    641 </ul>
    642 
    643 <p>The following example is not very useful, because the URLs of all items link
    644 to the same "project.l" page, but it should suffice to demonstrate the
    645 functionality:
    646 
    647 <pre><code>
    648 ########################################################################
    649 (html 0 "Menu+Tab" "@lib.css" NIL
    650    (&lt;div&gt; '(id . menu)
    651       (&lt;menu&gt;
    652          ("Item" "project.l")                      # Top level item
    653          (NIL (&lt;hr&gt;))                              # Plain HTML
    654          (T "Submenu 1"                            # Submenu
    655             ("Subitem 1.1" "project.l")
    656             (T "Submenu 1.2"
    657                ("Subitem 1.2.1" "project.l")
    658                ("Subitem 1.2.2" "project.l")
    659                ("Subitem 1.2.3" "project.l") )
    660             ("Subitem 1.3" "project.l") )
    661          (T "Submenu 2"
    662             ("Subitem 2.1" "project.l")
    663             ("Subitem 2.2" "project.l") ) ) )
    664    (&lt;div&gt; '(id . main)
    665       (&lt;h1&gt; NIL "Menu+Tab")
    666       (&lt;tab&gt;
    667          ("Tab1"
    668             (&lt;h3&gt; NIL "This is Tab 1") )
    669          ("Tab2"
    670             (&lt;h3&gt; NIL "This is Tab 2") )
    671          ("Tab3"
    672             (&lt;h3&gt; NIL "This is Tab 3") ) ) ) )
    673 ########################################################################
    674 </code></pre>
    675 
    676 <p><code>&lt;menu&gt;</code> takes a sequence of menu items. Each menu item is a
    677 list, with its CAR either
    678 
    679 <p><ul>
    680 <li><code>NIL</code>: The entry is not an active menu item, and the rest of the
    681 list may consist of arbitrary code (usually HTML tags).
    682 
    683 <li><code>T</code>: The second element is taken as a submenu name, and a click
    684 on that name will open or close the corresponding submenu. The rest of the list
    685 recursively specifies the submenu items (may nest to arbitrary depth).
    686 
    687 <li>Otherwise: The menu item specifies a direct action (instead of opening a
    688 submenu), where the first list element gives the item's name, and the second
    689 element the corresponding URL.
    690 
    691 </ul>
    692 
    693 <p><code>&lt;tab&gt;</code> takes a list of subpages. Each page is simply a tab
    694 name, followed by arbitrary code (typically HTML tags).
    695 
    696 <p>Note that only a single menu and a single tab may be active at the same time.
    697 
    698 
    699 <p><hr>
    700 <h2><a name="forms">Interactive Forms</a></h2>
    701 
    702 <p>In HTML, the only possibility for user input is via <code>&lt;form&gt;</code>
    703 and <code>&lt;input&gt;</code> elements, using the HTTP POST method to
    704 communicate with the server.
    705 
    706 <p>"@lib/xhtml.l" defines a function called <code>&lt;post&gt;</code>, and a
    707 collection of input tag functions, which allow direct programming of HTML forms.
    708 We will supply only one simple example:
    709 
    710 <pre><code>
    711 ########################################################################
    712 (html 0 "Simple Form" "@lib.css" NIL
    713    (&lt;post&gt; NIL "project.l"
    714       (&lt;field&gt; 10 '*Text)
    715       (&lt;submit&gt; "Save") ) )
    716 ########################################################################
    717 </code></pre>
    718 
    719 <p>This associates a text input field with a global variable <code>*Text</code>.
    720 The field displays the current value of <code>*Text</code>, and pressing the
    721 submit button causes a reload of "project.l" with <code>*Text</code> set to any
    722 string entered by the user.
    723 
    724 <p>An application program could then use that variable to do something useful,
    725 for example store its value in a database.
    726 
    727 <p>The problem with such a straightforward use of forms is that
    728 
    729 <p><ol>
    730 <li>they require the application programmer to take care of maintaining lots of
    731 global variables. Each input field on the page needs an associated variable for
    732 the round trip between server and client.
    733 
    734 <li>they do not preserve an application's internal state. Each POST request
    735 spawns an individual process on the server, which sets the global variables to
    736 their new values, generates the HTML page, and terminates thereafter. The
    737 application state has to be passed along explicitly, e.g. using
    738 <code>&lt;hidden&gt;</code> tags.
    739 
    740 <li>they are not very interactive. There is typically only a single submit
    741 button. The user fills out a possibly large number of input fields, but changes
    742 will take effect only when the submit button is pressed.
    743 
    744 </ol>
    745 
    746 <p>Though we wrote a few applications in that style, we recommend the GUI
    747 framework provided by "@lib/form.l". It does not need any variables for the
    748 client/server communication, but implements a class hierarchy of GUI components
    749 for the abstraction of application logic, button actions and data linkage.
    750 
    751 
    752 <p><hr>
    753 <h3><a name="sessions">Sessions</a></h3>
    754 
    755 <p>First of all, we need to establish a persistent environment on the server, to
    756 handle each individual session (for each connected client).
    757 
    758 <p>Technically, this is just a child process of the server we started <a
    759 href="#server">above</a>, which does not terminate immediately after it sent its
    760 page to the browser. It is achieved by calling the <code>app</code> function
    761 somewhere in the application's startup code.
    762 
    763 <pre><code>
    764 ########################################################################
    765 (app)  # Start a session
    766 
    767 (html 0 "Simple Session" "@lib.css" NIL
    768    (&lt;post&gt; NIL "project.l"
    769       (&lt;field&gt; 10 '*Text)
    770       (&lt;submit&gt; "Save") ) )
    771 ########################################################################
    772 </code></pre>
    773 
    774 <p>Nothing else changed from the previous example. However, when you connect
    775 your browser and then look at the terminal window where you started the
    776 application server, you'll notice a colon, the PicoLisp prompt
    777 
    778 <pre><code>
    779 $ pil @lib/http.l @lib/xhtml.l @lib/form.l  --server 8080 project.l  +
    780 :
    781 </code></pre>
    782 
    783 <p>Tools like the Unix <code>ps</code> utility will tell you that now two
    784 <code>picolisp</code> processes are running, the first being the parent of the
    785 second.
    786 
    787 <p>If you enter some text, say "abcdef", into the text field in the browser
    788 window, press the submit button, and inspect the Lisp <code>*Text</code>
    789 variable,
    790 
    791 <pre><code>
    792 : *Text
    793 -> "abcdef"
    794 </code></pre>
    795 
    796 <p>you see that we now have a dedicated PicoLisp process, "connected" to the
    797 client.
    798 
    799 <p>You can terminate this process (like any interactive PicoLisp) by hitting
    800 <code>Ctrl-D</code> on an empty line. Otherwise, it will terminate by itself if
    801 no other browser requests arrive within a default timeout period of 5 minutes.
    802 
    803 <p>To start a (non-debug) production version, the server is commonly started
    804 without the '+' flag, and with <code>-wait</code>
    805 
    806 <pre><code>
    807 $ pil @lib/http.l @lib/xhtml.l @lib/form.l  --server 8080 project.l  -wait
    808 </code></pre>
    809 
    810 <p>In that way, no command line prompt appears when a client connects.
    811 
    812 
    813 <p><hr>
    814 <h3><a name="actionForms">Action Forms</a></h3>
    815 
    816 <p>Now that we have a persistent session for each client, we can set up an
    817 active GUI framework.
    818 
    819 <p>This is done by wrapping the call to the <code>html</code> function with
    820 <code>action</code>. Inside the body of <code>html</code> can be - in addition
    821 to all other kinds of tag functions - one or more calls to <code>form</code>
    822 
    823 <pre><code>
    824 ########################################################################
    825 (app)                                              # Start session
    826 
    827 (action                                            # Action handler
    828    (html 0 "Form" "@lib.css" NIL                   # HTTP/HTML protocol
    829       (form NIL                                    # Form
    830          (gui 'a '(+TextField) 10)                 # Text Field
    831          (gui '(+Button) "Print"                   # Button
    832             '(msg (val&gt; (: home a))) ) ) ) )
    833 ########################################################################
    834 </code></pre>
    835 
    836 <p>Note that there is no longer a global variable like <code>*Text</code> to
    837 hold the contents of the input field. Instead, we gave a local, symbolic name
    838 '<code>a</code>' to a <code>+TextField</code> component
    839 
    840 <pre><code>
    841          (gui 'a '(+TextField) 10)                 # Text Field
    842 </code></pre>
    843 
    844 <p>Other components can refer to it
    845 
    846 <pre><code>
    847             '(msg (val&gt; (: home a)))
    848 </code></pre>
    849 
    850 <p><code>(: home)</code> is always the form which contains this GUI component.
    851 So <code>(: home a)</code> evaluates to the component '<code>a</code>' in the
    852 current form. As <code><a href="refM.html#msg">msg</a></code> prints its
    853 argument to standard error, and the <code>val&gt;</code> method retrieves the
    854 current contents of a component, we will see on the console the text typed into
    855 the text field when we press the button.
    856 
    857 <p>An <code>action</code> without embedded <code>form</code>s - or a
    858 <code>form</code> without a surrounding <code>action</code> - does not make much
    859 sense by itself. Inside <code>html</code> and <code>form</code>, however, calls
    860 to HTML functions (and any other Lisp functions, for that matter) can be freely
    861 mixed.
    862 
    863 <p>In general, a typical page may have the form
    864 
    865 <pre><code>
    866 (action                                            # Action handler
    867    (html ..                                        # HTTP/HTML protocol
    868       (&lt;h1&gt; ..)                                    # HTML tags
    869       (form NIL                                    # Form
    870          (&lt;h3&gt; ..)
    871          (gui ..)                                  # GUI component(s)
    872          (gui ..)
    873          .. )
    874       (&lt;h2&gt; ..)
    875       (form NIL                                    # Another form
    876          (&lt;h3&gt; ..)
    877          (gui ..)                                  # GUI component(s)
    878          .. )
    879       (&lt;br&gt; ..)
    880       .. ) )
    881 </code></pre>
    882 
    883 
    884 <h4><a name="guiFoo">The <code>gui</code> Function</a></h4>
    885 
    886 <p>The most prominent function in a <code>form</code> body is <code>gui</code>.
    887 It is the workhorse of GUI construction.
    888 
    889 <p>Outside of a <code>form</code> body, <code>gui</code> is undefined.
    890 Otherwise, it takes an optional alias name, a list of classes, and additional
    891 arguments as needed by the constructors of these classes. We saw this example
    892 before
    893 
    894 <pre><code>
    895          (gui 'a '(+TextField) 10)                 # Text Field
    896 </code></pre>
    897 
    898 Here, '<code>a</code>' is an alias name for a component of type
    899 <code>(+TextField)</code>. The numeric argument <code>10</code> is passed to the
    900 text field, specifying its width. See the chapter on <a href="#guiClasses">GUI
    901 Classes</a> for more examples.
    902 
    903 <p>During a GET request, <code>gui</code> is basically a front-end to
    904 <code>new</code>. It builds a component, stores it in the internal structures of
    905 the current form, and initializes it by sending the <code>init&gt;</code>
    906 message to the component. Finally, it sends it the <code>show&gt;</code>
    907 message, to produce HTML code and transmit it to the browser.
    908 
    909 <p>During a POST request, <code>gui</code> does not build any new components.
    910 Instead, the existing components are re-used. So <code>gui</code> does not have
    911 much more to do than sending the <code>show&gt;</code> message to a component.
    912 
    913 
    914 <h4><a name="ctlFlow">Control Flow</a></h4>
    915 
    916 <p>HTTP has only two methods to change a browser window: GET and POST. We employ
    917 these two methods in a certain defined, specialized way:
    918 
    919 <p><ul>
    920 <li>GET means, a <b>new page</b> is being constructed. It is used when a page is
    921 visited for the first time, usually by entering an URL into the browser's
    922 address field, or by clicking on a link (which is often a <a
    923 href="#menus">submenu item or tab</a>).
    924 
    925 <li>POST is always directed to the <b>same page</b>. It is triggered by a button
    926 press, updates the corresponding form's data structures, and executes that
    927 button's action code.
    928 
    929 </ul>
    930 
    931 <p>A button's action code can do almost anything: Read and modify the contents
    932 of input fields, communicate with the database, display alerts and dialogs, or
    933 even fake the POST request to a GET, with the effect of showing a completely
    934 different document (See <a href="#switching">Switching URLs</a>).
    935 
    936 <p>GET builds up all GUI components on the server. These components are objects
    937 which encapsulate state and behavior of the HTML page in the browser. Whenever a
    938 button is pressed, the page is reloaded via a POST request. Then - before any
    939 output is sent to the browser - the <code>action</code> function takes control.
    940 It performs error checks on all components, processes possible user input on the
    941 HTML page, and stores the values in correct format (text, number, date, object
    942 etc.) in each component.
    943 
    944 <p>The state of a form is preserved over time. When the user returns to a
    945 previous page with the browser's BACK button, that state is reactivated, and may
    946 be POSTed again.
    947 
    948 <p>The following silly example displays two text fields. If you enter some text
    949 into the "Source" field, you can copy it in upper or lower case to the
    950 "Destination" field by pressing one of the buttons
    951 
    952 <pre><code>
    953 ########################################################################
    954 (app)
    955 
    956 (action
    957    (html 0 "Case Conversion" "@lib.css" NIL
    958       (form NIL
    959          (&lt;grid&gt; 2
    960             "Source" (gui 'src '(+TextField) 30)
    961             "Destination" (gui 'dst '(+Lock +TextField) 30) )
    962          (gui '(+JS +Button) "Upper Case"
    963             '(set&gt; (: home dst)
    964                (uppc (val&gt; (: home src))) ) )
    965          (gui '(+JS +Button) "Lower Case"
    966             '(set&gt; (: home dst)
    967                (lowc (val&gt; (: home src))) ) ) ) ) )
    968 ########################################################################
    969 </code></pre>
    970 
    971 <p>The <code>+Lock</code> prefix class in the "Destination" field makes that
    972 field read-only. The only way to get some text into that field is by using one
    973 of the buttons.
    974 
    975 
    976 <h4><a name="switching">Switching URLs</a></h4>
    977 
    978 <p>Because an action code runs before <code>html</code> has a chance to output
    979 an HTTP header, it can abort the current page and present something different to
    980 the user. This might, of course, be another HTML page, but would not be very
    981 interesting as a normal link would suffice. Instead, it can cause the download
    982 of dynamically generated data.
    983 
    984 <p>The next example shows a text area and two buttons. Any text entered into the
    985 text area is exported either as a text file via the first button, or a PDF
    986 document via the second button
    987 
    988 <pre><code>
    989 ########################################################################
    990 (load "@lib/ps.l")
    991 
    992 (app)
    993 
    994 (action
    995    (html 0 "Export" "@lib.css" NIL
    996       (form NIL
    997          (gui '(+TextField) 30 8)
    998          (gui '(+Button) "Text"
    999             '(let Txt (tmp "export.txt")
   1000                (out Txt (prinl (val&gt; (: home gui 1))))
   1001                (url Txt) ) )
   1002          (gui '(+Button) "PDF"
   1003             '(psOut NIL "foo"
   1004                (a4)
   1005                (indent 40 40)
   1006                (down 60)
   1007                (hline 3)
   1008                (font (14 . "Times-Roman")
   1009                   (ps (val&gt; (: home gui 1))) )
   1010                (hline 3)
   1011                (page) ) ) ) ) )
   1012 ########################################################################
   1013 </code></pre>
   1014 
   1015 <p>(a text area is built when you supply two numeric arguments (columns and
   1016 rows) to a <code>+TextField</code> class)
   1017 
   1018 <p>The action code of the first button creates a temporary file (i.e. a file
   1019 named "export.txt" in the current process's temporary space), prints the value
   1020 of the text area (this time we did not bother to give it a name, we simply refer
   1021 to it as the form's first gui list element) into that file, and then calls the
   1022 <code>url</code> function with the file name.
   1023 
   1024 <p>The second button uses the PostScript library "@lib/ps.l" to create a
   1025 temporary file "foo.pdf". Here, the temporary file creation and the call to the
   1026 <code>url</code> function is hidden in the internal mechanisms of
   1027 <code>psOut</code>. The effect is that the browser receives a PDF document and
   1028 displays it.
   1029 
   1030 
   1031 <h4><a name="dialogs">Alerts and Dialogs</a></h4>
   1032 
   1033 <p>Alerts and dialogs are not really what they used to be ;-)
   1034 
   1035 <p>They do not "pop up". In this framework, they are just a kind of
   1036 simple-to-use, pre-fabricated form. They can be invoked by a button's action
   1037 code, and appear always on the current page, immediately preceding the form
   1038 which created them.
   1039 
   1040 <p>Let's look at an example which uses two alerts and a dialog. In the
   1041 beginning, it displays a simple form, with a locked text field, and two buttons
   1042 
   1043 <pre><code>
   1044 ########################################################################
   1045 (app)
   1046 
   1047 (action
   1048    (html 0 "Alerts and Dialogs" "@lib.css" NIL
   1049       (form NIL
   1050          (gui '(+Init +Lock +TextField) "Initial Text" 20 "My Text")
   1051          (gui '(+Button) "Alert"
   1052             '(alert NIL "This is an alert " (okButton)) )
   1053          (gui '(+Button) "Dialog"
   1054             '(dialog NIL
   1055                (&lt;br&gt; "This is a dialog.")
   1056                (&lt;br&gt;
   1057                   "You can change the text here "
   1058                   (gui '(+Init +TextField) (val&gt; (: top 1 gui 1)) 20) )
   1059                (&lt;br&gt; "and then re-submit it to the form.")
   1060                (gui '(+Button) "Re-Submit"
   1061                   '(alert NIL "Are you sure? "
   1062                      (yesButton
   1063                         '(set&gt; (: home top 2 gui 1)
   1064                            (val&gt; (: home top 1 gui 1)) ) )
   1065                      (noButton) ) )
   1066                (cancelButton) ) ) ) ) )
   1067 ########################################################################
   1068 </code></pre>
   1069 
   1070 <p>The <code>+Init</code> prefix class initializes the "My Text" field with the
   1071 string "Initial Text". As the field is locked, you cannot modify this value
   1072 directly.
   1073 
   1074 <p>The first button brings up an alert saying "This is an alert.". You can
   1075 dispose it by pressing "OK".
   1076 
   1077 <p>The second button brings up a dialog with an editable text field, containing
   1078 a copy of the value from the form's locked text field. You can modify this
   1079 value, and send it back to the form, if you press "Re-Submit" and answer "Yes"
   1080 to the "Are you sure?" alert.
   1081 
   1082 
   1083 <h4><a name="calc">A Calculator Example</a></h4>
   1084 
   1085 <p>Now let's forget our "project.l" test file for a moment, and move on to a
   1086 more substantial and practical, stand-alone, example. Using what we have learned
   1087 so far, we want to build a simple bignum calculator. ("bignum" because PicoLisp
   1088 can do <i>only</i> bignums)
   1089 
   1090 <p>It uses a single form, a single numeric input field, and lots of buttons. It
   1091 can be found in the PicoLisp distribution (e.g. under "/usr/share/picolisp/") in
   1092 "misc/calc.l", together with a directly executable wrapper script "misc/calc".
   1093 
   1094 <p>To use it, change to the PicoLisp installation directory, and start it as
   1095 
   1096 <pre><code>
   1097 $ misc/calc
   1098 </code></pre>
   1099 
   1100 <p>or call it with an absolute path, e.g.
   1101 
   1102 <pre><code>
   1103 $ /usr/share/picolisp/misc/calc
   1104 </code></pre>
   1105 
   1106 <p>If you like to get a PicoLisp prompt for inspection, start it instead as
   1107 
   1108 <pre><code>
   1109 $ pil misc/calc.l -main -go +
   1110 </code></pre>
   1111 
   1112 <p>Then - as before - point your browser to '<code><a
   1113 href="http://localhost:8080">http://localhost:8080</a></code>'.
   1114 
   1115 <p>The code for the calculator logic and the GUI is rather straightforward. The
   1116 entry point is the single function <code>calculator</code>. It is called
   1117 directly (as described in <a href="#urlSyntax">URL Syntax</a>) as the server's
   1118 default URL, and implicitly in all POST requests. No further file access is
   1119 needed once the calculator is running.
   1120 
   1121 <p>Note that for a production application, we inserted an allow-statement (as
   1122 recommended by the <a href="#security">Security</a> chapter)
   1123 
   1124 <pre><code>
   1125 (allowed NIL "!calculator" "@lib.css")
   1126 </code></pre>
   1127 
   1128 <p>at the beginning of "misc/calc.l". This will restrict external access to that
   1129 single function.
   1130 
   1131 <p>The calculator uses three global variables, <code>*Init</code>,
   1132 <code>*Accu</code> and <code>*Stack</code>. <code>*Init</code> is a boolean flag
   1133 set by the operator buttons to indicate that the next digit should initialize
   1134 the accumulator to zero. <code>*Accu</code> is the accumulator. It is always
   1135 displayed in the numeric input field, accepts user input, and it holds the
   1136 results of calculations. <code>*Stack</code> is a push-down stack, holding
   1137 postponed calculations (operators, priorities and intermediate results) with
   1138 lower-priority operators, while calculations with higher-priority operators are
   1139 performed.
   1140 
   1141 <p>The function <code>digit</code> is called by the digit buttons, and adds
   1142 another digit to the accumulator.
   1143 
   1144 <p>The function <code>calc</code> does an actual calculation step. It pops the
   1145 stack, checks for division by zero, and displays an error alert if necessary.
   1146 
   1147 <p><code>operand</code> processes an operand button, accepting a function and a
   1148 priority as arguments. It compares the priority with that in the top-of-stack
   1149 element, and delays the calculation if it is less.
   1150 
   1151 <p><code>finish</code> is used to calculate the final result.
   1152 
   1153 <p>The <code>calculator</code> function has one numeric input field, with a
   1154 width of 60 characters
   1155 
   1156 <pre><code>
   1157          (gui '(+Var +NumField) '*Accu 60)
   1158 </code></pre>
   1159 
   1160 <p>The <code>+Var</code> prefix class associates this field with the global
   1161 variable <code>*Accu</code>. All changes to the field will show up in that
   1162 variable, and modification of that variable's value will appear in the field.
   1163 
   1164 <p>The <a name="sqrtButton">square root operator button</a> has an
   1165 <code>+Able</code> prefix class
   1166 
   1167 <pre><code>
   1168          (gui '(+Able +JS +Button) '(ge0 *Accu) (char 8730)
   1169             '(setq *Accu (sqrt *Accu)) )
   1170 </code></pre>
   1171 
   1172 
   1173 <p>with an argument expression which checks that the current value in the
   1174 accumulator is positive, and disables the button if otherwise.
   1175 
   1176 <p>The rest of the form is just an array (grid) of buttons, encapsulating all
   1177 functionality of the calculator. The user can enter numbers into the input
   1178 field, either by using the digit buttons, or by directly typing them in, and
   1179 perform calculations with the operator buttons. Supported operations are
   1180 addition, subtraction, multiplication, division, sign inversion, square root and
   1181 power (all in bignum integer arithmetic). The '<code>C</code>' button just
   1182 clears the accumulator, while the '<code>A</code>' button also clears all
   1183 pending calculations.
   1184 
   1185 <p>All that in 53 lines of code!
   1186 
   1187 
   1188 <p><hr>
   1189 <h3><a name="charts">Charts</a></h3>
   1190 
   1191 <p>Charts are virtual components, maintaining the internal representation of
   1192 two-dimensional data.
   1193 
   1194 <p>Typically, these data are nested lists, database selections, or some kind of
   1195 dynamically generated tabular information. Charts make it possible to view them
   1196 in rows and columns (usually in HTML <a href="#tables">tables</a>), scroll up
   1197 and down, and associate them with their corresponding visible GUI components.
   1198 
   1199 <p>In fact, the logic to handle charts makes up a substantial part of the whole
   1200 framework, with large impact on all internal mechanisms. Each GUI component must
   1201 know whether it is part of a chart or not, to be able to handle its contents
   1202 properly during updates and user interactions.
   1203 
   1204 <p>Let's assume we want to collect textual and numerical data. We might create a
   1205 table
   1206 
   1207 <pre><code>
   1208 ########################################################################
   1209 (app)
   1210 
   1211 (action
   1212    (html 0 "Table" "@lib.css" NIL
   1213       (form NIL
   1214          (&lt;table&gt; NIL NIL '((NIL "Text") (NIL "Number"))
   1215             (do 4
   1216                (&lt;row&gt; NIL
   1217                   (gui '(+TextField) 20)
   1218                   (gui '(+NumField) 10) ) ) )
   1219          (&lt;submit&gt; "Save") ) ) )
   1220 ########################################################################
   1221 </code></pre>
   1222 
   1223 <p>with two columns "Text" and "Number", and four rows, each containing a
   1224 <code>+TextField</code> and a <code>+NumField</code>.
   1225 
   1226 <p>You can enter text into the first column, and numbers into the second.
   1227 Pressing the "Save" button stores these values in the components on the server
   1228 (or produces an error message if a string in the second column is not a legal
   1229 number).
   1230 
   1231 <p>There are two problems with this solution:
   1232 
   1233 <p><ol>
   1234 <li>Though you can get at the user input for the individual fields, e.g.
   1235 
   1236 <pre><code>
   1237 : (val> (get *Top 'gui 2))  # Value in the first row, second column
   1238 -> 123
   1239 </code></pre>
   1240 
   1241 there is no direct way to get the whole data structure as a single list.
   1242 Instead, you have to traverse all GUI components and collect the data.
   1243 
   1244 <li>The user cannot input more than four rows of data, because there is no easy
   1245 way to scroll down and make space for more.
   1246 
   1247 </ol>
   1248 
   1249 <p>A chart can handle these things:
   1250 
   1251 <pre><code>
   1252 ########################################################################
   1253 (app)
   1254 
   1255 (action
   1256    (html 0 "Chart" "@lib.css" NIL
   1257       (form NIL
   1258          (gui '(+Chart) 2)                         # Inserted a +Chart
   1259          (&lt;table&gt; NIL NIL '((NIL "Text") (NIL "Number"))
   1260             (do 4
   1261                (&lt;row&gt; NIL
   1262                   (gui 1 '(+TextField) 20)         # Inserted '1'
   1263                   (gui 2 '(+NumField) 10) ) ) )    # Inserted '2'
   1264          (&lt;submit&gt; "Save") ) ) )
   1265 ########################################################################
   1266 </code></pre>
   1267 
   1268 <p>Note that we inserted a <code>+Chart</code> component before the GUI
   1269 components which should be managed by the chart. The argument '2' tells the
   1270 chart that it has to expect two columns.
   1271 
   1272 <p>Each component got an index number (here '1' and '2') as the first argument
   1273 to <code>gui</code>, indicating the column into which this component should go
   1274 within the chart.
   1275 
   1276 <p>Now - if you entered "a", "b" and "c" into the first, and 1, 2, and 3 into
   1277 the second column - we can retrieve the chart's complete contents by sending it
   1278 the <code>val&gt;</code> message
   1279 
   1280 <pre><code>
   1281 : (val> (get *Top 'chart 1))  # Retrieve the value of the first chart
   1282 -> (("a" 1) ("b" 2) ("c" 3))
   1283 </code></pre>
   1284 
   1285 <p>BTW, a more convenient function is <code>chart</code>
   1286 
   1287 <pre><code>
   1288 : (val> (chart))  # Retrieve the value of the current chart
   1289 -> (("a" 1) ("b" 2) ("c" 3))
   1290 </code></pre>
   1291 
   1292 <p><code>chart</code> can be used instead of the above construct when we want to
   1293 access the "current" chart, i.e. the chart most recently processed in the
   1294 current form.
   1295 
   1296 
   1297 <h4><a name="scrolling">Scrolling</a></h4>
   1298 
   1299 <p>To enable scrolling, let's also insert two buttons. We use the pre-defined
   1300 classes <code>+UpButton</code> and <code>+DnButton</code>
   1301 
   1302 <pre><code>
   1303 ########################################################################
   1304 (app)
   1305 
   1306 (action
   1307    (html 0 "Scrollable Chart" "@lib.css" NIL
   1308       (form NIL
   1309          (gui '(+Chart) 2)
   1310          (&lt;table&gt; NIL NIL '((NIL "Text") (NIL "Number"))
   1311             (do 4
   1312                (&lt;row&gt; NIL
   1313                   (gui 1 '(+TextField) 20)
   1314                   (gui 2 '(+NumField) 10) ) ) )
   1315          (gui '(+UpButton) 1)                   # Inserted two buttons
   1316          (gui '(+DnButton) 1)
   1317          (----)
   1318          (&lt;submit&gt; "Save") ) ) )
   1319 ########################################################################
   1320 </code></pre>
   1321 
   1322 <p>to scroll down and up a single (argument '1') line at a time.
   1323 
   1324 <p>Now it is possible to enter a few rows of data, scroll down, and continue. It
   1325 is not necessary (except in the beginning, when the scroll buttons are still
   1326 disabled) to press the "Save" button, because <b>any</b> button in the form will
   1327 send changes to the server's internal structures before any action is performed.
   1328 
   1329 
   1330 <h4><a name="putGet">Put and Get Functions</a></h4>
   1331 
   1332 <p>As we said, a chart is a virtual component to edit two-dimensional data.
   1333 Therefore, a chart's native data format is a list of lists: Each sublist
   1334 represents a single row of data, and each element of a row corresponds to a
   1335 single GUI component.
   1336 
   1337 <p>In the example above, we saw a row like
   1338 
   1339 <pre><code>
   1340    ("a" 1)
   1341 </code></pre>
   1342 
   1343 <p>being mapped to
   1344 
   1345 <pre><code>
   1346    (gui 1 '(+TextField) 20)
   1347    (gui 2 '(+NumField) 10)
   1348 </code></pre>
   1349 
   1350 <p>Quite often, however, such a one-to-one relationship is not desired. The
   1351 internal data structures may have to be presented in a different form to the
   1352 user, and user input may need conversion to an internal representation.
   1353 
   1354 <p>For that, a chart accepts - in addition to the "number of columns" argument -
   1355 two optional function arguments. The first function is invoked to 'put' the
   1356 internal representation into the GUI components, and the second to 'get' data
   1357 from the GUI into the internal representation.
   1358 
   1359 <p>A typical example is a chart displaying customers in a database. While the
   1360 internal representation is a (one-dimensional) list of customer objects, 'put'
   1361 expands each object to a list with, say, the customer's first and second name,
   1362 telephone number, address and so on. When the user enters a customer's name,
   1363 'get' locates the matching object in the database and stores it in the internal
   1364 representation. In the following, 'put' will in turn expand it to the GUI.
   1365 
   1366 <p>For now, let's stick with a simpler example: A chart that holds just a list
   1367 of numbers, but expands in the GUI to show also a textual form of each number
   1368 (in German).
   1369 
   1370 <pre><code>
   1371 ########################################################################
   1372 (app)
   1373 
   1374 (load "@lib/zahlwort.l")
   1375 
   1376 (action
   1377    (html 0 "Numerals" "@lib.css" NIL
   1378       (form NIL
   1379          (gui '(+Init +Chart) (1 5 7) 2
   1380             '((N) (list N (zahlwort N)))
   1381             car )
   1382          (&lt;table&gt; NIL NIL '((NIL "Numeral") (NIL "German"))
   1383             (do 4
   1384                (&lt;row&gt; NIL
   1385                   (gui 1 '(+NumField) 9)
   1386                   (gui 2 '(+Lock +TextField) 90) ) ) )
   1387          (gui '(+UpButton) 1)
   1388          (gui '(+DnButton) 1)
   1389          (----)
   1390          (&lt;submit&gt; "Save") ) ) )
   1391 ########################################################################
   1392 </code></pre>
   1393 
   1394 <p>"@lib/zahlwort.l" defines the utility function <code>zahlwort</code>, which
   1395 is required later by the 'put' function. <code>zahlwort</code> accepts a number
   1396 and returns its wording in German.
   1397 
   1398 <p>Now look at the code
   1399 
   1400 <pre><code>
   1401          (gui '(+Init +Chart) (1 5 7) 2
   1402             '((N) (list N (zahlwort N)))
   1403             car )
   1404 </code></pre>
   1405 
   1406 <p>We prefix the <code>+Chart</code> class with <code>+Init</code>, and pass it
   1407 a list of numbers <code>(1 5 7)</code> for the initial value of the chart. Then,
   1408 following the '2' (the chart has two columns), we pass a 'put' function
   1409 
   1410 <pre><code>
   1411             '((N) (list N (zahlwort N)))
   1412 </code></pre>
   1413 
   1414 <p>which takes a number and returns a list of that number and its wording, and a
   1415 'get' function
   1416 
   1417 <pre><code>
   1418             car )
   1419 </code></pre>
   1420 
   1421 <p>which in turn accepts such a list and returns a number, which happens to be
   1422 the list's first element.
   1423 
   1424 <p>You can see from this example that 'get' is the inverse function of 'put'.
   1425 'get' can be omitted, however, if the chart is read-only (contains no (or only
   1426 locked) input fields).
   1427 
   1428 <p>The field in the second column
   1429 
   1430 <pre><code>
   1431                   (gui 2 '(+Lock +TextField) 90) ) ) )
   1432 </code></pre>
   1433 
   1434 <p>is locked, because it displays the text generated by 'put', and is not
   1435 supposed to accept any user input.
   1436 
   1437 <p>When you start up this form in your browser, you'll see three pre-filled
   1438 lines with "1/eins", "5/fünf" and "7/sieben", according to the
   1439 <code>+Init</code> argument <code>(1 5 7)</code>. Typing a number somewhere into
   1440 the first column, and pressing ENTER or one of the buttons, will show a suitable
   1441 text in the second column.
   1442 
   1443 
   1444 <p><hr>
   1445 <h2><a name="guiClasses">GUI Classes</a></h2>
   1446 
   1447 <p>In previous chapters we saw examples of GUI classes like
   1448 <code>+TextField</code>, <code>+NumField</code> or <code>+Button</code>, often
   1449 in combination with prefix classes like <code>+Lock</code>, <code>+Init</code>
   1450 or <code>+Able</code>. Now we take a broader look at the whole hierarchy, and
   1451 try more examples.
   1452 
   1453 <p>The abstract class <code>+gui</code> is the base of all GUI classes. A live
   1454 view of the class hierarchy can be obtained with the <code><a
   1455 href="refD.html#dep">dep</a></code> ("dependencies") function:
   1456 
   1457 <pre><code>
   1458 : (dep '+gui)
   1459 +gui
   1460    +JsField
   1461    +Button
   1462       +UpButton
   1463       +PickButton
   1464          +DstButton
   1465       +ClrButton
   1466       +ChoButton
   1467          +Choice
   1468       +GoButton
   1469       +BubbleButton
   1470       +DelRowButton
   1471       +ShowButton
   1472       +DnButton
   1473    +Img
   1474    +field
   1475       +Checkbox
   1476       +TextField
   1477          +FileField
   1478          +ClassField
   1479          +numField
   1480             +NumField
   1481             +FixField
   1482          +BlobField
   1483          +DateField
   1484          +SymField
   1485          +UpField
   1486          +MailField
   1487          +SexField
   1488          +AtomField
   1489          +PwField
   1490          +ListTextField
   1491          +LinesField
   1492          +TelField
   1493          +TimeField
   1494          +HttpField
   1495       +Radio
   1496 -> +gui
   1497 </code></pre>
   1498 
   1499 <p>We see, for example, that <code>+DnButton</code> is a subclass of
   1500 <code>+Button</code>, which in turn is a subclass of <code>+gui</code>.
   1501 Inspecting <code>+DnButton</code> directly
   1502 
   1503 <pre><code>
   1504 : (dep '+DnButton)
   1505    +Tiny
   1506    +Rid
   1507    +JS
   1508    +Able
   1509       +gui
   1510    +Button
   1511 +DnButton
   1512 -> +DnButton
   1513 </code></pre>
   1514 
   1515 <p>shows that <code>+DnButton</code> inherits from <code>+Tiny</code>,
   1516 <code>+Rid</code>, <code>+Able</code> and <code>+Button</code>. The actual
   1517 definition of <code>+DnButton</code> can be found in "@lib/form.l"
   1518 
   1519 <pre><code>
   1520 (class +DnButton +Tiny +Rid +JS +Able +Button)
   1521 ...
   1522 </code></pre>
   1523 
   1524 <p>In general, "@lib/form.l" is the ultimate reference to the framework, and
   1525 should be freely consulted.
   1526 
   1527 
   1528 <p><hr>
   1529 <h3><a name="inputFields">Input Fields</a></h3>
   1530 
   1531 <p>Input fields implement the visual display of application data, and allow -
   1532 when enabled - input and modification of these data.
   1533 
   1534 <p>On the HTML level, they can take the form of
   1535 
   1536 <ul>
   1537 <li>Normal text input fields
   1538 <li>Textareas
   1539 <li>Checkboxes
   1540 <li>Drop-down selections
   1541 <li>Password fields
   1542 <li>HTML links
   1543 <li>Plain HTML text
   1544 </ul>
   1545 
   1546 <p>Except for checkboxes, which are implemented by the <a
   1547 href="#checkboxes">Checkbox</a> class, all these HTML representations are
   1548 generated by <code>+TextField</code> and its content-specific subclasses like
   1549 <code>+NumField</code>, <code>+DateField</code> etc. Their actual appearance (as
   1550 one of the above forms) depends on their arguments:
   1551 
   1552 <p>We saw already "normal" text fields. They are created with a single numeric
   1553 argument. This example creates an editable field with a width of 10 characters:
   1554 
   1555 <pre><code>
   1556    (gui '(+TextField) 10)
   1557 </code></pre>
   1558 
   1559 <p>If you supply a second numeric for the line count ('4' in this case), you'll
   1560 get a text area:
   1561 
   1562 <pre><code>
   1563    (gui '(+TextField) 10 4)
   1564 </code></pre>
   1565 
   1566 <p>Supplying a list of values instead of a count yields a drop-down selection
   1567 (combo box):
   1568 
   1569 <pre><code>
   1570    (gui '(+TextField) '("Value 1" "Value 2" "Value 3"))
   1571 </code></pre>
   1572 
   1573 <p>In addition to these arguments, you can pass a string. Then the field is
   1574 created with a label:
   1575 
   1576 <pre><code>
   1577    (gui '(+TextField) 10 "Plain")
   1578    (gui '(+TextField) 10 4 "Text Area")
   1579    (gui '(+TextField) '("Value 1" "Value 2" "Value 3") "Selection")
   1580 </code></pre>
   1581 
   1582 <p>Finally, without any arguments, the field will appear as a plain HTML text:
   1583 
   1584 <pre><code>
   1585    (gui '(+TextField))
   1586 </code></pre>
   1587 
   1588 <p>This makes mainly sense in combination with prefix classes like
   1589 <code>+Var</code> and <code>+Obj</code>, to manage the contents of these fields,
   1590 and achieve special behavior as HTML links or scrollable chart values.
   1591 
   1592 
   1593 <h4><a name="numberFields">Numeric Input Fields</a></h4>
   1594 
   1595 <p>A <code>+NumField</code> returns a number from its <code>val&gt;</code>
   1596 method, and accepts a number for its <code>set&gt;</code> method. It issues an
   1597 error message when user input cannot be converted to a number.
   1598 
   1599 <p>Large numbers are shown with a thousands-separator, as determined by the
   1600 current locale.
   1601 
   1602 <pre><code>
   1603 ########################################################################
   1604 (app)
   1605 
   1606 (action
   1607    (html 0 "+NumField" "@lib.css" NIL
   1608       (form NIL
   1609          (gui '(+NumField) 10)
   1610          (gui '(+JS +Button) "Print value"
   1611             '(msg (val&gt; (: home gui 1))) )
   1612          (gui '(+JS +Button) "Set to 123"
   1613             '(set&gt; (: home gui 1) 123) ) ) ) )
   1614 ########################################################################
   1615 </code></pre>
   1616 
   1617 <p>A <code>+FixField</code> needs an additional scale factor argument, and
   1618 accepts/returns scaled fixpoint numbers.
   1619 
   1620 <p>The decimal separator is determined by the current locale.
   1621 
   1622 <pre><code>
   1623 ########################################################################
   1624 (app)
   1625 
   1626 (action
   1627    (html 0 "+FixField" "@lib.css" NIL
   1628       (form NIL
   1629          (gui '(+FixField) 3 10)
   1630          (gui '(+JS +Button) "Print value"
   1631             '(msg (format (val&gt; (: home gui 1)) 3)) )
   1632          (gui '(+JS +Button) "Set to 123.456"
   1633             '(set&gt; (: home gui 1) 123456) ) ) ) )
   1634 ########################################################################
   1635 </code></pre>
   1636 
   1637 
   1638 <h4><a name="timeDateFields">Time &amp; Date</a></h4>
   1639 
   1640 <p>A <code>+DateField</code> accepts and returns a <code><a
   1641 href="refD.html#date">date</a></code> value.
   1642 
   1643 <pre><code>
   1644 ########################################################################
   1645 (app)
   1646 
   1647 (action
   1648    (html 0 "+DateField" "@lib.css" NIL
   1649       (form NIL
   1650          (gui '(+DateField) 10)
   1651          (gui '(+JS +Button) "Print value"
   1652             '(msg (datStr (val&gt; (: home gui 1)))) )
   1653          (gui '(+JS +Button) "Set to \"today\""
   1654             '(set&gt; (: home gui 1) (date)) ) ) ) )
   1655 ########################################################################
   1656 </code></pre>
   1657 
   1658 <p>The format displayed to - and entered by - the user depends on the current
   1659 locale (see <code><a href="refD.html#datStr">datStr</a></code> and <code><a
   1660 href="refE.html#expDat">expDat</a></code>). You can change it, for example to
   1661 
   1662 <pre><code>
   1663 : (locale "DE" "de")
   1664 -> NIL
   1665 </code></pre>
   1666 
   1667 <p>If no locale is set, the format is YYYY-MM-DD. Some pre-defined locales use
   1668 patterns like DD.MM.YYYY (DE), YYYY/MM/DD (JP), DD/MM/YYYY (UK), or MM/DD/YYYY
   1669 (US).
   1670 
   1671 <p>An error is issued when user input does not match the current locale's date
   1672 format.
   1673 
   1674 <p>Independent from the locale setting, a <code>+DateField</code> tries to
   1675 expand abbreviated input from the user. A small number is taken as that day of
   1676 the current month, larger numbers expand to day and month, or to day, month and
   1677 year:
   1678 
   1679 <ul>
   1680 <li>"7" gives the 7th of the current month
   1681 <li>"031" or "0301" give the 3rd of January of the current year
   1682 <li>"311" or "3101" give the 31st of January of the current year
   1683 <li>"0311" gives the 3rd of November of the current year
   1684 <li>"01023" or "010203" give the first of February in the year 2003
   1685 <li>and so on
   1686 </ul>
   1687 
   1688 <p>Similar is the <code>+TimeField</code>. It accepts and returns a <code><a
   1689 href="refT.html#time">time</a></code> value.
   1690 
   1691 <pre><code>
   1692 ########################################################################
   1693 (app)
   1694 
   1695 (action
   1696    (html 0 "+TimeField" "@lib.css" NIL
   1697       (form NIL
   1698          (gui '(+TimeField) 8)
   1699          (gui '(+JS +Button) "Print value"
   1700             '(msg (tim$ (val&gt; (: home gui 1)))) )
   1701          (gui '(+JS +Button) "Set to \"now\""
   1702             '(set&gt; (: home gui 1) (time)) ) ) ) )
   1703 ########################################################################
   1704 </code></pre>
   1705 
   1706 <p>When the field width is '8', like in this example, time is displayed in the
   1707 format <code>HH:MM:SS</code>. Another possible value would be '5', causing
   1708 <code>+TimeField</code> to display its value as <code>HH:MM</code>.
   1709 
   1710 <p>An error is issued when user input cannot be converted to a time value.
   1711 
   1712 <p>The user may omit the colons. If he inputs just a small number, it should be
   1713 between '0' and '23', and will be taken as a full hour. '125' expands to
   1714 "12:05", '124517' to "12:45:17", and so on.
   1715 
   1716 
   1717 <h4><a name="telFields">Telephone Numbers</a></h4>
   1718 
   1719 <p>Telephone numbers are represented internally by the country code (without a
   1720 leading plus sign or zero) followed by the local phone number (ideally separated
   1721 by spaces) and the phone extension (ideally separated by a hyphen). The exact
   1722 format of the phone number string is not enforced by the GUI, but further
   1723 processing (e.g. database searches) normally uses <code><a
   1724 href="refF.html#fold">fold</a></code> for better reproducibility.
   1725 
   1726 <p>To display a phone number, <code>+TelField</code> replaces the country code
   1727 with a single zero if it is the country code of the current locale, or prepends
   1728 it with a plus sign if it is a foreign country (see <code><a
   1729 href="refT.html#telStr">telStr</a></code>).
   1730 
   1731 <p>For user input, a plus sign or a double zero is simply dropped, while a
   1732 single leading zero is replaced with the current locale's country code (see
   1733 <code><a href="refE.html#expTel">expTel</a></code>).
   1734 
   1735 <pre><code>
   1736 ########################################################################
   1737 (app)
   1738 (locale "DE" "de")
   1739 
   1740 (action
   1741    (html 0 "+TelField" "@lib.css" NIL
   1742       (form NIL
   1743          (gui '(+TelField) 20)
   1744          (gui '(+JS +Button) "Print value"
   1745             '(msg (val&gt; (: home gui 1))) )
   1746          (gui '(+JS +Button) "Set to \"49 1234 5678-0\""
   1747             '(set&gt; (: home gui 1) "49 1234 5678-0") ) ) ) )
   1748 ########################################################################
   1749 </code></pre>
   1750 
   1751 
   1752 <h4><a name="checkboxes">Checkboxes</a></h4>
   1753 
   1754 <p>A <code>+Checkbox</code> is straightforward. User interaction is restricted
   1755 to clicking it on and off. It accepts boolean (<code>NIL</code> or
   1756 non-<code>NIL</code>) values, and returns <code>T</code> or <code>NIL</code>.
   1757 
   1758 <pre><code>
   1759 ########################################################################
   1760 (app)
   1761 
   1762 (action
   1763    (html 0 "+Checkbox" "@lib.css" NIL
   1764       (form NIL
   1765          (gui '(+Checkbox))
   1766          (gui '(+JS +Button) "Print value"
   1767             '(msg (val&gt; (: home gui 1))) )
   1768          (gui '(+JS +Button) "On"
   1769             '(set&gt; (: home gui 1) T) )
   1770          (gui '(+JS +Button) "Off"
   1771             '(set&gt; (: home gui 1) NIL) ) ) ) )
   1772 ########################################################################
   1773 </code></pre>
   1774 
   1775 
   1776 <p><hr>
   1777 <h3><a name="fieldPrefix">Field Prefix Classes</a></h3>
   1778 
   1779 <p>A big part of this framework's power is owed to the combinatorial flexibility
   1780 of prefix classes for GUI- and DB-objects. They allow to surgically override
   1781 individual methods in the inheritance tree, and can be combined in various ways
   1782 to achieve any desired behavior.
   1783 
   1784 <p>Technically, there is nothing special about prefix classes. They are just
   1785 normal classes. They are called "prefix" because they are intended to be written
   1786 <i>before</i> other classes in a class's or object's list of superclasses.
   1787 
   1788 <p>Usually they take their own arguments for their <code>T</code> method from
   1789 the list of arguments to the <code>gui</code> function.
   1790 
   1791 
   1792 <h4><a name="initPrefix">Initialization</a></h4>
   1793 
   1794 <p><code>+Init</code> overrides the <code>init&gt;</code> method for that
   1795 component. The <code>init&gt;</code> message is sent to a <code>+gui</code>
   1796 component when the page is loaded for the first time (during a GET request).
   1797 <code>+Init</code> takes an expression for the initial value of that field.
   1798 
   1799 <pre><code>
   1800    (gui '(+Init +TextField) "This is the initial text" 30)
   1801 </code></pre>
   1802 
   1803 <p>Other classes which automatically give a value to a field are
   1804 <code>+Var</code> (linking the field to a variable) and <code>+E/R</code>
   1805 (linking the field to a database entity/relation).
   1806 
   1807 <p><code>+Cue</code> can be used, for example in "mandatory" fields, to give a
   1808 hint to the user about what he is supposed to enter. It will display the
   1809 argument value, in angular brackets, if and only if the field's value is
   1810 <code>NIL</code>, and the <code>val&gt;</code> method will return
   1811 <code>NIL</code> despite the fact that this value is displayed.
   1812 
   1813 <p>Cause an empty field to display "&lt;Please enter some text here&gt;":
   1814 
   1815 <pre><code>
   1816    (gui '(+Cue +TextField) "Please enter some text here" 30)
   1817 </code></pre>
   1818 
   1819 
   1820 <h4><a name="ablePrefix">Disabling and Enabling</a></h4>
   1821 
   1822 <p>An important feature of an interactive GUI is the context-sensitive disabling
   1823 and enabling of individual components, or of a whole form.
   1824 
   1825 <p>The <code>+Able</code> prefix class takes an argument expression, and
   1826 disables the component if this expression returns <code>NIL</code>. We saw an
   1827 example for its usage already in the <a href="#sqrtButton">square root
   1828 button</a> of the calculator example. Or, for illustration purposes, imagine a
   1829 button which is supposed to be enabled only after Christmas
   1830 
   1831 <pre><code>
   1832    (gui '(+Able +Button)
   1833       '(>= (cdr (date (date))) (12 24))
   1834       "Close this year"
   1835       '(endOfYearProcessing) )
   1836 </code></pre>
   1837 
   1838 <p>or a password field that is disabled as long as somebody is logged in
   1839 
   1840 <pre><code>
   1841    (gui '(+Able +PwField) '(not *Login) 10 "Password")
   1842 </code></pre>
   1843 
   1844 <p>A special case is the <code>+Lock</code> prefix, which permanently and
   1845 unconditionally disables a component. It takes no arguments
   1846 
   1847 <pre><code>
   1848    (gui '(+Lock +NumField) 10 "Count")
   1849 </code></pre>
   1850 
   1851 <p>('10' and "Count" are for the <code>+NumField</code>), and creates a
   1852 read-only field.
   1853 
   1854 <p>The whole form can be disabled by calling <code>disable</code> with a
   1855 non-<code>NIL</code> argument. This affects all components in this form. Staying
   1856 with the above example, we can make the form read-only until Christmas
   1857 
   1858 <pre><code>
   1859    (form NIL
   1860       (disable (> (12 24) (cdr (date (date)))))  # Disable whole form
   1861       (gui ..)
   1862       .. )
   1863 </code></pre>
   1864 
   1865 <p>Even in a completely disabled form, however, it is often necessary to
   1866 re-enable certain components, as they are needed for navigation, scrolling, or
   1867 other activities which don't affect the contents of the form. This is done by
   1868 prefixing these fields with <code>+Rid</code> (i.e. getting "rid" of the lock).
   1869 
   1870 <pre><code>
   1871    (form NIL
   1872       (disable (> (12 24) (cdr (date (date)))))
   1873       (gui ..)
   1874       ..
   1875       (gui '(+Rid +Button) ..)  # Button is enabled despite the disabled form
   1876       .. )
   1877 </code></pre>
   1878 
   1879 
   1880 <h4><a name="formatPrefix">Formatting</a></h4>
   1881 
   1882 <p>GUI prefix classes allow a fine-grained control of how values are stored in -
   1883 and retrieved from - components. As in predefined classes like
   1884 <code>+NumField</code> or <code>+DateField</code>, they override the
   1885 <code>set&gt;</code> and/or <code>val&gt;</code> methods.
   1886 
   1887 <p><code>+Set</code> takes an argument function which is called whenever that
   1888 field is set to some value. To convert all user input to upper case
   1889 
   1890 <pre><code>
   1891    (gui '(+Set +TextField) uppc 30)
   1892 </code></pre>
   1893 
   1894 <p><code>+Val</code> is the complement to <code>+Set</code>. It takes a function
   1895 which is called whenever the field's value is retrieved. To return the square of
   1896 a field's value
   1897 
   1898 <pre><code>
   1899    (gui '(+Val +NumField) '((N) (* N N)) 10)
   1900 </code></pre>
   1901 
   1902 <p><code>+Fmt</code> is just a combination of <code>+Set</code> and
   1903 <code>+Val</code>, and takes two functional arguments. This example will display
   1904 upper case characters, while returning lower case characters internally
   1905 
   1906 <pre><code>
   1907    (gui '(+Fmt +TextField) uppc lowc 30)
   1908 </code></pre>
   1909 
   1910 <p><code>+Map</code> does (like <code>+Fmt</code>) a two-way translation. It
   1911 uses a list of cons pairs for a linear lookup, where the CARs represent the
   1912 displayed values which are internally mapped to the values in the CDRs. If a
   1913 value is not found in this list during <code>set&gt;</code> or
   1914 <code>val&gt;</code>, it is passed through unchanged.
   1915 
   1916 <p>Normally, <code>+Map</code> is used in combination with the combo box
   1917 incarnation of text fields (see <a href="#inputFields">Input Fields</a>). This
   1918 example displays "One", "Two" and "Three" to the user, but returns a number 1, 2
   1919 or 3 internally
   1920 
   1921 <pre><code>
   1922 ########################################################################
   1923 (app)
   1924 
   1925 (action
   1926    (html 0 "+Map" "@lib.css" NIL
   1927       (form NIL
   1928          (gui '(+Map +TextField)
   1929             '(("One" . 1) ("Two" . 2) ("Three" . 3))
   1930             '("One" "Two" "Three") )
   1931          (gui '(+Button) "Print"
   1932             '(msg (val> (field -1))) ) ) ) )
   1933 ########################################################################
   1934 </code></pre>
   1935 
   1936 
   1937 <h4><a name="sideEffects">Side Effects</a></h4>
   1938 
   1939 <p>Whenever a button is pressed in the GUI, any changes caused by
   1940 <code>action</code> in the current environment (e.g. the database or application
   1941 state) need to be reflected in the corresponding GUI fields. For that, the
   1942 <code>upd&gt;</code> message is sent to all components. Each component then
   1943 takes appropriate measures (e.g. refresh from database objects, load values from
   1944 variables, or calculate a new value) to update its value.
   1945 
   1946 <p>While the <code>upd&gt;</code> method is mainly used internally, it can be
   1947 overridden in existing classes via the <code>+Upd</code> prefix class. Let's
   1948 print updated values to standard error
   1949 
   1950 <pre><code>
   1951 ########################################################################
   1952 (app)
   1953 (default *Number 0)
   1954 
   1955 (action
   1956    (html 0 "+Upd" "@lib.css" NIL
   1957       (form NIL
   1958          (gui '(+Upd +Var +NumField)
   1959             '(prog (extra) (msg *Number))
   1960             '*Number 8 )
   1961          (gui '(+JS +Button) "Increment"
   1962             '(inc '*Number) ) ) ) )
   1963 ########################################################################
   1964 </code></pre>
   1965 
   1966 
   1967 <h4><a name="validPrefix">Validation</a></h4>
   1968 
   1969 <p>To allow automatic validation of user input, the <code>chk&gt;</code> message
   1970 is sent to all components at appropriate times. The corresponding method should
   1971 return <code>NIL</code> if the value is all right, or a string describing the
   1972 error otherwise.
   1973 
   1974 <p>Many of the built-in classes have a <code>chk&gt;</code> method. The
   1975 <code>+NumField</code> class checks for legal numeric input, or the
   1976 <code>+DateField</code> for a valid calendar date.
   1977 
   1978 <p>An on-the-fly check can be implemented with the <code>+Chk</code> prefix
   1979 class. The following code only accepts numbers not bigger than 9: The
   1980 <code>or</code> expression first delegates the check to the main
   1981 <code>+NumField</code> class, and - if it does not give an error - returns an
   1982 error string when the current value is greater than 9.
   1983 
   1984 <pre><code>
   1985 ########################################################################
   1986 (app)
   1987 
   1988 (action
   1989    (html 0 "+Chk" "@lib.css" NIL
   1990       (form NIL
   1991          (gui '(+Chk +NumField)
   1992             '(or
   1993                (extra)
   1994                (and (&gt; (val&gt; This) 9) "Number too big") )
   1995             12 )
   1996          (gui '(+JS +Button) "Print"
   1997             '(msg (val&gt; (field -1))) ) ) ) )
   1998 ########################################################################
   1999 </code></pre>
   2000 
   2001 <p>A more direct kind of validation is built-in via the <code>+Limit</code>
   2002 class. It controls the <code>maxlength</code> attribute of the generated HTML
   2003 input field component. Thus, it is impossible to type to more characters than
   2004 allowed into the field.
   2005 
   2006 <pre><code>
   2007 ########################################################################
   2008 (app)
   2009 
   2010 (action
   2011    (html 0 "+Limit" "@lib.css" NIL
   2012       (form NIL
   2013          (gui '(+Limit +TextField) 4 8)
   2014          (gui '(+JS +Button) "Print"
   2015             '(msg (val&gt; (field -1))) ) ) ) )
   2016 ########################################################################
   2017 </code></pre>
   2018 
   2019 
   2020 <h4><a name="linkage">Data Linkage</a></h4>
   2021 
   2022 <p>Although <code>set&gt;</code> and <code>val&gt;</code> are the official
   2023 methods to get a value in and out of a GUI component, they are not very often
   2024 used explicitly. Instead, components are directly linked to internal Lisp data
   2025 structures, which are usually either variables or database objects.
   2026 
   2027 <p>The <code>+Var</code> prefix class takes a variable (described as the
   2028 <code>var</code> data type - either a symbol or a cons pair - in the <a
   2029 href="ref.html#fun">Function Reference</a>). In the following example, we
   2030 initialize a global variable with the value "abc", and let a
   2031 <code>+TextField</code> operate on it. The "Print" button can be used to display
   2032 its current value.
   2033 
   2034 <pre><code>
   2035 ########################################################################
   2036 (app)
   2037 
   2038 (setq *TextVariable "abc")
   2039 
   2040 (action
   2041    (html 0 "+Var" "@lib.css" NIL
   2042       (form NIL
   2043          (gui '(+Var +TextField) '*TextVariable 8)
   2044          (gui '(+JS +Button) "Print"
   2045             '(msg *TextVariable) ) ) ) )
   2046 ########################################################################
   2047 </code></pre>
   2048 
   2049 <p><code>+E/R</code> takes an entity/relation specification. This is a cons
   2050 pair, with a relation in its CAR (e.g. <code>nm</code>, for an object's name),
   2051 and an expression in its CDR (typically <code>(: home obj)</code>, the object
   2052 stored in the <code>obj</code> property of the current form).
   2053 
   2054 <p>For an isolated, simple example, we create a temporary database, and access
   2055 the <code>nr</code> and <code>nm</code> properties of an object stored in a
   2056 global variable <code>*Obj</code>.
   2057 
   2058 <pre><code>
   2059 ########################################################################
   2060 (when (app)                # On start of session
   2061    (class +Tst +Entity)    # Define data model
   2062    (rel nr (+Number))      # with a number
   2063    (rel nm (+String))      # and a string
   2064    (pool (tmp "db"))       # Create temporary DB
   2065    (setq *Obj              # and a single object
   2066       (new! '(+Tst) 'nr 1 'nm "New Object") ) )
   2067 
   2068 (action
   2069    (html 0 "+E/R" "@lib.css" NIL
   2070       (form NIL
   2071          (gui '(+E/R +NumField) '(nr . *Obj) 8)    # Linkage to 'nr'
   2072          (gui '(+E/R +TextField) '(nm . *Obj) 20)  # Linkage to 'nm'
   2073          (gui '(+JS +Button) "Show"                # Show the object
   2074             '(out 2 (show *Obj)) ) ) ) )           # on standard error
   2075 ########################################################################
   2076 </code></pre>
   2077 
   2078 
   2079 <p><hr>
   2080 <h3><a name="buttons">Buttons</a></h3>
   2081 
   2082 <p>Buttons are, as explained in <a href="#ctlFlow">Control Flow</a>, the only
   2083 way (via POST requests) for an application to communicate with the server.
   2084 
   2085 <p>Basically, a <code>+Button</code> takes
   2086 
   2087 <ul>
   2088 <li>a label, which may be either a string or the name of an image file
   2089 <li>an optional alternative label, shown when the button is disabled
   2090 <li>and an executable expression.
   2091 </ul>
   2092 
   2093 <p>Here is a minimal button, with just a label and an expression:
   2094 
   2095 <pre><code>
   2096    (gui '(+Button) "Label" '(doSomething))
   2097 </code></pre>
   2098 
   2099 <p>And this is a button displaying different labels, depending on the state:
   2100 
   2101 <pre><code>
   2102    (gui '(+Button) "Enabled" "Disabled" '(doSomething))
   2103 </code></pre>
   2104 
   2105 <p>To show an image instead of plain text, the label(s) must be preceeded by the
   2106 <code>T</code> symbol:
   2107 
   2108 <pre><code>
   2109    (gui '(+Button) T "img/enabled.png" "img/disabled.png" '(doSomething))
   2110 </code></pre>
   2111 
   2112 <p>The expression will be executed during <code>action</code> handling (see <a
   2113 href="#actionForms">Action Forms</a>), when this button was pressed.
   2114 
   2115 <p>Like other components, buttons can be extended and combined with prefix
   2116 classes, and a variety of predefined classes and class combinations are
   2117 available.
   2118 
   2119 
   2120 <h4><a name="dialogButtons">Dialog Buttons</a></h4>
   2121 
   2122 <p>Buttons are essential for the handling of <a href="#dialogs">alerts and
   2123 dialogs</a>. Besides buttons for normal functions, like <a
   2124 href="#scrolling">scrolling</a> in charts or other <a href="#sideEffects">side
   2125 effects</a>, special buttons exist which can <i>close</i> an alert or dialog in
   2126 addition to doing their principal job.
   2127 
   2128 <p>Such buttons are usually subclasses of <code>+Close</code>, and most of them
   2129 can be called easily with ready-made functions like <code>closeButton</code>,
   2130 <code>cancelButton</code>, <code>yesButton</code> or <code>noButton</code>. We
   2131 saw a few examples in <a href="#dialogs">Alerts and Dialogs</a>.
   2132 
   2133 
   2134 <h4><a name="jsButtons">Active JavaScript</a></h4>
   2135 
   2136 <p>When a button inherits from the <code>+JS</code> class (and JavaScript is
   2137 enabled in the browser), that button will possibly show a much faster response
   2138 in its action.
   2139 
   2140 <p>The reason is that the activation of a <code>+JS</code> button will - instead
   2141 of doing a normal POST - first try to send only the contents of all GUI
   2142 components via an XMLHttpRequest to the server, and receive the updated values
   2143 in response. This avoids the flicker caused by reloading and rendering of the
   2144 whole page, is much faster, and also does not jump to the beginning of the page
   2145 if it is larger than the browser window. The effect is especially noticeable
   2146 while scrolling in charts.
   2147 
   2148 <p>Only if this fails, for example because an error message was issued, or a
   2149 dialog popped up, it will fall back, and the form will be POSTed in the normal
   2150 way.
   2151 
   2152 <p>Thus it makes no sense to use the <code>+JS</code> prefix for buttons that
   2153 cause a change of the HTML code, open a dialog, or jump to another page. In such
   2154 cases, overall performance will even be worse, because the XMLHttpRequest is
   2155 tried first (but in vain).
   2156 
   2157 <p>When JavaScript is disabled int the browser, the XMLHttpRequest will not be
   2158 tried at all. The form will be fully usable, though, with identical
   2159 functionality and behavior, just a bit slower and not so smooth.
   2160 
   2161 
   2162 <p><hr>
   2163 <h2><a name="minApp">A Minimal Complete Application</a></h2>
   2164 
   2165 <p>The PicoLisp release includes in the "app/" directory a minimal, yet complete
   2166 reference application. This application is typical, in the sense that it
   2167 implements many of the techniques described in this document, and it can be
   2168 easily modified and extended. In fact, we use it as templates for our own
   2169 production application development.
   2170 
   2171 <p>It is a kind of simplified ERP system, containing customers/suppliers,
   2172 products (items), orders, and other data. The order input form performs live
   2173 updates of customer and product selections, price, inventory and totals
   2174 calculations, and generates on-the-fly PDF documents. Fine-grained access
   2175 permissions are controlled via users, roles and permissions. It comes localized
   2176 in six languages (English, Spanish, German, Norwegian, Russian and Japanese),
   2177 with some initial data and two sample reports.
   2178 
   2179 
   2180 <p><hr>
   2181 <h3><a name="getStarted">Getting Started</a></h3>
   2182 
   2183 <p>For a global installation (see <a href="ref.html#inst">Installation</a>),
   2184 please create a symbolic link to the place where the program files are
   2185 installed. This is necessary because the application needs read/write access to
   2186 the current working directory (for the database and other runtime data).
   2187 
   2188 <pre><code>
   2189 $ ln -s /usr/share/picolisp/app
   2190 </code></pre>
   2191 
   2192 <p>As ever, you may start up the application in debugging mode
   2193 
   2194 <pre><code>
   2195 $ pil app/main.l -main -go +
   2196 </code></pre>
   2197 
   2198 <p>or in (non-debug) production mode
   2199 
   2200 <pre><code>
   2201 $ pil app/main.l -main -go -wait
   2202 </code></pre>
   2203 
   2204 <p>and go to '<code><a
   2205 href="http://localhost:8080">http://localhost:8080</a></code>' with your
   2206 browser. You can login as user "admin", with password "admin". The demo data
   2207 contain several other users, but those are more restricted in their role
   2208 permissions.
   2209 
   2210 <p>Another possibility is to try the online version of this application at <a
   2211 href="http://app.7fach.de">app.7fach.de</a>.
   2212 
   2213 
   2214 <h4><a name="localization">Localization</a></h4>
   2215 
   2216 <p>Before or after you logged in, you can select another language, and click on
   2217 the "Change" button. This will effect all GUI components (though not text from
   2218 the database), and also the numeric, date and telephone number formats.
   2219 
   2220 
   2221 <h4><a name="navigation">Navigation</a></h4>
   2222 
   2223 <p>The navigation menu on the left side shows two items "Home" and "logout", and
   2224 three submenus "Data", "Report" and "System".
   2225 
   2226 <p>Both "Home" and "logout" bring you back to the initial login form. Use
   2227 "logout" if you want to switch to another user (say, for another set of
   2228 permissions), and - more important - before you close your browser, to release
   2229 possible locks and process resources on the server.
   2230 
   2231 <p>The "Data" submenu gives access to application specific data entry and
   2232 maintenance: Orders, product items, customers and suppliers. The "Report"
   2233 submenu contains two simple inventory and sales reports. And the "System"
   2234 submenu leads to role and user administration.
   2235 
   2236 <p>You can open and close each submenu individually. Keeping more than one
   2237 submenu open at a time lets you switch rapidly between different parts of the
   2238 application.
   2239 
   2240 <p>The currently active menu item is indicated by a highlighted list style (no
   2241 matter whether you arrived at this page directly via the menu or by clicking on
   2242 a link somewhere else).
   2243 
   2244 
   2245 <h4><a name="choosing">Choosing Objects</a></h4>
   2246 
   2247 <p>Each item in the "Data" or "System" submenu opens a search dialog for that
   2248 class of entities. You can specify a search pattern, press the top right
   2249 "Search" button (or just ENTER), and scroll through the list of results.
   2250 
   2251 <p>While the "Role" and "User" entities present simple dialogs (searching just
   2252 by name), other entities can be searched by a variety of criteria. In those
   2253 cases, a "Reset" button clears the contents of the whole dialog. A new object
   2254 can be created with bottom right "New" button.
   2255 
   2256 <p>In any case, the first column will contain either a "@"-link (to jump to that
   2257 object) or a "@"-button (to insert a reference to that object into the current
   2258 form).
   2259 
   2260 <p>By default, the search will list all database objects with an attribute value
   2261 greater than or equal to the search criterion. The comparison is done
   2262 arithmetically for numbers, and alphabetically (case sensitive!) for text. This
   2263 means, if you type "Free" in the "City" field of the "Customer/Supplier" dialog,
   2264 the value of "Freetown" will be matched. On the other hand, an entry of "free"
   2265 or "town" will yield no hits.
   2266 
   2267 <p>Some search fields, however, show a different behavior depending on the
   2268 application:
   2269 
   2270 <ul>
   2271 <li>The names of persons, companies or products allow a tolerant search,
   2272 matching either a slightly misspelled name ("Mühler" instead of "Miller") or a
   2273 substring ("Oaks" will match "Seven Oaks Ltd.").
   2274 
   2275 <li>The search field may specify an upper instead of a lower limit, resulting in
   2276 a search for database objects with an attribute value less than or equal to the
   2277 search criterion. This is useful, for example in the "Order" dialog, to list
   2278 orders according to their number or date, by starting with the newest then and
   2279 going backwards.
   2280 
   2281 </ul>
   2282 
   2283 <p>Using the bottom left scroll buttons, you can scroll through the result list
   2284 without limit. Clicking on a link will bring up the corresponding object. Be
   2285 careful here to select the right column: Some dialogs (those for "Item" and
   2286 "Order") also provide links for related entities (e.g. "Supplier").
   2287 
   2288 
   2289 <h4><a name="editing">Editing</a></h4>
   2290 
   2291 <p>A database object is usually displayed in its own individual form, which is
   2292 determined by its entity class.
   2293 
   2294 <p>The basic layout should be consistent for all classes: Below the heading
   2295 (which is usually the same as the invoking menu item) is the object's identifier
   2296 (name, number, etc.), and then a row with an "Edit" button on the left, and
   2297 "Delete" button, a "Select" button and two navigation links on the right side.
   2298 
   2299 <p>The form is brought up initially in read-only mode. This is necessary to
   2300 prevent more than one user from modifying an object at the same time (and
   2301 contrary to the previous PicoLisp Java frameworks, where this was not a problem
   2302 because all changes were immediately reflected in the GUIs of other users).
   2303 
   2304 <p>So if you want to modify an object, you have to gain exclusive access by
   2305 clicking on the "Edit" button. The form will be enabled, and the "Edit" button
   2306 changes to "Done". Should any other user already have reserved this object, you
   2307 will see a message telling his name and process ID.
   2308 
   2309 <p>An exception to this are objects that were just created with "New". They will
   2310 automatically be reserved for you, and the "Edit" button will show up as "Done".
   2311 
   2312 <p>The "Delete" button pops up an alert, asking for confirmation. If the object
   2313 is indeed deleted, this button changes to "Restore" and allows to undelete the
   2314 object. Note that objects are never completely deleted from the database as long
   2315 as there are any references from other objects. When a "deleted" object is
   2316 shown, its identifier appears in square brackets.
   2317 
   2318 <p>The "Select" button (re-)displays the search dialog for this class of
   2319 entities. The search criteria are preserved between invocations of each dialog,
   2320 so that you can conveniently browse objects in this context.
   2321 
   2322 <p>The navigation links, pointing left and right, serve a similar purpose. They
   2323 let you step sequentially through all objects of this class, in the order of the
   2324 identifier's index.
   2325 
   2326 <p>Other buttons, depending on the entity, are usually arranged at the bottom of
   2327 the form. The bottom rightmost one should always be another "Edit" / "Done"
   2328 button.
   2329 
   2330 <p>As we said in the chapter on <a href="#scrolling">Scrolling</a>, any button
   2331 in the form will save changes to the underlying data model. As a special case,
   2332 however, the "Done" button releases the object and reverts to "Edit". Besides
   2333 this, the edit mode will also cease as soon as another object is displayed, be
   2334 it by clicking on an object link (the pencil icon), the top right navigation
   2335 links, or a link in a search dialog.
   2336 
   2337 
   2338 <h4><a name="btnLinks">Buttons vs. Links</a></h4>
   2339 
   2340 <p>The only way to interact with a HTTP-based application server is to click
   2341 either on a HTML link, or on a submit button (see also <a
   2342 href="#ctlFlow">Control Flow</a>). It is essential to understand the different
   2343 effects of such a click on data entered or modified in the current form.
   2344 
   2345 <ul>
   2346 <li>A click on a link will leave or reload the page. Changes are discarded.
   2347 <li>A click on a button will commit changes, and perform the associated action.
   2348 </ul>
   2349 
   2350 <p>For that reason the layout design should clearly differentiate between links
   2351 and buttons. Image buttons are not a good idea when in other places images are
   2352 used for links. The standard button components should be preferred; they are
   2353 usually rendered by the browser in a non-ambiguous three-dimensional look and
   2354 feel.
   2355 
   2356 <p>Note that if JavaScript is enabled in the browser, changes will be
   2357 automatically committed to the server.
   2358 
   2359 <p>The enabled or disabled state of a button is an integral part of the
   2360 application logic. It must be indicated to the user with appropriate styles.
   2361 
   2362 
   2363 <p><hr>
   2364 <h3><a name="dataModel">The Data Model</a></h3>
   2365 
   2366 <p>The data model for this mini application consists of only six entity classes
   2367 (see the E/R diagram at the beginning of "app/er.l"):
   2368 
   2369 <ul>
   2370 <li>The three main entities are <code>+CuSu</code> (Customer/Supplier),
   2371 <code>+Item</code> (Product Item) and <code>+Ord</code> (Order).
   2372 
   2373 <li>A <code>+Pos</code> object is a single position in an order.
   2374 
   2375 <li><code>+Role</code> and <code>+User</code> objects are needed for
   2376 authentication and authorization.
   2377 
   2378 </ul>
   2379 
   2380 <p>The classes <code>+Role</code> and <code>+User</code> are defined in
   2381 "@lib/adm.l". A <code>+Role</code> has a name, a list of permissions, and a list
   2382 of users assigned to this role. A <code>+User</code> has a name, a password and
   2383 a role.
   2384 
   2385 <p>In "app/er.l", the <code>+Role</code> class is extended to define an
   2386 <code>url&gt;</code> method for it. Any object whose class has such a method is
   2387 able to display itself in the GUI. In this case, the file "app/role.l" will be
   2388 loaded - with the global variable <code>*ID</code> pointing to it - whenever an
   2389 HTML link to this role object is activated.
   2390 
   2391 <p>The <code>+User</code> class is also extended. In addition to the login name,
   2392 a full name, telephone number and email address is declared. And, of course, the
   2393 ubiquitous <code>url&gt;</code> method.
   2394 
   2395 <p>The application logic is centered around orders. An order has a number, a
   2396 date, a customer (an instance of <code>+CuSu</code>) and a list of positions
   2397 (<code>+Pos</code> objects). The <code>sum&gt;</code> method calculates the
   2398 total amount of this order.
   2399 
   2400 <p>Each position has an <code>+Item</code> object, a price and a quantity. The
   2401 price in the position overrides the default price from the item.
   2402 
   2403 <p>Each item has a number, a description, a supplier (also an instance of
   2404 <code>+CuSu</code>), an inventory count (the number of these items that were
   2405 counted at the last inventory taking), and a price. The <code>cnt&gt;</code>
   2406 method calculates the current stock of this item as the difference of the
   2407 inventory and the sold item counts.
   2408 
   2409 <p>The call to <code>dbs</code> at the end of "app/er.l" configures the physical
   2410 database storage. Each of the supplied lists has a number in its CAR which
   2411 determines the block size as (64 &lt;&lt; N) of the corresponding database file.
   2412 The CDR says that the instances of this class (if the element is a class symbol)
   2413 or the tree nodes (if the element is a list of a class symbol and a property
   2414 name) are to be placed into that file. This allows for some optimizations in the
   2415 database layout.
   2416 
   2417 
   2418 <p><hr>
   2419 <h3><a name="usage">Usage</a></h3>
   2420 
   2421 <p>When you are connected to the application (see <a href="#getStarted">Getting
   2422 Started</a>) you might try to do some "real" work with it. Via the "Data" menu
   2423 (see <a href="#navigation">Navigation</a>) you can create or modify customers,
   2424 suppliers, items and orders, and produce simple overviews via the "Report" menu.
   2425 
   2426 
   2427 <h4><a name="cuSu">Customer/Supplier</a></h4>
   2428 
   2429 <p align=right>Source in "app/cusu.l"
   2430 
   2431 <p>The Customer/Supplier search dialog (<code>choCuSu</code> in "app/gui.l")
   2432 supports a lot of search criteria. These become necessary when the database
   2433 contains a large number of customers, and can filter by zip, by phone number
   2434 prefixes, and so on.
   2435 
   2436 <p>In addition to the basic layout (see <a href="#editing">Editing</a>), the
   2437 form is divided into four separate tabs. Splitting a form into several tabs
   2438 helps to reduce traffic, with possibly better GUI response. In this case, four
   2439 tabs are perhaps overkill, but ok for demonstration purposes, and they leave
   2440 room for extensions.
   2441 
   2442 <p>Be aware that when data were modified in one of the tabs, the "Done" button
   2443 has to be pressed before another tab is clicked, because tabs are implemented as
   2444 HTML links (see <a href="#btnLinks">Buttons vs. Links</a>).
   2445 
   2446 <p>New customers or suppliers will automatically be assigned the next free
   2447 number. You can enter another number, but an error will result if you try to use
   2448 an existing number. The "Name" field is mandatory, you need to overwrite the
   2449 "&lt;Name&gt;" clue.
   2450 
   2451 <p>Phone and fax numbers in the "Contact" tab must be entered in the correct
   2452 format, depending on the locale (see <a href="#telFields">Telephone
   2453 Numbers</a>).
   2454 
   2455 <p>The "Memo" tab contains a single text area. It is no problem to use it for
   2456 large pieces of text, as it gets stored in a database blob internally.
   2457 
   2458 
   2459 <h4><a name="item">Item</a></h4>
   2460 
   2461 <p align=right>Source in "app/item.l"
   2462 
   2463 <p>Items also have a unique number, and a mandatory "Description" field.
   2464 
   2465 <p>To assign a supplier, click on the "+" button. The Customer/Supplier search
   2466 dialog will appear, and you can pick the desired supplier with the "@" button in
   2467 the first column. Alternatively, if you are sure to know the exact spelling of
   2468 the supplier's name, you can also enter it directly into the text field.
   2469 
   2470 <p>In the search dialog you may also click on a link, for example to inspect a
   2471 possible supplier, and then return to the search dialog with the browser's back
   2472 button. The "Edit" mode will then be lost, however, as another object has been
   2473 visited (this is described in the last part of <a href="#editing">Editing</a>).
   2474 
   2475 <p>You can enter an inventory count, the number of items currently in stock. The
   2476 following field will automatically reflect the remaining pieces after some of
   2477 these items were sold (i.e. referenced in order positions). It cannot be changed
   2478 manually.
   2479 
   2480 <p>The price should be entered with the decimal separator according to the
   2481 current locale. It will be formatted with two places after the decimal
   2482 separator.
   2483 
   2484 <p>The "Memo" is for an arbitrary info text, like in <a
   2485 href="#cuSu">Customer/Supplier</a> above, stored in a database blob.
   2486 
   2487 <p>Finally, a JPEG picture can be stored in a blob for this item. Choose a file
   2488 with the browser's file select control, and click on the "Install" button. The
   2489 picture will appear at the bottom of the page, and the "Install" button changes
   2490 to "Uninstall", allowing the picture's removal.
   2491 
   2492 
   2493 <h4><a name="order">Order</a></h4>
   2494 
   2495 <p align=right>Source in "app/ord.l"
   2496 
   2497 <p>Oders are identified by number and date.
   2498 
   2499 <p>The number must be unique. It is assigned when the order is created, and
   2500 cannot be changed for compliance reasons.
   2501 
   2502 <p>The date is initialized to "today" for a newly created order, but may be
   2503 changed manually. The date format depends on the locale. It is YYYY-MM-DD (ISO)
   2504 by default, DD.MM.YYYY in the German and YYYY/MM/DD in the Japanese locale. As
   2505 described in <a href="#timeDateFields">Time &amp; Date</a>, this field allows
   2506 input shortcuts, e.g. just enter the day to get the full date in the current
   2507 month.
   2508 
   2509 <p>To assign a customer to this order, click on the "+" button. The
   2510 Customer/Supplier search dialog will appear, and you can pick the desired
   2511 customer with the "@" button in the first column (or enter the name directly
   2512 into the text field), just as described above for <a href="#item">Item</a>s.
   2513 
   2514 <p>Now enter order the positions: Choose an item with the "+" button. The
   2515 "Price" field will be preset with the item's default price, you may change it
   2516 manually. Then enter a quantity, and click a button (typically the "+" button to
   2517 select the next item, or a scroll button go down in the chart). The form will be
   2518 automatically recalculated to show the total prices for this position and the
   2519 whole order.
   2520 
   2521 <p>Instead of the "+" or scroll buttons, as recommended above, you could of
   2522 course also press the "Done" button to commit changes. This is all right, but
   2523 has the disadvantage that the button must be pressed a second time (now "Edit")
   2524 if you want to continue with the entry of more positions.
   2525 
   2526 <p>The "x" button at the right of each position deletes that position without
   2527 further confirmation. It has to be used with care!
   2528 
   2529 <p>The "^" button is a "bubble" button. It exchanges a row with the row above it.
   2530 Therefore, it can be used to rearrange all items in a chart, by "bubbling" them
   2531 to their desired positions.
   2532 
   2533 <p>The "PDF-Print" button generates and displays a PDF document for this order.
   2534 The browser should be configured to display downloaded PDF documents in an
   2535 appropriate viewer. The source for the postscript generating method is in
   2536 "app/lib.l". It produces one or several A4 sized pages, depending on the number
   2537 of positions.
   2538 
   2539 
   2540 <h4><a name="reports">Reports</a></h4>
   2541 
   2542 <p align=right>Sources in "app/inventory.l and "app/sales.l"
   2543 
   2544 <p>The two reports ("Inventory" and "Sales") come up with a few search fields
   2545 and a "Show" button.
   2546 
   2547 <p>If no search criteria are entered, the "Show" button will produce a listing
   2548 of the relevant part of the whole database. This may take a long time and cause
   2549 a heavy load on the browser if the database is large.
   2550 
   2551 <p>So in the normal case, you will limit the domain by stating a range of item
   2552 numbers, a description pattern, and/or a supplier for the inventory report, or a
   2553 range of order dates and/or a customer for the sales report. If a value in a
   2554 range specification is omitted, the range is considered open in that direction.
   2555 
   2556 <p>At the end of each report appears a "CSV" link. It downloads a file with the
   2557 TAB-separated values generated by this report.
   2558 
   2559 </body>
   2560 </html>