Message output UI [examples]

Display a message
set message to "Hello World"

Enable or disable spaces between expression output
set space on
? "A","B",(2*3),(2+6),"C"
A B          6          8 C
set space off
? "A","B",(2*3),(2+6),"C"
AB         6         8C

Evaluate expression and output result
? "price" at 01 picture "@!",1234.56 picture "$99,999.99"
PRICE $1,234.56

Evaluate expression and output result on the same line
?? "price" at 01 picture "@!",1234.56 picture "$99,999.99"
PRICE $1,234.56

Evaluate expression and output result on the same line
echo "price" at 10 picture "@!",1234.56 picture "$9,999.99"
echo "-----\n" at 10
          PRICE $1,234.56
// php-style $variable and {expression} substitution
m_date = date()
echo "Today's date is {m_date}\n"

Close the alternate output file
use patrons index names
set alternate to namelist
set console off
list for event = "BALLET"
close alternate

Display a text message in a dialog box
dialog box "Transaction Completed"

Display a block of text on the screen or printer
open database southwind
use example
set textmerge to balance.txt
set textmerge delimiters to "{{","}}"
set textmerge on
go top
do while balance > 0
    text noshow
    Date: {{date()}}
    Name: {{last_name}}  {{first_name}}
    Account Number  :  {{account_no}}
    Current Balance  :   {{balance}}
    Credit Limit:        :   {{limit}}
set textmerge off
set textmerge to

Suspend program execution pending a key press or mouse-click
wait "Click to continue"

Return a single color value from a set of red, green, and blue color components
? rgb(255,0,255)                                                              

Display the color picker
? getcolor()

Display the font picker
? getfont()

Display a dialog box with for user input of a string
nReturn = inputbox("Please enter your password:", "System login", "*")
if not empty(nReturn)
    select users
    seek username()
    if password = nReturn
        // match
        // nomatch
    // no password entered

Display a dialog box with user-defined elements
nReturn = messagebox("Are you sure?", 36, "Continue to next screen")
if nReturn = 6
    // user selected 'Yes', process accordingly
    // user selected 'No', process accordingly

Returns the number of input events
nCurrevents = inputevents()
// Assumes nPrevEvents variable already declared/set and in scope
if nCurrEvents = nPrevEvents
  // No events since last check, return to App Center
nPrevEvents = nCurrEvents

Turn the screen display on or off


set console off
report form patrons to print
set console on

Categories UI

Form UI class [examples]

To create desktop UI classes in Lianja/VFP:


myform = createObject("Form")
myform.caption = "This is a demo form"
myform.resize(600, 400)
myform.autocenter = .t.

To add controls to a form (or other containers) we use the addObject() method of the Form class. Now add a MenuBar, Toolbar and Actionbar.

myform.addObject("mymenubar", "MenuBar")
myform.addObject("mytoolbar", "ToolBar")
myform.addObject("myactionbar", "ActionBar")

Now add a Form statusbar and specify a message to be displayed in it.

myform.statusbar = .t.
myform.message = "Double click on a row in the grid to select a customer"

Now that we have a basic form, we will add a container to it which will be used to add controls and possibly other containers.

myform.addObject("mycontainer", "Container")
mycontainer.anchor = 15

Unlike VFP, the Lianja Container class can handle layout management for us. There are four types of layouts that we can set on a container.

  • Horizontal
  • Vertical
  • Form
  • Grid

Let’s set the layout of our container to be “Vertical”. This will cause all controls that are added to it to be automatically adjusted to the width of the container. We use the fixedheight property to establish a fixed height for the controls that we add to the container.

mycontainer.layout = "vertical"
mycontainer.addObject("myheader", "label")
myheader.fixedheight = 40
myheader.caption = "Select a Customer"
myheader.gradient = 1
myheader.forecolor = "gray"
myheader.fontbold = .t.
myheader.fontsize = 18
myheader.alignment = "center"

Now let’s add a Grid to the container but not set any fixedheight property so that that it uses up all remaining vertical space in the container.

mycontainer.addObject("mygrid", "grid")
mygrid.readonly = .t.
mygrid.caption = "Customers"
mygrid.additems("select * from southwind!customers")

We make the form visible (and 1=modal):




in the example_webapp2 app…

…In the web client this appears to lock the company name field. The user is no longer able to edit the Company Name field on any record. You have to exit the app or edit the whole page and cancel in order for the field to become editable again.

Should the navigation buttons be disabled automatically when a field is in edit mode, as is the case when editing a full record?


You can disable inline editing in the Web Client. There is an App Setting – the last setting under ‘General App Configuration’.


Is there a way to close a browse window using CTRL-W?


No, the window corner x is currently the only way to close the window.


I am looking for a list of all available hot keys in Lianja.


The Hotkey event delegate is triggered by the function keys, Ins, Backspace, Delete, PgUp, PgDn, Home, End and combinations of these with ctrl, alt and shift.…legates#Hotkey

There wasn’t a definitive list, so I have added these to the Hotkey delegate link.


I am also using Left, Right, Up and down arrows (which are working), so I thought perhaps there were other keys.


I had missed the hotkey functionality.

Does this functionality extend to mobile apps? The reason I ask is that “desktop” to us at this point means an Electron app.


Currently desktop (not Electron) only.


How does one set an individual ‘form’ to be a specific size rather than filling the whole screen


custom forms have properties for that.

Pages themselves always adjust to the geometry of the app. Custom forms exist on their own, in effect outside the page object and the App. Custom sections conform to the page width.

Custom forms limit your deployment flexibility: ever see a free-floating form on a mobile app?


You just specify the size of the window using showdialog.Name:  floatingwindow.jpg Views: 28 Size:  67.7 KB

As you can see in the image, I have an app that has a floating window outside the main part of the app.

in a mobile app, you would have to show the dialog panel with the OnTop parameter set to .F.,


In a canvas section, when a TextBox or NumericTextBox field has Editable = False, the background is greyed.

1. Is there a reason why this shouldn’t be the case for DateTextBox and EditBox fields (or possibly others…haven’t tested them all) ?

2. Is there a VFP equivalent to the Enabled property or is Editable the only option?

3. Is there a way to control the Background/Foreground Colors for Non-editable Canvas fields?


If you look in the App Settings there is an attribute which specifies the background color of non-editable/readonly fields.

The Qt UI framework which Lianja uses adapts the controls to the host operating system it is running on. This is so it renders native UI controls whenever available. Some composite UI controls do not have host operating system counterparts so these are custom controls.

The enabled property is not exposed for design reasons. You should use the editable attribute.

UI presentation rules can be used to adjust this dynamically depending on the logged in user.

In Lianja 4.1 I have enhanced the web/mobile framework so that you can embed grids, charts, webviews and pageframes (Tabbed UI) inside a grid cell or FormGrid cell.

I’ve also implemented the Lianja/VFP “form”, “webview” and “pageframe/page” classes in the web/mobile framework.

So now it is simple to show a popup window to edit a grid cell or drill down in a management dashboard.

Here’s some example JavaScript code:

f = createObject("form");
f.caption = "This is a popup form";
f.resize(1024, 600);
f.addObject("wv", "webview");
wv.url = "";;

and the result.

Name:  Screen Shot 2017-10-28 at 3.08.39 PM.jpg Views: 45 Size:  71.3 KB

Clearly using the Lianja Web/Mobile framework is dramatically easier than messing about with HTML/CSS etc and if you have any VFP knowledge you will be right at home with the custom classes available to you.

Remember also that you can addObject() a “container” to the “form” and give that container a “layout” of “grid”, “form”, “vertical” or “horizontal”. These layouts will help you build responsive UI forms that adjust and lay out their “children” UI components automatically.

So you can build complex data entry forms and extract the data from the form in the “afterClose()” delegate to update remote data or update the UI and change its state by selecting other pages using Lianja.showDocument() etc.

Further refinements with custom classes.

Pageframe/Page (tabs)

are now all available in the Web/Mobile client.

Pageframe handles the new “tabposition” property:

tabposition (can be “north”, “south”, “east” or “west” same as in desktop).

Name:  Screen Shot 2017-10-29 at 2.34.33 PM.jpg Views: 40 Size:  56.7 KB

Here is the JavaScript code for that dialog.

f = createObject("form");
f.addObject("pf", "pageframe");
pf.addObject("tab1", "page");
pf.addObject("tab2", "page");
pf.addObject("tab3", "page");
tab1.addObject("wv", "webview");
wv.url = "";
pf.tabposition = "south";;

You can handle Tab navigation yourself to stack up a lot of panels in the UI and raise one into view:

pf.tabbarvisible = false;

// select tab1
pf.activatepage = 0;
// or"tab1");

To provide a better mobile experience you can set the mobilefullscreen form property to true. This is ignored unless the App is running on a phone. On a phone this maximizes the form into the viewport of the phone and removes the border.

Note that you can show the form fullscreen on all devices by setting the “fullscreen” property to true.

f = createObject("form");
f.addObject("pf", "pageframe");
pf.addObject("tab1", "page");
tab1.addObject("wv", "webview");
wv.url = "";
f.fullscreen = true;;


accepted (a property). You describe the events. I can guess what “accepted” means but thought I’d ask just to confirm.


Its a property that is true by default.

You can set it to false in the beforeClose() event to stay in the form if validation fails.


can setAttribute() be used to change an app attribute?


setAttribute() as documented is only relevant to UI page, section, formitem… not App.


Categories UI