Creating a User Interface for Data Modification, Part 2
Tags: picolisp, lisp, functional, database
Published: 2022-05-08 15:38:58

In the last post, we created a HTML page that displayed the database records in a HTML form. However, all fields of this form were disabled and read-only. Now we will see how to enable the fields, and how to search in data and add these to the table.

--------------------------

### Enabling the fields

The easiest way to enable all fields for an edit mode is by adding an ``editButton``. The syntax is as easy as it can be:

```
(form NIL
   (<h2> NIL (<id> (: nm)))
   ( editButton T )
```

This renders a button that says ``EDIT`` while the fields are disabled. On pressing it, all input fields are enabled and it the button label changes to ``DONE``. Let's test it:


![elizabeth2b.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1634581777184/P43_ujP2x.gif)

Note also how the input field is *suggesting* data as soon as we type into the field, thanks to the ``+Obj`` prefix class.

----------------------------

### Searching and choosing data

A very common requirement for a database is to search for data and choose items from the values we receive back.

The easiest form to implement this is via the predefined GUI element ``choDlg`` (for "choose dialog"). It takes one argument, the "destination" ``Dst``, which is ``0`` for standalone GUI elements and any number for a GUI element within a chart.

Let's say we want to be able to search persons by their name. We can define a function called ``choPerson`` function like this:

```
(de choPerson (Dst)
   (choDlg Dst "Persons" '(nm +Person)) )
```

--------------

Now we can insert ``(choPerson Dst)`` anywhere we want to be able to replace a record by searching for a new one. Specifically, these would be the records for mother, father, partner and kids, as these are also ``+Person`` objects. So let's add ``choPerson`` and see what happens:

```
(<grid> 5
   ... 
   (choPerson 0)
   "Father"
   (gui '(+E/R +Obj +TextField) '(pa : home obj) '(nm +Man) 30)
   ...
```

*Note we also have to increase the grid from 4 to 5 because the ``choPerson`` is a standalone element.*

After this modification, we see small ``+`` buttons next to the input fields.


![plusbutton.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1634582085777/6hjhuO_2U.png)

------------

What happens if we press "Edit" and then the ``choPerson`` button? We get a dialog with a search field and a list of results. If we click on the name, we get forwarded to this record's page. If we click on the ``@`` symbol, this record gets added to the currently open page, to the field which is connected to the ``choPerson`` button.

![ed.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1634582056324/vyo9VETyd.png)

With clicking on ``cancel``, the dialog closes.

----------------------

Let's test it!

![georgeiv.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1634582177556/BK9o56Yf7.gif)

---------------

### Adding the ``Treeview`` function

Now let's bring our current view on the data and our previous ``Treeview`` function together. Let's add a link to the treeview page in form of a button:

```
(gui '(+Rid +Button) "Tree View"
   '(url "!treeReport" (: home obj)) ) ) ) ) )
```

Due to the ``+Rid`` prefix class, the button is always enabled, even if the rest of the form is not. The button is labelled preview and is calling the function ``treeReport`` with the current object as argument.

![treeview.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1634583619072/_hfiHCbMd.png)

----------------

When we click it, we get re-directed to our previously designed ``treeReport`` page. T

As last step, let's re-define our links in the tree report so that clicking on a name directs us back to that person's record page. We can use again the ``url>`` method of the object for this by using the ``mkUrl`` function:

```
(<href> (: nm) (mkUrl @))
```

This creates a relative link to our function ``person`` with the person's object as ``*ID`` argument. However, this could throw an error if the object is ``NIL``. So we need to check it first using the ``try`` function, which takes a method and an object as arguments, and optionally further arguments (here ``1`` for the tab - i. e. we want our current tab to change). 

```
(when (try 'url> This 1)
```

With this, we can jump between record and treeview as we wish:

![treeview.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1634584566829/B0cvJJXas.gif)

------------------------

You can find the source code of this example [here](https://gitlab.com/picolisp-blog/web-applications/-/blob/main/database/family-edit.l).


---------------------------

### Sources

- https://software-lab.de/doc/index.html   
- https://software-lab.de/doc/app.html