The Xdialog Genie in Action scripting has several powerful new controls.
Cascading dropdown boxes - For example, define a series of dropdown boxes that display State names, Cities within the selected State, Companies within the selected City, and finally Lastnames within the selected Company.
Dynamic trees - For example a tree control that shows a list of States. Expand a particular State and then show the list of Cities in that state, and so on, up to any depth that you want. Since the tree is not fully populated when it is displayed initially (only the states are fetched from the database), it is extremely fast, regardless of how large the table that you are working with.
Grid Component - This allows you to insert a Web Grid Component into an Xdialog. The Application Server does not have to be running in order to run the Grid Component. The image below shows an Xdialog with an embedded Grid Component.

The Grid Component (created when you build a Web application) is an extremely feature rich control, with many features that are not possible in Alpha Five desktop applications (or at a minimum, would require extensive Xbasic and Xdialog skills to duplicate). Now, you can use Grid Components in your Desktop applications. You can embed Grid Components in Xdialogs. When a Grid is embedded into an Xdialog is works without requiring the Application Server to be running.
The implications of this new feature are profound. If you are building Desktop applications, and you use Grid Components for your data entry tasks, then all of the work that you do for your Desktop applications can be used as-is should you want to port your application to the Web at some future point in time.
There are two ways in which you can embed a Grid into an Xdialog:
The new a5_showPopupHelp() makes it very easy to put help buttons on an Xdialog that the user can click for additional help. The help can be defined using Xdialog or HTML.
(See example in Learning Xdialog.)

It is now even easier to embed HTML into Xdialog. Previously, you had to define and place the Internet Explorer ActiveX control in your Xdialog. Now, you simply use the new {html}, or {htmlIE} command.
The script below uses the command:
{html=50,10test}
This indicates that we want to create a window that is 50 'characters' wide and 10 'lines' high, and display the HTML content that is stored in the variable called 'test' which is defined in the script.
For example:
htest = <<%html%
<html>
<body style="font-family:tahoma;font-size:8pt;background-color:#ffff00;">
<span style="font-size:12pt;"> Hello World!<span>
<p>This is HTML text. You can use the full array of HTML styling features,
including CSS style sheets.</p>
</body>
</html>
%html%
ui_dlg_box("HTML in Xdialog",<<%dlg%
This is regular Xdialog content here.;
The area in the frame is HTML;
{frame=1,1}
{html=50,10htest};
{justify=center}
<10OK>;
%dlg%)

The {html} and {htmlIE} commands are similar but have some important differences. The {html} command uses Alpha Five's built-in HTML rendering engine. It is extremely fast and lightweight, but does not support Javascript, and does not give you access to the HTML DOM. The {htmlIE} command uses Internet Explorer as its rendering engine, and does support Javascript and does give you access to the DOM.
These two commands will allow you to create visually stunning Xdialogs. In particlar, the {htmlIE} control is extremely powerful because you can incorporate third-party open source Javascript libraries, such as JQuery, to add a vast array of features and visual effects to your Xdialogs.
You can attach Xbasic event handlers for some of the standard DOM events in the HTML displayed in the {html} control. The following example shows some HTML with events. Notice a) the event names all have 'a5:' prefixes and b) 'div' are not 'clickable' by default. It is necessary to add a special 'style' attribute in order to make the div clickable.
dim html as c
html = <<%html%
<div a5:onclick="divClick()"
style="behavior: clickable;font-family: tahoma; font-size: 8pt;
background-color: #ffffff; border-style: solid; border-width: 1px; border-color:
#a0a0a0;">
<img style="vertical-align:middle;"
src="a5res:images/$$file.save.png" />Some text inside a DIV
</div>
<p>
<button a5:onclick="buttonClick()"
style="font-family: tahoma; font-size: 8pt;">Button</button>
%html%
dim p.object as p
dim p.dom as p
ui_dlg_box("Test",<<%dlg%
{html=100,10html};
%dlg%,<<%code%
%code%)
function divClick as c ()
ui_msg_box("Notice","You clicked on a DIV")
end function
function buttonClick as c ()
ui_msg_box("Notice","You clicked on a Button")
end function
When you use {htmlIE} you first need to define an arbitrarily named dot variable. The dot variable must have an .html property that contains the HTML to display. It can also have two optional properties:
If you set options.loadA5Core to .t., {htmlIE} loads the Alpha Five Core Javascript Library. By default, this property is set to .f.. Loading Alpha Five Core gives you access to certain library functions such as:
If you want to use a 3rd party Javascript library, such as JQuery, the Alpha Five library might conflict with the 3rd party library (for example, JQuery also uses the $ be default), and so you will not want to load the Alpha Five Core library.
The following example script shows how we have an HTML dialog with a button. The button's event handler is written in Xbasic.
dim p as p
dim p.html as c
dim p.dom as p 'we define this property so we can get access to the DOM
'the .options property is optional
dim p.options as p
p.options.loadA5Core = .f.
p.html = <<%html%
<b>This is some html</b>
<br>
<button onclick="!button1">click</button>
<span id="s1"></span>
%html%
ui_dlg_box("Using HTMLIE",<<%dlg%
{htmlIE=100,20p}
%dlg%,<<%code%
if a_dlg_button = "button1" then
a_dlg_button = ""
dim obj as p
obj = p.dom.getElementById("s1")
obj.innerHTML = "Content set by Xbasic"
end if
%code%)
Notice that the HTML button's onclick event is set to "!button". By prefixing the event code with a !, we indicate that the standard Xdialog event handler will handle the event.
As you can see the Xdialog code section contains this code to handle the event:
if a_dlg_button = "button1" then
a_dlg_button = ""
dim obj as p
obj = p.dom.getElementById("s1")
obj.innerHTML = "Content set by Xbasic"
end if
When the user click the button, the Xbasic event handler gets a pointer to the span in the HTML. The span has an id if "s1". We use the standard Javascript .getElementById() method.
See the sample Learning Xdialog database for examples of how to use the {html} and {htmlIE} command.
A common requirement in an Xdialog is to display a listbox showing data from an array. The array is often a property array, and so the Xdialog displays data from one of the properties in the array.
For example, the property array shown below has 'fname' and 'lname' properties, and the Xdialog shows the value in the 'lname' property:
dim arr[0] as p
arr[].fname = "Sam"
arr[..].lname = "Raven"
arr[].fname = "Charles"
arr[..].lname = "Chambliss"
arr[].fname = "Dion"
arr[..].lname = "Smits"
ui_dlg_box("Show Lname",<<%dlg%
[.50,20index^#arr[\].lname];
%dlg%)
The resulting Xdialog looks like this:

But, what if you wanted the listbox to show both the 'fname' and 'lname' property? You could pre-process the array and add a new property called (say) 'Display' value to the array and then display that property in the array. But a better approach is to use the new option to dynamically calculate the display property of the listbox. This is done by using a special owner draw format.
The owner draw format is =expression, where expression is some expression that you want to evaluate. The expression can reference a special variable called value that passes in a reference to the current row in the array.
Here of some examples of owner draw formats:
| %O==eval(value+ "." + propertyName)% | In this example, propertyName is a variable that contains the name of the property (e.g. 'fname' or 'lname') that you want to display |
| %O==eval(value+".fname+' '+" + value + ".lname" ) | In this example, the expression returns the 'fname' and 'lname' properties of the array. |
| %O==testFN(eval(value))% | In this example, another UDF (testFN()) is called to compute the display value in the listbox. |
Here is an example that demonstrates the use of these format strings:
dim arr[0] as p
arr[].fname = "Sam"
arr[..].lname = "Raven"
arr[].fname = "Charles"
arr[..].lname = "Chambliss"
arr[].fname = "Dion"
arr[..].lname = "Smits"
index = 1
dim fmt as c = ".fname"
ui_dlg_box("Owner Draw Listbox - Computed Display",<<%dlg%
{wrap=40}
{repaint_begin=fmt}
Select the property to display:;
[.10fmt^={.fname,.lname}];
[%O==eval(value+fmt)%.50,5index^#arr];
Listbox can show an expression showing a calculation involving properties in the
array:;
[%O==eval(value+".fname+' '+" + value + ".lname" )%.50,5index^#arr];
A more complex expression:;
[%O==eval("upper(" + value+".fname)+' '+" + value + ".lname" )%.50,5index^#arr];
You can call a UDF to compute the data to display:;
\(This is the most flexible option.);
[%O==testFN(eval(value))%.50,5index^#arr];
{repaint_end}
%dlg%)
'value is a placeholder for 'arr'. eval(value) passes in the the current row in
the array to the function.
function testFN as c (ar as p)
testFN = upper(ar.lname) + ", " + f_upper(lower(ar.fname))
if ar.lname = "chambliss" then
testFN = "{I:'$$generic.orb.green.small'} " + testFN
else
testFN = "{I:'$$generic.orb.blue.small'} " + testFN
end if
end function

Xdialog listboxes now has horizontal scrolling. To turn on horizontal scrolling, you must use the 'H' directive, as shown in the example below:
frms = a5.Form_Enum(16)
ui_dlg_box("","[%H%.30,10frm^#frms]")
You can now use HTML in a standard Xdialog Listbox. To use HTML, you use the 'HTML' directive in the Listbox definition.
For example:
MyList = <<%html%
{DATA=1}<div style="width: 4in;background-color:red;font-size:20pt;"><img
src="a5res:images/$$generic.orb.red.png"/> Red</div>
{DATA=2}<div style="width: 4in;background-color:blue;"><img src="a5res:images/$$generic.orb.blue.png"/>
Blue</div>
{DATA=3}<div style="width: 4in;background-color:green;"><img src="a5res:images/$$generic.orb.green.png"/>
Green</div>
{DATA=4}<div style="width: 4in;"><table><tr><td><img src="a5res:images/$a5_close.png"/>This
is a multi-line item - Line1</td></tr><tr><td><img src="a5res:images/$a5_open.png"/>This
is a multi-line item - Line2</td></tr></table></div>
%html%
MyItem = "1"
dim pg as p
pg.BodyText = "The contents of this standard Xdialog ListBox is populated
with HTML content. The 'directives' section in the ListBox definition
contains the 'HTML' directive and the 'D' directive, which makes the height
of each line in the listbox dynamic."
pg.HeadingText = "HTML ListBox"
pg.Image = ""
ui_dlg_box("Xdialog with HTML ListBox",<<%dlg%
{XdialogTitleSection=100,5pg};
{lf};
ListBox populated with HTML content:;
[%HTML;D%.80,10myItem^#MyList];
{lf};
Current selection:;
[.20myItem]
%dlg%)
Notice in this example that the data in the ListBox is a CRLF delimited list. Each row in the list can contain HTML. The HTML must appear on a single line. The ListBox command uses the 'HTML' and 'D' directives. 'HTML' enables HTML formatting and the 'D' directive enables dynamic line heights.

The layout of an Xdialog is defined by a string variable. This makes it easy to write an Xbasic script that generates an Xdialog, or modifies one before it is rendered.
Two new Xdialog commands make creating dynamic Xdialogs even easier.
If the variable, 'state' is 'MA', the dialog on the right will be shown. If the 'state' is not 'MA', the dialog on the left will be shown.
You can have as many conditional sections as you want.
ui_dlg_box("Xdialog",<<%dlg%
This is common code;
{staticConditionalSection:1:state="MA"}
This section only applies if the user is in MA;
{end_staticConditionalSection:1}
This is more common code.;
%dlg%

Contrast this example with the {condition_begin}/{condition_end} Xdialog command which can also dynamically hide/show sections of an Xdialog. The {condition_begin} command does not eliminate the space taken up by hidden sections (unless the {start_pos} command is also used). On the other hand, {condition_begin} evaluates the conditions after the Xdialog has been rendered - so changes in the condition expression dynamically affect the appearance of the Xdialog.
Consider the following script. The variables, 'section1' and 'section2' both contain some Xdialog markup. If mode = "A" the markup in 'section1' is included in the Xdialog. If mode = "B", the markup in 'section2' is included in the Xdialog.
section1 = "this is section 1 <button>;"
section2 = "this is section 2"
mode = "B"
dlg = <<%dlg%
{hyperlink=foo!foo}
this is common code;
{staticConditionalInclude:section1:mode="a"}
this is more common code
{staticConditionalInclude:section2:mode="b"}
%dlg%
ui_dlg_box("Xdialog",dlg)
Here is how the Xdialog renders if mode = "A"

Here is how the Xdialog renders if mode = "B"

Note: The {staticConditionalInclude} command is recursive. This means that the Xdialog markup that is dynamically included can also contain static conditional sections, as demonstrated by this script:
section1 = <<%dlg%
this is section 1 <button>;
{staticConditionalInclude:subsection1:submode="a"}
%dlg%
section2 = "this is section 2"
subsection1 = "this is subsection 1 <button2>;"
submode = "a"
mode = "a"
dlg = <<%dlg%
{hyperlink=foo!foo};
this is common code;
{staticConditionalInclude:section1:mode="a"}
this is more common code
{staticConditionalInclude:section2:mode="b"}
%dlg%
ui_dlg_box("",dlg)
Xdialogs have been able do display the standard windows ListView control for some time now. Now, a new simplified syntax is available to make it easier to use a ListView control in an Xdialog. The following script shows an example:
dim list as c
list = <<%txt%
{data=1}Erica|Jones
{data=2}Tom|Snider
{data=3}Molly|Maloney
%txt%
ui_dlg_box("Quick ListView",<<%dlg%
[%M;K%.100,20id^"Firstname|Lastname"list!idchange];
%dlg%,<<%code%
if a_dlg_button = "idchange" then
a_dlg_button = ""
ui_msg_box("Note","User clicked on : " + id )
end if
%code%)
Note: The alternative technique is to use the Xdialog {ListView}
command. The Action Scripting Genie generates code that uses the {ListView}
command. The {ListView} command has more features than the syntax
discussed here, but the Xbasic is more verbose.

The ListView displays data in a CR-LF delimited string. The string can contain an optional {Data=value} portion, to set the value of the variable assigned to the ListView.
The syntax for the ListView is:
[%directives%.width,height^#columHeaders"list!eventName?enableFlag]
Where:
| directives | directives is a semi-colon delimited list of directives. M - turn on multiple selections K- keep the selected rows visible when the control does not have focus B=N - turn off the border around the ListView S=G - turn on grid lines |
| width | Width of the ListView in 'columns' |
| height | Height of the ListView in 'lines' |
| columnHeaders | A pipe delimited list of column headings.
Example: Firstname|Lastname|City You can set an explicit column width by specifying a column heading as columnName:width Example: Firstname:30|Lastname:50|City:40 |
| list | A CR-LF delimited list of data to show in the ListView. Each row can
contain an optional {Data=value} element to control the
value that the bound variable is set to when the row is selected. Example: {data=0001}0001|John|Smith {data=0002}0002|Ken|Jones |
| eventName | The name of the Xdialog event handler. E.g. 'selectionChanged'. In
this case, when the selected item changes, the a_dlg_button variable
will be set to 'selectionChanged'.
To trap more events, such as double click on a row, or click on a column title, use an event name with a *. e.g. 'change_*'. See Learning Xdialog - ListView Control with Sorting - Using the ^" Command for more details. |
| enableFlag | If enableFlag is .f. the ListView is not enabled. |
An important change has been made in V10 with regard to data that is retrieved from SQL databases using AlphaDAO.
In V10, all data that is retrieved from SQL databases is in UTF-8 format. If your data does not have any foreign characters in it, then this change will not have any consequences for you. However, if your data does have foreign characters in it, and you want to display the data in an Xdialog, you will need to use one of the available options to convert the data into ansi format.
The options are:
The following Interactive window session shows how UTF-8 data will look before, and after it is converted to ansi format:
(The convert_utf8_to_acp() function is used. There is also a convert_ansi_to_utf8() function.)
dim cn as sql::connection
?cn.open("{A5API=Access,FileName='C:\a5v10\MDBFiles\Northwind.mdb',UserName='Admin'}")
?cn.Execute("select * from customers where customerId = 'bergs'")
= .T.
rs = cn.ResultSet
x = rs.data("companyname")
?x
= "Berglunds snabbköp"
?convert_utf8_to_acp(x)
= "Berglunds snabbköp"
The following Xdialog shows how the {encoding} Xdialog command can be used:
dim cn as sql::connection
cn.open("{A5API=Access,FileName='C:\a5v10\MDBFiles\Northwind.mdb',UserName='Admin'}")
cn.Execute("select * from customers where customerId = 'bergs'")
rs = cn.ResultSet
x = rs.data("companyname")
ui_dlg_box("Show UTF-8 Data",<<%dlg%
No encoding command - ascii encoding is assumed;
Name: [.50x];
UTF-8 encoding command - data looks correct;
{encoding=utf8}
Name: [.50x];
ASCII encoding command - data looks wrong;
{encoding=ascii}
Name: [.50x];
%dlg%)
