Prompting User for Data

A common need is to ask the user for a single string:

require "CLRForm"
if PromptForString("MyApp","Give your name","") then
    MessageBox.Show("Name!",arg[0],MessageBoxButtons.OK)
end

People however get irritated by being asked tiny questions, so in true bureaucratic style we would like her to fill in a form. This is a very common thing in GUI applications, and generally requires far too much coding. Some of that coding may be generated by the wizards that lurk in your IDE, but sometimes the ideal amount of code is zero. Consider this:

-- auto1.wlua
require "CLRForm"
 
data = {
    firstname = "",
    lastname = "",
    age = 0,
    title = "",
    phone = "",
    email = ""
}
 
form = AutoVarDialog { Text = "Please Supply Details", Object = data;
    "First Name:","firstname",
    "Last Name:","lastname",
    "Age:","age",
    "Title:","title",
    "Phone number:","phone",
    "E-mail Address:","email"
}
 
if form:ShowDialogOK() then
   print 'ok'
end
 
os.exit(0)

The call to AutoVarDialog automatically generates a dialog based on a template, which maps descriptive labels to the actual fieldnames. This kind of trick is possible in highly dynamic languages like Lua, where the actual type at runtime of any object is easy to determine. So by default we will try to edit numbers and strings with text boxes, and boolean values with checkboxes. At this level, some input validation is already possible; age was a number, so whatever gets typed into the 'Age:' box must be convertable to a number and the user will not be allowed to proceed successfully until this is fixed.

But the general problem of validation remains. It's a bad idea to let bogus data into your system, and it should be caught as soon as possible. Also, fields like 'Title' are profoundly confusing. People will put in what their interpretation tells them, rather than your interpretation. So the next example shows an extra (optional) validation field that can follow the field name:

-- auto1.wlua
require "CLRForm"
 
data = {
    firstname = "steve",
    lastname = "donovan",
    age = 16,
    title = "Mr",
    phone = "+27116481212",
    email = "steve.j.donovan@gmail.com"
}
 
form = AutoVarDialog { Text = "Please Supply Details", Object = data;
    "First Name:","firstname",NonBlank,
    "Last Name:","lastname",NonBlank,
    "Age:","age",Range(16,120),
    "Title:","title",{"Mr","Ms","Dr","Prof"},
    "Phone number:","phone",Match ('^%+%d+$',"Not a valid phone no."),
    "E-mail Address:","email",Match ("%S+@%S+","Not valid email")
}
 
if form:ShowDialogOK() then
   print 'ok'
end
 
os.exit(0)

Notice that by making 'title' to be explicitly a list of items, we can now deduce that a drop-down list is the appropriate way to present the choice to the user. As for 'age', numerical values nearly always have a valid range. Text fields require more complicated validation - here phone numbers must be entered in international format, and email addresses must have a '@' somewhere. (They can still be utterly bogus, but at least they are well-formed rubbish ;))

Here is a more complete example, showing off file entry fields and booleans.

-- autoform.wlua
require "CLRForm"
 
tbl = {
    x = 2.3,
    y = 10.2,
    z = "two",
    t = -1.0,
    file = "c:\\lang\\lua\\ilua.lua",
    outfile = "",
    res = true,
}
 
form = AutoVarDialog { Text = "Test AutoVar", Object = tbl;
    "First variable:","x", Range(0,4),
    "Second Variable:","y",
    "Domain name:","z", {"one","two","three"; Editable=true},
    "Blonheim's Little Adjustment:","t",
    "Input File:","file",FileIn "Lua (*.lua)|C# (*.cs)",
    "Output File:","outfile",FileOut "Text (*.txt)",
    "Make a Note?","res",
}
 
if form:ShowDialogOK() then
    print(tbl.x,tbl.z,tbl.res,tbl.file)
end

autovar