Now that we have covered the basics of object-oriented programming in PicoLisp, we can finally start with the PicoLisp GUI framework!
What is the PicoLisp GUI framework?
The PicoLisp GUI framework is a set of objects and classes that allow a very efficient and simplified way to define user interactive forms.
They are organized within the
form function and sent to the server via
POST is always redirected back to the current page and is triggered by a button press. As we will see, a button's action code can do almost anything: Read and modify the contents of input fields, communicate with the database, display alerts and dialogs, or even fake the POST request to a GET, with the effect of showing a completely different document.
Checking out the source code
The PicoLisp GUI framework is defined in the library
form.l. You can find it in the
lib-Folder of your PicoLisp installation (or type
$ locate "lib/form.l" in your terminal). The framework is organized in classes: Each GUI element has its own class, and we can modify and extend its behaviour by using Prefix-Classes.
The library also has its own documentation, available at software-lab.de/doc/form/form.html.
Before we dive into the theory, let's take a look at an example - our previously defined
first Name, last Name-example.
(setq *Css '("@lib.css" "bootstrap.css")) (app) (action (html 0 "Simple Session" *Css NIL (form NIL (gui 'a '(+TextField) 30 "First Name") (<br>) (gui 'b '(+TextField) 30 "Last Name") (gui '(+Button) "Send" ) ) ) )
This is the output we get:
Ctrl-U in the browser (Firefox), we can also view the source code.
As you can see, we have two
<input type="text"> fields with name
id2-2, and an
<input type="submit" with name
*Gui:-3 and an id
The input fields are surrounded by a
method=post and an
action=<some auto-generated link>. If we fill in the form and click on "Send", we see that the URL changes to
So far so good, but how does it work? Let's review again the source code and check what functions we have:
(action (html (form NIL (gui 'a '(+TextField) 30 "First Name") ... ) ) )
We will go through it step by step with help fo the form library reference.
The top function is
action. From the documentation, we learn that it's "only" a wrapper function:
Top level wrapper function for the form event handling. Typically contains one or several calls to
Then we get to the
form function, which is the wrapper function for the form elements.
form, we can find many calls to a function called
gui is only defined inside a
form function and takes the following parameters:
- an alias name for the component (optional)
- a list of classes that define the GUI-element, for example
- additional arguments as needed by the constructors of these classes.
All gui-classes are subclasses of the abstract class
+gui. We can list them all by viewing the dependency tree of
: (dep '+gui) +gui +Img +field +Radio +TextField (...) +Button (...) -> +gui
Let's take a closer look at
+TextField class can be defined by several arguments:
(gui '(+TextField)): Plain HTML text is created.
(gui '(+TextField) 10): A text field of length 10 is created.
(gui '(+TextField) 10 4): A text field of length 10 and 4 lines is created.
(gui '(+TextField) '("Value 1" "Value 2" "Value 3")): a drop-down selection.
(gui '(+TextField) '("Value1" "Value2" "Value3") "Please choose: ")Strings are used as labels.
In rendered form, it looks like this:
+Button takes several arguments as well:
- A label, which may be either a string or the name of an image file,
- An optional, alternative label which is shown when the button is disabled,
- An optional executable expression.
The button works as
submit-element that sends the form data via
POST and causes the reloading of the page with updated data.
Accessing the data
Now we come to an important point: where can we find the data that we have collected?
If you remember the Object-Oriented programming introduction, you might remember that we can get specific properties of an object with the
: function. All GUI-elements have a property called
home which contains the current form, a function
val>that returns the current value and a function
set> that sets the current value.
Let's take again our textfield example from the beginning:
(form NIL (gui 'a '(+TextField) 30 "First Name") ... )
We can find its content by getting the
home property from our current form, and then return its property
a (which is our
(: home a)
To get its value:
(val> (: home a))
Now let's modify our button so that it prints the content of
a when we press it. Printing to standard error is possible using the
(gui '(+Button) "Print" '(msg (val> (: home a)))
If we now enter our text into the textfield and press the button, we see a line in the terminal where the server is running:
Instead of referencing by alias names, we can also use the relative position of the GUI element, which can be more convenient. For example, in order to access the text of the previous element, we can use
(gui '(+Style +TextField) "mb-2" 30 "Enter your text: ") (gui '(+Button) "Print" '(msg (val> (field -1)))
The example showed how to create HTML forms using the PicoLisp GUI framework.
By calling a
form function within
action, the content is created by pre-defined classes. At submission, the form content is automatically re-directed to the current page using
POST. We can access the values in each field by relative position or by alias names.
It might seem a little confusing at the moment, but it will become clearer the more examples we see. In the next post, we will see how to use Prefix-Classes to further style and define those elements.