Web Apps: GUI Component Interaction

Search for a command to run...

No comments yet. Be the first to comment.
Sometimes an example says more than 1000 pages of documentation. This series will take specific algorithmns and discuss their implementation in PicoLisp step by step. https://rosettacode.org/
Task Create a window that has: a label that says "There have been no clicks yet" a button that says "click me". Upon clicking the button with the mouse, the label should change and show the number of times the button has been clicked. I guess t...
In our previous post, we introduced how to utilize Discrete Event Simulation (DES) in PicoLisp. Now, let's explore another application: a railroad model simulation that includes tracks and trains. The visualization is ASCII-based, so feel free to unl...

The Dining Philosophers

In this post, we will introduce the concept of co-routines and how they are handled in PicoLisp. This will be the foundation for the subsequent posts on Discrete Event Simulation and finally a couple of examples, including an ASCII model railway simu...

One of the many nice things of PicoLisp is that it comes with a built-in database. This makes it easy to collect and store our own data, for example via a mobile app. But not all data is best represented in tables and lists: sometimes a colorful litt...

In the last two posts, we have built a little app that shows the current location and displays the nearest ice cream shops: https://picolisp-explored.com/an-openstreetmap-app-written-in-picolisp-pt-1 https://picolisp-explored.com/an-openstreetmap-ap...

For a minimal "application", write a program that presents a form with three components to the user:
- a numeric input field ("Value")
- a button ("increment"
- a button ("random")
The field is initialized to zero. The user may manually enter a new value into the field, or increment its value with the "increment" button. Entering a non-numeric value should be either impossible, or issue an error message.
Pressing the "random" button presents a confirmation dialog, and resets the field's value to a random value if the answer is "Yes".
This task is very similar to the previously discussed task "Simple Windowed Application", so we will use the script and modify it. This is how it will look like in the end:

A hosted version can be found here.
In this task, we need a numeric input field that can be modfied by the user, a button called "increment" and another button called "random". Let's define them without putting any logic inside:
(gui '(+NumField) 20 "Value: ")
(gui '(+Button) "increment")
(gui '(+Button) "random")

We want the +NumField to show us the value of the *Count variable, and also be able to modify it. We can do this by setting the prefix class +Var on the *Count variable:
(gui '(+Var +NumField) '*Count 20 "Value: ")
Secondly, we want the button to increase the '*Count value. So lets add a function to the button definition:
(gui '(+Button) "increment" '(inc '*Count))
And the prefix class +JS to avoid the reload of the complete page.
(gui '(+JS +Button) "increment" '(inc '*Count))
As last step, we need to define the random function. PicoLisp has a built in function called rand which can be used for that purpose:
(rand ['cnt1 'cnt2] | ['T]) -> cnt | flgReturns a pseudo random number in the range of the positive short numbers
cnt1andcnt2(or -2147483648 .. +2147483647 if no arguments are given). If the argument isT, a boolean valueflgis returned.
The task description has no specification about the range, so let's use the rand function without any arguments. When the button is pressed, we set *Count to the random value.
(gui '(+Button) "random" '(setq *Count (rand)))

There is only one last specification to fulfill: The task description tells us that we need to open a dialog which needs to be confirmed by the user first. form.l provides a function ask for this purpose:
(ask Str . Prg)Creates an alert dialog with a string, a 'Yes'- and a 'No'-button.
Stris the text that will populate the alert,Prgis the action triggered by the 'Yes'- button.

As you can see, the pop-up moves the position of all the other components, because it's not an overlay dialog box but a normal <form> element that is inserted just above the form which created them.
<form enctype="multipart/form-data" ...> ...
<fieldset class="alert"> ...
<span class="ask">Reset to a random value?</span><br/>
<input type="submit" name="*Gui:-1" value="Yes" onmousedown="inBtn(this,1)" onblur="inBtn(this,0)" class="submit" id="i0--1"/>
<input type="submit" name="*Gui:-2" value="No" onmousedown="inBtn(this,1)" onblur="inBtn(this,0)" class="submit" id="i0--2"/>
</fieldset>
</form>
There is not so much we can do about the shifting, but at least we can make sure that it is inserted above instead of next to our form GUI elements by wrapping these into their own <div> within the form function:
(<div> "d-flex flex-column bg-light text-center mx-5"
<-- Dialog comes here! -->
(form NIL
(<div> "d-flex justify-content-center text-center my-5"
(gui '...)
(gui '...)
Due to the text-center class in the <div> above the dialog it gets centered. Then it looks like this:

Now our form elements get pushed down when the dialog box appears, but not to the side. Finished!
The final source code can be downloaded here, css here.
https://rosettacode.org/wiki/GUI_component_interaction#PicoLisp
https://software-lab.de/doc/app.html#dialogs