Release Notes for Alpha Anywhere (Alpha Five Version 12)

This document describes the updates and fixes made to Alpha Anywhere since its initial release.

To see the 'What's New in V12' document (which describes all of the new features in Alpha Anywhere's initial release) please click here.

 

Please note that Alpha Anywhere patches are only available to users with a current subscription.
 

You can verify your subscription status from within Alpha Anywhere by going to Help, About, or by clicking this link shown here (https://activation.alphasoftware.com/subscriptionStatus.aspx). If you install an update for which your subscription is not entitled, you will need to uninstall the update and rollback to an older version that you are authorized to use in order to continue using Alpha Anywhere.
 

The 'Pre-Release' Build

In addition to the official updates that Alpha Software makes available from time to time (which are described in this document), we also make available our internal pre-release builds that allow you to see what features have been added and what bugs have been fixed since the last official update. The features and bug fixes in the pre-release build will be part of the next official update. To see the pre-release notes, please click here.

 

Alpha Anywhere V4.6.2.1 - 6699 5464 19 MAY-2020

 

Features

REST Service - PATCH - When defining a REST API, you can now use the PATCH verb.

UX Component - Multi-select Tokens Control - Right to Left - You can now configure the Multi-select Tokens Control to display right-to-left

UX Component - Control Bar - Buttons - Pre-defined Action - List Column Selector - When you add a new button item to a Control Bar a new pre-defined button type is available. The 'List Column Selector' will open a drop-down window allowing you to select which columns in a list should be shown.

 

 

Bugs

Tabbed UI Component - Grid Component - Refresh - Fixed an issue where a Grid that had a button to open a child component in a tab pane was not being refreshed when the child component's tab pane was closed.

UX Component - Tree Control - Security - Pre-rendered - Fixed an issue where items in a tree control could not be shown/hidden based on user's recurity role. Issue only occurred if UX was pre-rendered.

UX Component - List Control - Alphabet Button Search - The prompt to configure the Alphabet Button Search was not shown even after the search feature was turned on.

Publishing - CSS - Fixed a regression when publishing CSS files if the CSS files were not at the top level folder of the Web Project.

UX Component - List Control - Image Capture - Thumbnail - If the image was submitted to the server in base64 format, the option to create a thumbnail was not working.

 

Alpha Anywhere V4.6.2.0 - 6655 5457 05 MAY-2020

IMPORTANT NOTE

UX Component - Embedded Objects - If you have an existing UX component with embedded objects and you recalculate the UX, the embedded object will fail when you run the UX. This is easily resolved. Embedded Objects now have an ID property. This property will be blank for embedded objects that were added to the UX with a previous release. Assign an ID to each embedded object and then recalculate the UX. This will resolve the problem.

 

Hotfix - The 'Alphabet Button' search configuration option was missing from the List Builder. This hotfix need only be applied to the Developer Version. Does not need to be applied to the server.

 


How to install a hotfix

 

Videos

 

UX Component Enabling and disabling PanelCards in a PanelNavigator The PanelNavigator is commonly used in building mobile applications. This control, when in Carousel mode allows you to swipe through a series of PanelCards in the order in which the PanelCards were defined. However, in certain applications you might want to dynamically turn a PanelCard off or on so that it is skipped when swiping through the PanelCards in a PanelNavigator.

In this video we show how this is done.

Watch Video
Download Component

Date added: 2020-03-10
UX Component Rotating an Image with Animation A common UI technique is to rotate an icon (such as a 'hamburger' menu itcon) when the icon is clicked. Typically, animation is used when the icon is rotated.

In this video we show how you can rotate an image using animation.

Watch Video
Download Component

Date added: 2020-04-06
UX Component Displaying Logical Values using a CheckBox It is common to display logical values in a List. You can use a switch control, a checkbox style control, or HTML text to indicate if the logical value is true (on) or false (off).

In this video we show how a Switch control can be configured to behave like a logical checkbox with custom images for the on and off states.

Watch Video
Download Component

Date added: 2020-04-24
UX Component Selecting Active ControlBar Layout Based on Current PanelCard in a PanelNavigator In mobile applications it is common to have a PanelNavigator with multiple PanelCards. Each PanelCard should have its own ControlBar. An efficient way to design this is to define a single ControlBar for the PanelNavigator and then to select the active Layout in the ControlBar depending on which PanelCard is currently visible.

In this video we show how this can be done.

Watch Video
Download Component

Date added: 2020-04-27
     

 


 

Features

UX Component - {dialog.object}.setValueFrom() Method - honorChange - You can now specify whether the target control's onChange event should fire when the target control's value is set. By default the honorChange flag is true.

UX Cpmponent - List Control - Alphabet Buttons Search - The Grid Component has a feature that allows you to add a series of alphabet buttons to the Grid and then when you click on a button, a search is performed for all records that have a specified field that starts with the letter you clicked on. For example if the search field is set to City and you click on the P button, all records where the city starts with P are shown.

Now you can also add an alphabet search to the List control (as long as the List is based on a SQL data source). In the image below an alphabet search has been added to the List header.

 

 

To turn on the alphabet bar search, check the Has 'Alphabet Button' search bar property.

 

 

Then, click on the smart field to configure the settings for the search bar.

 

 

Properties of note in the builder include:

 

 

 

UX Component - List Control - Switch Control Type - Behavior - Checkbox - RadioButton - If you have a List control with multiple fields set to display using the Switch control type, you can now configure a group of switch controls to behave like a RadioButton (i.e. only one of the switch controls in a 'group' of switch controls can be in the 'on' state).

 

 

 

 

To configure a group of columns to behave as a RadioButton, set the Switch behavior to RadioButton and assign the same Group name to each of the fields.

 

 

UX Component - List Control - Drag-to-Reorder - onBeforeMove Event - When you configure a List control to allow drag-to-reorder, a new event allows you to dynamically control whether the selected row can be moved. The onBeforeMove event fires when the user initiates a move. If the event return false, the move is aborted.

 

UX Component - List Control - Switch Control Type - Icons and HTML - The List control allows you to display the value in a logical field using a switch. You can also change the value in the list data by toggling the switch position. Now, you can specify different display styles for a Switch control. The new display styles are Icons and HTML.

In the image below the data in the Group1, Group2 and Group3 columns are logical values. The List is configured to use a Switch control for all three columns, but the display style for the Group1 column has been set to Icons (and the icons for the on and off state have been chosen to resemble a checkbox control) and the display style for the Group3 column has been set to HTML. (See second image below).

Watch Video

 

 

UX Component - Expanding Menu Control - Right-to-Left - You can now specify a Direction for the Expanding Menu Control. Specifying rtl (right to left) would be used for languages such as Arabic and Hebrew.

 

 

 

UX Component - Control Bar - Dropdown-Menu - Expanding Menu - Direction - When you add an expanding drop-down menu to a Control Bar you can now specify the direction - ltr (left-to-right) or rtl (right-to-left). The rtl option is used for languages such as Arabic and Hebrew.

Application Server - OpenSSL - Version 1.1.1g - Alpha Anywhere now uses the latest version of OpenSSL.

UX Component - Action Javascript - Open a UX, Grid or Report - Dynamic Panel - The Action Javascript actions to open a UX Grid, Report etc. has always let you specify that the target component should be opened in a new Dynamic Panel in a Panel Navigator.

Now you can specify the alias and the title for the Dynamic Panel using Javascript. This makes it possible to create a user experience using a Panel Navigator that is similar to a TabbedUI

 

 

 

 

UX Component - List Control - Field Types - Menu - You can now add a Menu field type to each row in the List.

 

 

At run-time, the List will look like this:

Notice that each row has either an icon or a button that you can click to open the menu. In this case the menu has been configured to use an image for the button, and we have specified that when you click the image the image should rotate by 90 degrees (over a period of 300 milliseconds) and then change to a large X icon.

 

 

 

This image shows how the List appears when the menu in the first row has been opened. Notice that the image is now a large X indicating that the menu is open. If you click on the X the menu will close and the image will rotate back and change to the 'hamburger' icon.

 

 

If you scroll the list, or open a menu on another row, the currently open menu will be hidden.

 

List Menu Events

There are two client-side events associated with Menus:

 

 

 

For example, the following code could be defined for the beforeMenuOpen event to change the menu choices to Item1, Item2 and the name of the City field in the row that was clicked.

Note that the menu choices are stored in an object called _menuSettings that is part of the List object. The key to the object is the name field which is made available to the Javascript code. The listObj variable (a pointer to the List) is also made available to the Javascript code. The name field is the name of the menu field. So the menu data for the name menu is an array in listObj._menuSettings[name].

 

var _menu = [
    {html : 'Item1', onClick: function() { alert(1)}},
    {html : 'Item2', onClick: function() { alert(2)}}
]

var d = listObj._data[rowNumber];
_menu.push({html: d.City});

var obj = listObj._menuSettings[name];
obj.menuData = _menu;
 

UX Component - List Control - Static Image - A new option is available when adding fields to a List control. The Static Image option puts the same image into each row of the List. Contrast with the Dynamic Image option where the image in each row can be different, based on data in the row.

 

 

UX Component - List Control - Button - When you add a button to a List (the button appears in each row in the List), you can now specify whether the button should be text only, image only, text followed by image, or image followed by text.

 

Web Applications - IIS Server - Optimizing Memory Usage - Stack Options - A new feature is available to optimize memory usage when using the IIS server (which includes Alpha Cloud).

 IIS creates a new thread with an 8MB stack for each request that needs to be processed by Xbasic (a5w, a5wcmp, a5svc, etc.). Stack options allows IIS to be configured to use the IIS thread rather than create a worker thread. Additionally, if a worker thread is needed, the amount of stack to be allocated can be configured.

Stack options are located in the Web site defaults (ISS and Alpha Cloud Only) section of the web project properties dialog:



Click on the smart button edit the settings:



Stack options are not enabled by default in existing web applications. Any new web applications will have stack options enabled by default. Also note that currently published applications will run/continue to run with stack options not enabled so there is no change in behavior to existing applications... a worker thread is created with an 8MB stack.

After enabling stack options, a stack size of 256KB will run the request in the IIS thread. Any value greater then 256KB will create a worker thread with a stack of that defined size. The "Advanced" section of the dialog will allow different stack sizes to be defined so one or a few pages that need a larger stack won't force the rest of the application to run with that stack size. This may be necessary for an application that loads a third party assembly that needs (say) 2MB of stack, but is only used in one page. All the other pages can run in the IIS thread and only that one page will have a worker thread created for it.



The page names are regular expressions. A smart button will bring up a dialog to help selecting pages:





Once stack options is enabled, the application will need to be republished (both IIS and Cloud) before the options will be used.

 

Background Information

IIS assigns a thread to each request. The stack size of that thread is 256KB. That amount of stack was insufficient for the XBasic engine so Application Server for IIS created an additional thread for each request with an 8MB stack and then that thread is used to process the request. The IIS thread waits for the Alpha created thread to finish and then the IIS thread finishes processing the request/sending the response.

A while back changes were made to to reduce Xbasic's stack size requirement. It now works with a 256KB stack. However, due to legacy concerns the IIS behavior was not changed. Third party assemblies could be used and they may require a stack larger than 256KB. The third party assemblies may have "just worked" because Xbasic's previous stack requirement was already large. We don't know of any cases where this happens, but we still needed to plan for it. This new setting was created to get the most benefit out of the reduced Xbasic stack size requirement while also supporting edge cases.

So with stack options enabled and a stack size set to 256KB there is no need for Application Server for IIS to create its own worker thread. It can use the IIS thread to process the request in Xbasic. This saves time and memory associated with allocating and freeing a thread which includes stack. Because of Windows virtual memory management 8MB of actually memory was not being allocated for each request. But some stack memory would become "committed" (actually used). So you most likely won't see an 8MB difference with each request, but as stated above, there will be a savings in thread management for each request so ultimately in an ideal application a machine should be able to handle more concurrent requests.
 

 

AlphaDAO - SQL Server - Connection String Builder - ODBC Driver Version - When you build a connection string to a SQL Server database and you click the Test Connection, you might now see the following dialog indicating that you do not have the correct version of the ODBC driver installed.

 

 

UX Component - Expanding Menus - Expand/Contract onMouseOver - When you create an Expanding Menu control, you can now specify that a menu item should be expanded (or contracted) when the mouse is hovering over the menu item (i.e. you do not actually have to click on the menu item). You can also specify how long the mouse should have to hover over a menu item before it is expanded or contracted.

 

AlphaDAO - MariaDB - Has an updated MariaDB driver. The previous driver had issues connecting to MariaDB databases on Azure with SSL/TLS.

 

Application Server (Classic and IIS) - Same Site Cookies - Unset Option - Added a new option for the SameSite Cookies option: Unset. When this is set no SameSite attribute will be written with the Alpha Anywhere cookie(s).

This change may be useful for testing PhoneGap apps on a local server that is not using https.

 

UX Component - Embedded Object - Refresh - A new method has been added to the Alpha Anywhere Javascript library to refresh an EmbeddedObject in a UX component.

{dialog.object}.refreshEmbeddedObject(EmbeddedObjectId);

 

In addition the UX builder now allows you to assign an explicit Id to each EmbeddedObject. You will need to pass this Id embedded object to the method.

For example:

{dialog.object}.refreshEmbeddedObject('PAGELAYOUTPART_3');

 

NOTE: If you have an existing UX component with EmbeddedObjects you will need to assign each EmbeddedObject an unique ID.



Reports - Arguments - If a report query uses arguments, a dialog is shown when you edit the report, or preview the report, to prompt for argument values. In some cases, reports use a large number of arguments and the dialog that prompts for their values becomes cumbersome. Therefore a new, resizable dialog (shown in the image below)  is now available to prompt for argument values. The new dialog has the added benefit of allowing you to save and then restore argument values.

 


NOTE If you prefer the old dialog to this new dialog, you can revert to the old dialog by selecting the View, Settings menu command and then navigating to the Preferences, Arguments section.

 

UX Component - Embedded Object - A5W Page - You can now include control placeholders in the query string for the embedded .A5W page.
The query string can reference the value in other controls on the component. For example, in the image below, the URL is: page1.a5w?name={name}

 


The query string is: name={name}.


When the embedded .A5W page is rendered, the resolved query string will be used.

UX Component - Embedded Object - A5W Page - Live Refresh - If the URL for the embedded .A5W page includes control placeholders you can automatically refresh the embedded .A5W page when any of the references controls change value. To turn on live refresh check the Live refresh property in the UX builder (as shown in the image above)

SQL Builder - Font Size - You can now increate the font-size shown in the SQL window in the SQL builder.

 

UX Component - List Builder - Freeform Template - Filter Available Placeholders - When designing a freeform template you can now filter the list of available Placeholders that can be inserted into your freeform layout. This can be helpful if your List query returns a large number of fields.

 

 

UX Component - List Builder - Selecting Fields in a Table - If your List is based on a table with a large number fields, selecting the fields you want to return in your List query can be difficult if the table you are basing the query on has a large number fields. This is because the list of available fields is presented in the same order that they are defined in the table. The Select Fields dialog now has a Sort button to sort the list. Each time the button is pressed, the list is sorted. First click sorts alphabetically in ascending order. Second click sorts alphabetically in descending order and third click returns the fields to their "natural" (i.e. unsorted) order.

 

UX Component - TextBox - In-control Buttons - When you are defining in-control buttons for a Text Box control, a new option is available in the Pre-defined buttons list. The Show/hide password option will add a button that shows the password you have typed into the control in plain text. Pressing the button a second time will revert the control type to password.

 

 

Bugs

UX Component - Radio Buttons - Client-side Enable Expressions - Fixed an issue.

UX Component - List Control - Drag Re-order - Client-side Group Breaks - Drag re-order now works is List has client-side group breaks turned on.

UX Component - List Control - CSS - Fixed a regression concerning CSS defined in the List builder.

UX Component -  CSS Icons - Fixed an issue with CSS Icons not rendering.

Grid and UX Components - Arguments - Line Breaks - Fixed an issue when passing argument values if the argument value had a cr-lf character.

UX Component - List Control - Freeform Layout - Fixed an issue if the free-form Layout contained both the placeholder for in-place edit icons and also the placeholder for zero based row numbers.

UX Component - List Control - InPlace Edit - Fillin Fields - Fixed an issue where fill-in fields were not filling in columns that were set to not allow edit and where the fill-in value was blank or null.

UX Component - List Control - Parent-Child Lists - Paginated - Allow Null - If a UX has two Lists that have a parent-child relationship and if the parent List was paginated (and if the Parent List was set to Allow NULL = false), the data in the child List was not automatically refreshed when the parent List was navigated to a new page.

CPU Usage - Fixes an issue with occasional high CPU usage. Issue was introduced in build 6516.

UX Component - Data Bound - Server Side Actions - Get Primary Keys - Slider Navigator - Fixes an issue with the Slider record navigator.

Web Applications - Classic Server - a5_application.a5i - Caching - The a5_application.a5i file was not being cached when the first request after publishing any file to the server was made. As a result it was possible, in rare situations, that the performance of the server would degrade slowly until the server was restarted.

AlphaDAO - Custom Xbasic Driver (e.g. Audit Trail, Multi-tenant) - Using a Custom Xbasic driver could cause a thread state invalid message in the Windows Event Log

 

 

Alpha Anywhere V4.6.1.9 - 6488 5436 28 FEB-2020

Videos

UX Component - List Control Reading Information (such as record count) from the List's state Object A common requirement with a List control on a UX is to know how many records are in the List (and in the case where the List is paginated, how many pages of data the List has and what page you are currently on). For Lists based on SQL tables, you might also want to know what the current filter and order for the List are. All of this information is available in the List's state object.

In this video we show how the record count can be read from the List's state object.


Watch Video
Date added: 2020-02-14

Features

Web Components - Language and Text Dictionary Tags - Rendering Method - In many places in the various component builders in a Web Application you can language (<A5:r>..</Ar:r) or text diction (<a5:t>..</a5:t>) tags to indicate that the text should be translated into a different language at run-time, depending on the user's preference. Now, these tags are easier to distinguish in the property grid because they are displayed in red.

 

Xbasic - Xdialog - Property Grids -  You can now format display values in the property using the new format directive as shown in the example below.

The format directive allows you to specify the name of an Xbasic function that will format the value. In the example below, the property grid value for the ++Table name property is 'customer', but the format function (myForm) adds square brackets so the property grid displays [customer]

Example:

 

dim TableName as c = "customer"
ps.def = <<%str%
^^Category 1
	state=open
	++Table name
		var=TableName
		format=myForm(<value>)
%str%

ui_dlg_box("Table", <<%dlg%
{propgrid=100,20ps}
%dlg%)

function myForm as c(name as c)
	myForm = "["+upper(name)+"]"
end function

		
	

UX Components - List Control - In-place Editing - Spacing - You can now set the spacing between controls when the List row is in edit mode. Previously, the spacing was set to 20px.

 

To set the spacing, edit the List and then on the Fields pane, click the smart field for the In-place edit Control settings.

 

Web Control Panel - Copying Components Into Folder - When you paste Web Components into the Web Project folder, a dialog appears asking if you want to make an initial backup for this component. Some users have requested the ability to suppress this dialog. You can now do so by adding a file called SuppressInitialBackupWarning.txt to the Web Project folder. The actual contents of the file does not matter.

Desktop Applications - Forms and Browse - Export to Excel - .xlsx - Export to Excel now exports files as .xlsx files.

 

Web Applications - Bulk Updates - UX Components - Suppress Prompts and Warnings - When a Bulk Update operation on UX Components is executed you can now choose to suppress the prompt and warnings that are normally displayed when a UX is edited and recalculated. This is helpful if you want to run a Bulk Update operation on a large web project in unattended mode.

 

Web Server - Classic Server - Logging - There was no definitive way to correlate entries in the various Classic Server logs with each other in order to ensure you are looking at the details for the same request. The Raw HTTP log has always included a Thread ID and a Request Sequence. These two values together are a unique identifier for the request being processed. The Access and Error logs now also record these values for each log entry. The exact format of these details varies across the logs in order to keep the log formats consistent with their historical formats. An example of an error recorded in all 3 logs is shown below.
 

UX Component - List Control - In-place Editing - Add New Row - Focus Row - When you click the + button to add a new row, focus is automatically set to the new row. Previously the focused row was not changed.

UX Component - List Control - In-place Editing - New Events - Two new events are available in Lists that are configured to allow in-place editing.

 

Bugs

UX Component - Javascript - {dialog.object}.setListTemplateAndPopulate() Method - Fixed this method that allows you to define a new template for a List's Freeform layout and also populate the list with data.

List Control - Custom Data Source - Server-side Conditional Formatting and Server-side Display Format - If the Xbasic function that produced the data for a List that was based on a Custom data source did not return "proper" JSON (e.g. it returned [{name: 'Fred Jones'}] as opposed to [{"name": "Fred Jones"}] and if the List used any server-side Display form or Conditional Style, the List did not render any data.

UX Component - Copy and Paste Controls - Collapsed Containers -  Fixed an issue with copy/paste of container controls that were in a 'collapsed' state.

Grid Components - Radio Button Controls - Client-side Show/Hide and Enable Expressions - Fixed an issue where a client-side expression was based on the value in a Radio Button control

Trace Window - Working Preview - Fixed an issue when writing to the Trace window from a component that was running in Working Preview.

UX Component - Fields Tab - Client-side Conditional Style - Fixed an issue were certain types of expressions were being incorrectly flagged as invalid in the Conditional Style Builder.

UX Component - List and ViewBox Controls - Delay Render Till Visible - Fixed an issue that occurred when a List or ViewBox control had their Delay Render till Visible property checked and the List or ViewBox was inside a PanelCard that was inside a PanelLayout or a PanelNavigator.

UX Builder - Text and Language Tags - Fixed an issue that could occasionally occur when getting a list of the text and language tags used in a component.

PhoneGap - PhoneGap-Shell-V2 Template - IIS - Made a change to the PhoneGap-Shell-V2 Template to fix an issue when the Server was set to point to an IIS server.

Alpha Cloud - Publish - Security Data - There were occasional errors when publishing security data to Alpha Cloud. This was tracked down to the MySQL bulk loader not being thread safe. This has now been addressed. This change does not affect on-premesis IIS installations which did not have any problem.

UX Component - Data Bound - New Record - Unbound Controls - When you clicked on the New Record button to create a new record in a data bound UX, the values in any unbound controls on the component were getting reset to their initial values. The values in controls that were not data bound should not have been updated.

UX Component - Find Command - A regression was introduced in the last release causing the Find command to fail if the UX contained any Embedded Component controls.

UX Component - Repeating Section - .setValue() Method - The .setValue() method allows you to set the value in a specific row in a Repeating Section. For example, {dialog.object}.setValue('LASTNAME:3','Smith') should set the value of the LASTNAME control in the 3rd logical row in the Repeating Section. This failed if the Repeating Section had been previously resized to a number of rows that was smaller than its original size and then increased to a number of rows greater than its original size.

UX Component - .getValue() Method - In certain rare situations, the .getValue() method returned an incorrect value if the UX was not dirty.

UX Component - .getValue() Method - Watermark - If the UX was clean, the  .getValue() would return the wrong value for controls that were displaying the Watermark text. Once you had replaced the Watermark value with a typed-in value .getValue() would return the correct value.

 

 

Alpha Anywhere V4.6.1.8 - 6465 5428 17 FEB-2020

Videos

 

UX Component - List Control In-place editing - Capturing Edited Rows and Old Values (Advanced Users) When you are editing the data in a List row using in-place editing, and you have the List Detail View turned on, and the List is based on a SQL table, Alpha Anywhere generates the SQL statements to perform the CRUD operations automatically. However, there may be situations where you want to generate your own SQL CRUD. To do this, you will need to know which rows have been edited, and for each edited row you will need to know the current values in each List row as well as the original values.

In this video we show how this can be done.
Watch Video

Date added: 2020-02-03
UX Component - Multi-select Tokens Control Adding Tokens to a SQL Database The Multi-select Tokens control allows you to select tokens from a pick-list and (optionally) type tokens into the control. You can configure the control to only allow tokens that are in the pick list or to allow the user to type in any token value. If the user types in a token value that is not in the pick list you can fire a notInList event and add the token to the pick list (and to the database table that backs the pick list).

In this video we show how a token value that a user enters is added to a SQL table.

Watch Video
Download Component
Date added: 2020-02-11
     

 

Features

 

 

 

SQL Reports - DataSource Builder - Arguments - Export/Import Arguments Definition - When defining a SQL report data source, the builder now allows you to export and import argument definitions.

 

UX Component - Action Javascript - Open a UX Component Action - When you define an action to open a UX in a Window, you can specify that the a cached version of the component should be used the second and subsequent time it is opened. You can also specify that the data bound controls can be populated with the child UX is both opened the first time and also opened subsequently. Now in addition to repopulating the data bound control when the child UX is both opened and re-opened, you can also specify the certain controls (such as Lists and Viewboxes) should also be refreshed when the child UX is re-opened.

 

 

 

UX Component - Find Dialog - Previously you could only find certain control types (such as Buttons, Static Text) by the text that display in the UX builder control tree. Now you can also search by ID

 

 

UX Component - MultiSelectTokens Control - inputFocus() Method - The MultiSelectTokens control now has a new method that allows you to set focus to the control.

 

Watch Video
Download Component

 

For example:

 

var vobj = {dialog.object}.getControl("MULTISELECTTOKENS");

vobj.inputFocus();
 

UX Component - Map Control - ViewBox - Adding Markers to Map - Action Javascript has previously allowed you to add multiple markers to a Map control using data that is stored in a List Control. Now you can also add multiple markers to a Map control using data that is in ViewBox control.

 

UX Component - ViewBox Control - Action Javascript - Two new action are available for the Action Javascript action for ViewBox controls. These are:

 

 

UX Component - List Control - Checkbox Column - onRowCheck Event - A new event has been added to the List. The onRowCheck event will fire if the List has the Checkbox column turned on and the user toggles the checkmark in a row in the List.

 

New Version Notice - Suppress in Runtime - You can now suppress the New Version warning for Runtime applications.

 

UX Component - Find Dialog - Collapsed Containers - Previously the Find Dialog did not search inside containers that had been collapsed. Now the search is performed in all containers, but if a match if found in a collapsed container, the dialog will warn you that you can't set focus to the control because it is inside a collapsed container.

 

Publishing Files - Saving a File List - When you publish your Application, the Publish dialog gives you the option of publishing all files, selected files, or the currently selected file in the Web Control Panel. If you select the Selected Files option you get a dialog where you can select the files you want to publish. The list of files you select can now be saved with a name so that you can quickly retrieve a previously saved list of files.

 

 

Editors -Search - When you open the Search or Search and Replace dialog, the currently selected text (if any) will be shown as the default in the Find What? text box.

UX Component - List Control - In-place Edit - SVG Icons - Sizeable - The default class name for the SVG icons used in in-place edit has been changed from icon to iconSizeable. As a result of this change you can now more easily adjust the size of the SVG icons used for in-place edited (previously you had to change the icon class name from icon to some other class that did not specify the icon size before you could adjust the icon size).

UX Component - Width Property - Custom Class - <none> - If you have a control in your UX and you specify a custom class for this control and the custom class specifies a width property, the width set in the class will not be used unless you also use the !important CSS flag in the custom class definition. Now, you can set the control's width property to <none> and the width specified in the custom class will be honored (without requiring the !important flag).

UX Component - Ajax Callbacks - Submit List Data - When you make an Ajax callback from a UX you can now automatically submit the data from all of the Lists on the UX. This could potentially submit a large amount of data when the callback occurs (as the List may have a large number of rows of data in it) and you should only turn this property on if you really need access to the List data in your server side event handler.

The List data will be available in the e.__listData property in the e object passed to your Xbasic function that handles the callback. e.__listData will be a JSON array with a listId and data property in each array item.

 

 

 

Xbasic -  word_merge_python() Function - Performs a Word Mail Merge Operation - A common requirement is to create a Microsoft Word document from a Word template by merging data into placeholders in the Word template documents. There is an existing Xbasic function to do this (the a5_word_merge_dotNet() function), but this function requires that Microsoft Word is installed on the machine where the Alpha Server is running. This precludes the a5_word_merge_dotNet() function from being used in applications that are hosted on Alpha Cloud). The word_merge_python() function does not require that Word be installed and also, this function is significantly faster than the the a5_word_merge_dotNet() function.

 

Syntax

p Result = word_merge_python(C fn_template,C fn_out,C json)

Where:

 

Another significant benefit of the word_merge_python() function is the ability to merge data from nested Arrays in the input JSON data into tables in the Word template. Additional rows are automatically added to the table in the template document to accommodate all of the rows in the nested array in the input JSON.

IMPORTANT: In order to use the word_merge_python() function you must install Python, which (as of the time of this writing) is not installed by default when you install Alpha Anywhere. Installing the Python dependency in the Alpha Anywhere IDE is done by selecting the Tools, Packages menu command when the Web Control Panel has focus



Installing the Python dependency in your Web Project is done by clicking the Project Properties button on the Web Control Panel and then clicking the smart field for the Referenced Packages property.

 

How to Create the Word Template

To create the Word template, create a new Word document and then insert placeholders in the Word document for the fields in your JSON data.

To insert a field placeholder, put your insertion point at the place where you want to insert the placeholder and then press Ctrl-F9.

This will insert a pair of braces as shown in the above image (DO NOT type the braces yourself).

Type (case insensitive) the following between the braces:

Mergefield name_of_field_in_json_data

For example, say you have a field in your JSON data called Firstname, you would type:

When you are done, press the F9 key (with the insertion point inside the braces). The document will then show the placeholder as follows:

To edit the placeholder, right click on it and select Edit Field...

 

How to Define Tables in the Word Template for Array Data in the JSON

To insert data from a nested array into a table in the Word Template, insert a Table into the Word document, The table should have two rows - one for column headings and one for placeholders, and as many columns as you need (plus one additional column - which can be hidden, as explained later- where the Linking field must be specified).

For example, consider the following JSON data. This data has a nested array called Children.

{
    "Firstname": "John",
    "Lastname": "Smith",
    "City": "Boston",
    "State": "MA",
    "Children": [
        {
        	
            "Name": "Callie",
            "Age": 5
        },
        {
            "Name": "Griffin",
            "Age": 3
        },
        {
            "Name": "Luke",
            "Age": 1
        }
    ]
 }		
		

The Word template should have a table that looks like this (Note, the << >> characters are not typed in yourself - they are inserted by Word automatically when you insert placeholders as explained above - i.e. by pressing Ctrl - F9):

 

  Name Age
<<Children>> <<Name>> <<Age>>

 

Notice that the first column (i.e. the linking column) has a placeholder with the name of the nested array (Children). The column heading for this this column is irrelevant (and is blank in this example). The data in the array is shown using placeholders in the second row (columns 2 and 3). The column heading for the data columns can be anything you want (i.e. they do not have to match the names of the data properties).

 

How to Hide the Linking Column

To hide the linking column (i.e. the first column), select the first column and set the font color to white on white. Then set the font size for the column to 1 pixel (the smallest value Word allows), then set the cell border to none, then drag the column divider to the left to make the column as narrow as possible.

After you do this, the first visible column (the Name column in this example) will not have a left border, so select the column and turn on the border for all edges.

Watch Video

 

 

Example

 

Assume the following JSON data:

{
    "CUSTOMERID": "123",
    "FIRSTNAME": "Fred",
    "LASTNAME": "Thomas",
    "COMPANY": "Alpha Anywhere Development",
    "ADDRESSES": [
        {
            "ADDRESSTYPE": "Billing",
            "ADDRESS": "123 Billing Street",
            "CITY": "Boston",
            "STATE": "MA",
            "POSTALCODE": "02134"
        },
        {
            "ADDRESSTYPE": "Headquarters",
            "ADDRESS": "987 Headquarters Lanest",
            "CITY": "Burlington",
            "STATE": "MA",
            "POSTALCODE": "01803"
        },
        {
            "ADDRESSTYPE": "Shipping",
            "ADDRESS": "33 Shipping Ave.",
            "CITY": "Lexington",
            "STATE": "MA",
            "POSTALCODE": "02142"
        }
    ]
}		
		
 

Assume a Word template document that looks like this (You can download this template by clicking here):

NOTE: The linking column in the table is now shown, as it has been hidden. The first column in the table actually has a placeholder in the second row called Addresses to indicate that the table will display data from the nested ADDRESSES array.

Xbasic to merge data into template:

dim json as c

json = <<%txt%

    JSON data shown above goes here......

%txt%

dim fn_template as c = "c:\word\template.docx"
dim fn_out as c = "c:\word\template_out.docx"
dim p as p
p = word_merge_python(fn_template,fn_out,json)

 

 

The resulting Word document showing the placeholders replaced with data and showing the Table expanded to show all of the data in the nested array will look like this.

 

 

Advanced Actions

Here is a sample JSON definition for the fn_out parameter to specify that the resulting Word document should be uploaded to an Amazon S3 bucket. (Important: Your Alpha Anywhere connection string must not be encrypted). The objectName can specify a folder in your S3 bucket.

{
    "type": "Store",
    "storageConnectionString": "your_AA_storage_connection_string",
    "objectName": "word_merge/document1.docx"
}

 

Here is a sample JSON definition for the fn_out parameter to specify that the resulting Word document should be emailed:

 

{
    "type": "email",
    "apikey": "your SparkPost or SendGrid API key",
    "send_to": "comma delimited list of email addresses",
    "send_from": "email address of sender",
    "send_from_friendly_name": "name of sender",
    "subject": "subject",
    "message": "message body",
    "attachment_filename": "name of attachment file e.g. invoice.docx"
}

 

NOTE: If you are using SendGrid, prefix the API key with sendgrid: .

 

Documentation - Xbasic - A new Xbasic Guide is available. Click here.

 

Application Server - Logs - Fewer Warning Messages -  Previously the logs for both the Classic Server and IIS Server would report warnings in the Xbasic error log if you set a session variable to a non-character value. These warnings are no longer reported. Also, if your component submitted data that would result in an invalid variable name (for example, you submitted a form with an input control that had a name of first-name, the logs would contain a warning that the variable had been renamed to first_name. In the case of the Grid component, which uses a naming convention of V.R[rownumber].NAME for variables (where [rownumber] is a negative number for new record rows), the Xbasic error log could contain a large number of warnings (that a variable of the form V.R-1.NAME had been renamed to V.R_1.NAME). These warnings are now suppressed in the Xbasic Error logs.

As a result of these changes, the Xbasic Error log will be smaller, and will be easier to read, as it will no longer have so many warnings.

UX Component - Manifest - PhoneGap - A Manifest allow you to specify a list of files that can be downloaded and installed on a device so that the files are available even if the device no longer has an internet connection. Previously, only one manifest could be specified. Now, you can define named manifests and you can download and install multiple manifests on a device.

The default manifest is automatically given a name of Default Manifest.

The Action Javascript Manifest actions allow you to specify the name of the Manifest that the action applies to.

Two new action have been added to Action Javascript - Manifest Action. These are:

 

 

Bugs

UX Component - MultiSelectTokens Control - inputFocus() Method - NotInList Event - Fixed a regression resulting in the NotInListEvent not firing when the user typed a value into the multi-select-tokens control.

UX Component - List and ViewBox - DelayRenderTillVisible - Both the List and ViewBox controls have a property that delays the rendering of the data in the control (property is only available for certain data source types, such as SQL) until the control is actually visible. Determining if the List or VieBox is visible is now more robust and this property should now behave more predictably.

UX Component - Ajax Callbacks - Radio Buttons - As a result of a recent regression, if the UX was "clean" the value of Radio Button controls in the e.dataSubmitted object passed to the Xbasic function handler was not set.

SQL Builder - Focus - Fixed a focus issue when the Filter tab had focus and the user tried to edit the SQL text.

UX Builder - HTML Controls - Class Name - The way in which the user specified class name for certain controls (i.e. textbox, textarea, etc.) is applied has been fixed. Now, when you specify a class name you can specify if the class name is in addition to, or replaces the default class name for the control. Prefix the class name with a + character to indicate it is in addition to the default class name for the control type. If you do not use the + prefix, the class name you specify is used in place of the default class name for the control type.

 

AlphaDAO - Oracle - PortableSQL - AddMonthsToDate() Function - Changed the way native SQL is generated for Oracle for the AddMonthsToDate() portable function.

Application Server - Memory Leak - Fixed a memory leak when running old UX components that had not been edited and resaved for a long (unclear how far back) time.

UX Component - Repeating Sections - Image and File Upload - Data Binding - Fixed an issue when uploading images or files in a Repeating Section. The uploaded file information was not persisted to the corresponding data bound field in the target table.

AlphaDAO - Native SQL - Trailing Spaces - If the SQL statement you executed using Native SQL contained a trailing CRLF and did an insert, the last inserted identity was not correct.

 

UX and TabbedUI Component - In certain cases the server would return a 500 error reporting an issue in the a5wcb_createBackupForImportedComponent() (the reported error was: Error calling 'XDialogBox' .a5wui method')

 

Application Server - Gzip Caching - The Application Server was not correctly recognizing that a static asset had changed after it was initially requested.

For example, say you requested:

http://www.myapp.com/image1.jpg

 

Then changed image1.jpg on the server and then requested:

http://www.myapp.com/image1.jpg?1234

The new image was not rendered.

 

UX - List Control - Action Javacript - Filter Records in a List - Date Fields - Range Search - Fixed an issue when executing a range search on a Date type fields (Datetime fields worked OK).

 

 

Alpha Anywhere V4.6.1.7 - Build 6402-5418 19-JAN-2020

Hotfix - Fixes a Server issue where the server reports a 500 error with a message regarding the a5wcb_createBackupForImportedComponent() function

Hotfix - Fixes a Developer Version issue when you try to edit certain UX or TabbedUI components. The reported error is concerning creating an initial backup of a component that has no existing backups.


How to install a hotfix

Videos

UX Component Keyboard Friendly Edit-Combo In order to make a UX component that is "keyboard friendly" (i.e. minimizes the need for the user to use the mouse to tap on a button to open a pick-list), the edit-combo control can be configured to open automatically as soon as the user tabs into the control, and then once the user makes a selection from the pick-list, you can set focus to the next control.

in this video we show how you can configure the edit-combo to behave in this "keyboard friendly" manner.

Watch Video

Date added: 2020-01-03
UX Component - Pusher Service Real-time Messaging using the Pusher Service Real-time applications are typically built using web-sockets. However, it can be tricky to set up web-socket applications, especially if your application is behind a load balancer. The 3rd party Pusher service (www.pusher.com) makes it very easy to build real-time applications that allow you to broadcast messages on a 'channel'. All clients that subscribe to that channel will receive the message.

In this video we show how the UX component can be configured for real-time applications using the Pusher service.

Watch Video

Download component

Date Added: 2020-01-05
UX Component - Pusher Service Real-time Location Reporting using the Pusher Service In this video we show how you can build a real-time location reporting application. When a user 'reports' their location, a marker is automatically added to a map control showing the location of the user.

Watch Video - Part 1
Watch Video - Part 2

Download component

Date Added: 2020-01-05
     

 

Features

PhoneGap - Session Variables - As a result of changes that Chrome recently introduced concerning third-party cookies, session variables in PhoneGap applications running on certain mobile devices were not working.

Because of some bugs in Chrome, the behavior of session variables is not consistent across all versions of Chrome.

If the UI Web View in your PhoneGap application uses versions of Chrome older than version  67, session variables now always work, regardless of the setting for Same Site Mode (See note on Cookies below). For versions of Chrome 67 and above, the Same Site Mode should be set to None.

NOTE: If your PhoneGap App uses the new Alpha WkWebView plugin for iOS apps, session variable always work correctly on iOS devices, regardless of the setting for Same Site Mode.

Web Projects Control Panel - Show Publish History for File - You can now display information about the publish history for a file. Right click on the file in the Web Control Panel and select the Show Publish History... command.

 

 

This will display a dialog like the one shown below. The Target Folder column shows where the file has been published. The Time stamp of Published File column shows the timestamp on the file that was published.

The use case for this feature is to allow you to easily find out if a particular file in your Web Project has been published to your Web site.

 

 

 

 

UX, Grid and TabbedUI Components - Real-time Applications using the Pusher Service - Real-time applications are typically built using web-sockets. But setting up web-sockets can be tricky, especially if your application is behind a load balancer or runs on Alpha Cloud. An alternative to setting up web-sockets yourself is a 3rd party service called Pusher. You can now easily create real-time applications using the Pusher service. You can sign up for a free Pusher account at www.pusher.com .

Basic messaging

Watch Video

Download component

 

 

Real-time location reporting

Watch Video - Part 1
Watch Video - Part 2

Download components
 

 

How Pusher Applications Work

Pusher applications follow a publish/subscribe model. Your components can subscribe to certain channels. Server-side code can broadcast messages on different channels. When a message is broadcast on a particular channel, all clients that are subscribed to that channel will receive the message and the client-side onPusherMessage event will be invoked.

 

Configuring a UX, Grid or TabbedUI Component as a Pusher Application

To configure a UX component as a Pusher application, go the the Pusher Real-time Application section in the UX Builder Properties and check the Pusher application property.

Grid and TabbedUI components also have a Pusher Real-time Application section in their builders.

 

 

This will enable the Pusher configuration property where you can specify your Pusher account credentials and other properties.

 

 

The Pusher Configuration dialog is shown below.

 

 

This dialog allows you to specify the following properties (from your Pusher account when you sign up at www.Pusher.com ):

You must also specify the URL from where the Pusher JavaScript library will be loaded.

Finally, you can specify the channels that you want to subscribe to.

NOTE: You can leave the Channels prompt blank and then use Action Javascript to create an action that subscribes to a particular channel later.

 

 

Action Javascript

Action Javascript allows you to perform certain Pusher service actions. (Only available in the UX Component.)

 

 

 

Pusher Service Actions

 

 

Client-side Events

A new client-side event is available. The onPusherMessage client-side event fires when a message is broadcast on a channel that the client is subscribed to. The code in your client-side event handler can reference these properties:

 

Broadcasting Messages

Messages are broadcast using server-side code. The pusher_sendMessage() Xbasic function is used to broadcast messages. The syntax for the pusher_sendMessage() function is:

 

pusher_sendMessage(C appId ,C key ,C secret ,C cluster ,C channel ,C message [,C eventName [,C componentConfigJSON ]])

 

Where

This function returns a void. I.e. it does not return any value.

Example:

Send a message on the 'channel3' channel using Pusher settings that are stored in the component's Pusher configuration:

 

dim message as c = "This is a Pusher message sent at: " + now()

dim channel as c = "channel3"

dim configJSON as c = e.tmpl.pusherConfigJSON

pusher_sendMessage("","","","",channel,message,configJSON)

 

Sample Components

When you create a new UX component you can select a Pusher Service template to get a quick start on building your Pusher application.

 

 

UX Component - List Control - Persist Layout Changes - When you make changes to a List layout at run-time (e.g. show/hide columns, re-order colors, re-size columns, select the active Layout), these changes can be persisted to Local Storage so that the next time the List is rendered, the settings are automatically restored.

 

 

UX Component - Action Javascript - List Control Actions - New actions to persist and restore List layouts.

 

 

Cookies - The Google Chrome browser has introduced a new policy for handling cookies to make them "secure-by-default". See https://blog.chromium.org/2019/10/developers-get-ready-for-new.html.

This change has been pushed out on a limited basis, but will become generally available with Chrome version 80 in February 2020. Other browsers are pledged to follow suit. This change is intended to increase security and privacy.

A cookie's SameSite policy will be enforced to prevent cross site access to those cookies. Some 3rd party site integrations may not behave as expected once this change is in place. For example, a 3rd party payment handler/processor may rely on the previous behavior for cookies (which made the cookies available). When using version 80 or later of Chrome, the cookies will not be available to the 3rd party site.

If a web application has a 3rd party site integration that is not working as expected, use the Chrome developer tools to view the browser's console. A message like this will likely be there:

A cookie associated with a cross-site resource at <3rd part site> was set without the 'SameSite' attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with 'SameSite=None' and 'Secure'. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592  and https://www.chromestatus.com/feature/5633521622188032.

Alpha Anywhere has been enhanced to default its cookies to use the most secure SameSite policy of "Strict". No changes need to be made to an application for this setting to be used. Only build 6382 or later of Alpha Anywhere Application Server or the Application Server for IIS need to be installed.

If an application needs to have access to Alpha Anywhere system cookies such as the session cookie or authentication cookie in a cross-site way, the cookie SameSite policy may need to be set to "Lax" or "None". "None" will result in the same behavior as before the SameSite policy existed.

The SameSite policy can be changed in one of two ways.
For Alpha Anywhere Application Server, the cookie SameSite policy can be set in the server settings dialog on the advanced tab in the Sessions section.



For Alpha Anywhere Application Server for IIS, the cookie SameSite policy can be set in the Web Project Properties dialog.



Note Cookies set by an application using Context.Response.AppendCookie() can set the SameSite property on the cookie passed to it. For example:

dim cookie as System::Web::HttpCookie = new System::Web::HttpCookie("MyCookie", "MyCookieValue")
cookie.HttpOnly = .t.
cookie.SameSite = System::Web::SameSiteMode::None
Context.Response.AppendCookie(cookie)
 

 

UX Component - Action Javascript - PDF From HTML - Page Size and Method - You can now specify the method you want to use to convert HTML to PDF. Previously Alpha Anywhere would always use PhantomJS if it was installed and would fall back to WebKitToHTML. Now you can explicitly select the method. If you select PhantomJS and it is not installed, Alpha Anywhere will still automatically fall back to using WebKitToHTML.

The Action Javascript builder for this action now include a prompt for Method for generating PDF.

If the method is set to PhantomJS you get options to set the page size. Previously, page size settings for PhantomJS were not being honored.

 

 

UX Component - List Control - SQL Database - Export to Excel - Non-Portable SQL - If you define an action on a List to export data in a List query to Excel and if the user has applied a filter to the List and has specified that the List does not use portable sql, and if the SQL cannot be parsed by Alpha Anywhere, previously Alpha Anywhere would export all of the records in the List query. Now, it will try to export only the records that satisfy the List query.

UX Component - Control Bar - Dropdown Menu - Xbasic - A new action in Action Javascript allows you to refresh the data in any dropdown menu controls in the Control Bar.

NOTE: This action is only meaningful if the dropdown menus are populated using Xbasic.

 

 

UX Component - Action Javascript - Upload Files to S3 - Xbasic - After Upload Complete - When you define an action to upload files to Amazon S3 you can now specify the name of an Xbasic function to call once all files have been uploaded. The e object passed to the Xbasic function will contain an array with the names of all of the files that were uploaded and the object name on S3 of each uploaded file. The Xbasic function call is made by performing an Ajax callback to the server.

 

 

Loading jQuery - Protocol - PhoneGap - For web applications, when you load jQuery from a remote location, the same protocol as the the host page is used. However, for static pages and PhoneGap applications you can now specify what protocol to use.

 

 

UX Component - Edit Combo - Set Focus After Selection - A new property has been added to the Edit-combo control that now allows you to specify the ID of a control that should get focus after a selection has been made from the pick-list.

 

 

This allows developers to created more "keyboard friendly" user interfaces. See video.

 

Tabbed UI - Search Feature - Execute Action - If you have enabled the Search feature in the TabbedUI component, then, if the user does a search that finds a single item, you can allow the user to "click" the button by pressing the Enter key, or you can automatically "click" the button (to open the component associated with the item that was found).

In the Tabbed UI Properties, the following new properties are available:

 

 

 

Xbasic - Dates - 2 Digit Years - All two digit years are now considered to be in this century. Previously only 2 digit years between 00 and 19 were considered to be this century.

For example:

?ctod("1/1/20")

= {01/01/2020}

 

UX Component - List Control - Export to Excel or Ascii - Coded Values - When you export data in a List you can select whether to export the data shown in the List or the data in the List query. If the List is not paginated, these two choices are the same. However, if the List is paginated, there can be many more records in the List query than are shown in the List (because the List only shows one page of records at a time). When you export data from the List (using the export data in List query option), if any of the fields in the List contain coded values, you can now choose if the coded values should be resolved.

 

 

NOTE: If the export is defined as "Records in the List", then coded values are always resolved.

UX Component - List Control Builder - Improved performance opening the List builder when the List is based on a SQL table with a large number of records.

Bugs

 UX Component - PhantomJS - Fixed an issue when using the PhantomJS library from server-side Xbasic code that could result in a server crash. (PhantomJS is used to convert HTML to PDF).

UX Component - Repeating Sections - Radio Buttons - Set Dirty - Changing the value in a Radio Button control in a Repeating Section did not cause the UX to go dirty.

 

REST Services - Swagger Test Page - Security Framework - If you publish a REST API to a server that has the security framework turned on, you will no longer get a permission denied (403) error when trying to access the Swagger page to test the API.

IMPORTANT: You must right click on the service name in Web Control Panel and select Page Properties, Always Allowed.

Application Server for IIS - Session State Storage - S3 - If session state storage was configured to use Amazon S3 (as is the case for Alpha Cloud), under some circumstances, saving data to a session file was failing.

 

Grid Component - Search Part - Date Fields - "Last week" - Fixed an issue with the "Last week" pre-defined search range.

UX Component - List Control - In-place Editing - Data Pickers - If a List row has 2 or more data picker controls, making a selection in one of the data pickers would update all of the data picker controls.

HTML Reporting - Layout Table Reports - Images - Images size was not scaled to the size of the layout table cell.

UX Component - List Control - Dynamic Images - Image Sequences - In-place Editing - Fixed an issue with image sequences when a row in a List was edited.

Active Link Tables - Sets - Fixed a regression in sets built from active-link tables (desktop applications).

 

 

 

Alpha Anywhere V4.6.1.6 - Build 6348-5409 22-DEC-2019

 

Videos

UX Component File Upload using Drag and Drop You can upload files to either Amazon S3 or to your Alpha Anywhere server by dragging and dropping files onto a 'drag drop area' on your UX component.

This video shows how to configure drag and drop file upload.

Watch Video

Date added: 2019-12-11
Xbasic Generate a File in an Ajax Callback and then Download It. In UX and Grid components you might want to make an Ajax callback to the server and then generate a file on the server which the user can then download. The file that you generate on the server might be an Excel file, a PDF document, a Word document, etc.

In this video we show how you can create the Xbasic function that handles the Ajax callback, creates the file and then generates the necessary Javascript to send back to the browser in order to download the file.

Download component
Watch Video

Date added: 2019-12-18
     

 

Features

Alpha Cloud - A new tutorial on best practices for deploying applications to Alpha Cloud is available here.

Xbasic - a5Helper_generateFileDownloadJS() Helper Function - A new Xbasic helper function is available for use in Ajax callbacks to generate the necessary Javascript to download a file to the browser. The file is created during the Ajax callback.

Syntax:

c javascript = a5Helper_generateFileDownloadJS(c componentAlias, c filename [,c clientsidefilename])

 

Where

For example, say you have a UX component with a button. When you click the button, you want to make an Ajax callback to the server, generate an Excel file on the server and then allow the user to download the file.

Watch Video

Here is the sample Xbasic function you would need to handle the Ajax callback:

function generateExcelFile as c (e as p)
dim js as c = ""
json = <<%a%
[
    {"id": "1", "firstname" : "Fred", "lastname": "Jones"},
    {"id": "2", "firstname" : "Tom", "lastname": "Smith"}
]
%a%
'Get a Temp file name
dim filename as c = Request.GetRequestTempFileName("xlsx")
 

'Write json to temp file
a5_json_to_excel(json, filename)

dim clientsidefilename as c = "myexcel.xlsx"
dim componentAlias as c
componentAlias = e.tmpl.alias

'generate the javascript response to send the file
dim js as c
js =a5Helper_generateFileDownloadJS(componentAlias,filename,clientsidefilename)
generateExcelFile = js
end function
 

Optimizations for the  extension::curl::DownloadMultiple() Method - This method is used when you have a report that has images that are links to remote files. It downloads all of the referenced images into a temporary folder on your computer before the report is rendered. The performance of this function has been significantly improved. As a result, reports that reference remote images should not render quicker.

UX Component - List Control - Coded Values - Export to Excel - When you export List data to Excel, and coded fields are decoded.

UX Component - List Control - InPlace Editing - OnEdit and AfterEdit Events - Two new event types have been added for fields when in-place editing is enabled.

 

The onEdit event fires when the List row goes into edit mode. This event can be used to format the data for editing.

The afterEdit event fires when the List data is saved. This event can be used to un-format data.

 

For example, assume you have a List that has a field called DOB (date of birth) and the data type of this field in the SQL database that is the source of the list data is datetime. If the regional settings of the machine where the server is running is US, the data in the list will be stored in this format: MM/dd/yyyy. So a particular value might be 12/24/1972.

You might format this value to display using dd.MM.yy format by setting the field's Date/time display format property as shown in the image below:

 

 

This will cause the List to display the date value as 24/12/1972 (assuming that the default date format for the UX was set to dd.MM.yy format). However, as soon as the List row is put into edit mode, the value in the field will be displayed as: 12/24/1972 (because this is the actual value that is stored in the List's data).

You probably will want the format of the date when you are editing the List row to be the same as its format when you are not editing the row.

This is achieved by using the onEdit event to format the field when the List row goes into edit mode.

 

Here is the code you would use in the onEdit event to format the data in the DOB field

var d = new Date()

//parse the date value string using the format that it is currently stored in
d.fromFormat(data.dob,'MM/dd/yyyy')

//generate a date string in the required format
data.dob = d.toFormat('dd.MM.yy');

 

Here is the code you would use in the afterEdit event to un-format the data when you save the row:

var d = new Date()
d.fromFormat(data.dob,'dd.MM.yy')
data.dob = d.toFormat('MM/dd/yyyy');

 

 

UX Component - List Control - Virtual Javascript Columns - You can now add a new type of field to a List control. The Virtual Javascript field is a field whose value is computed by executing Javascript code when the List is rendered.

To add a Virtual Javascript field to a List click the Add Item button when the Fields tab in the List Builder has focus. Then select the Virtual Javascript menu item.

 

 

Next, define the Javascript code that must be executed to return the value for the Virtual Javascript field.

 

 

NOTE: A Virtual Javascript field is very similar to defining a Computed Column using the Computed columns property in the List Builder. The primary difference is that when a List row is in edit mode (using in-place editing) the values in Virtual Javascript fields are updated as the List is being edited, whereas the values in computed columns are only update when the List row is saved.


 

 

You can sort Virtual Javascript columns.

 

Components and .a5w Pages - Security Framework - When you save a new component, or .a5w page in a Web Project that has the Security Framework enabled, you will now get a new prompt allowing you select the Component or Page Security for the component.

 

 

UX Component - File Upload to Amazon S3 or Alpha Anywhere Server - Drag and Drop - You can now use drag and drop to select the files you want to upload to Amazon S3 or the Alpha server.

Watch Video

To add drag and drop file upload to a component, add a Drag&DropArea control to your UX component.

 

 

Next, click on the smart field to configure these properties:

 

 

When the UX component is run, the Drag&Drop control will be rendered as shown in the image below:

 

 

You can control various aspects of the appearance and behavior of the Drag&Drop Area. For example:

 

Bugs

Ajax Callbacks - Chunked Responses - Fixed a regression. The final response (i.e. the code that the Xbasic function returned) after all of the chunks had been sent was not getting executed.

Grid Builder - Tree View - Fixed a regression in the Grid Builder. The Tree View for Grid and Detail View fields was not working.

UX Component - Repeating Sections - Fixed a regression in UX components that used Repeating Sections.

Reports - HTML Memo - HTML memo fields occasionally did not render in reports.

UX Component - Pre-rendered - Working Preview - CSS Icons - Were not rendering.

UX Component - Control Bar - Drop-down Menu - Language Tags - Was not processing language tags in the definition of dropdown menus.

UX Component - Fixed a regression when running a UX. Depending on the structure of the UX you might get a run-time error stating that the rtc.args variable was not found.

UX Component Builder - Fixed a regression when saving a UX component that does not have any arguments. An alternative to installing this update is to simply define a dummy argument for the the UX component.

Web Socket Applications - IIS - Security - Fixes an issue with Web Socket applications running under IIS when the security framework is enabled.

 

Alpha Anywhere V4.6.1.5 - Build 6315-5397 10-DEC-2019

Hotfix - UX Component - Fixes an issue when running a pre-rendered UX that does not define any arguments. Also fixes an issue when executing the New Record command in a data bound control. Initial values for controls that did not define a default value were shown as 'Invalid expression'.

Hotfix - SQL Query Builder - Fixes an issue where the SQL Query Builder stripped parentheses in the SQL statement WHERE clause that should not have been stripped out.

 

How to install a hotfix

 

Bugs

UX Component Builder - Fixed a regression when saving a UX component that does not have any arguments. An alternative to installing this update is to simply define a dummy argument for the the UX component.

Web Socket Applications - IIS - Security - Fixes an issue with Web Socket applications running under IIS when the security framework is enabled.

 

Alpha Anywhere V4.6.1.4 - Build 6311-5396 09-DEC-2019

Hotfix - UX Component Builder - Fixes an issue when saving a UX component that does not have any arguments. An alternative to applying the hotfix is to simply define a dummy argument for the the UX component.

 

How to install a hotfix

 

Breaking Changes

UX Component - List Control - <listObject>.editInPlaceAddRow() method - This method has been changed to <listObject>.editInplaceAddRow() (lower case 'P') so that its is named consistently with the other editInplace* methods.

Features

UX Component - List Control - In-place Editing - .editInplaceEditRow() Method - A new method to put a row into edit mode is now available.

Example:

var lObj = {dialog.object}.getControl('list1');

lObj.editInplaceEditRow(0) //edit first row in the List

 

UX Component - Default Value - A change has been made in how default values for the controls in a UX are computed. Previously you could not define expressions that used arguments (e.g. =ut(:arg1) ). Now, expressions that use arguments will work.

 

UX Component - List Control - SQL - Filter Builder Genie - When you define a Filter for a List that is based on a SQL table, a new genie is available to help build the filter. When you click the smart field to open the Filter builder, you can then click the hyperlink to open the Filter Builder Genie.

 

 

This displays the Filter Builder Genie, as shown below:

 

 

Node Modules - You can now install Node modules into the current Web Project folder using the built-in version of NPM.

 

 

 

To open the Node Module Install dialog, select More..., Node, Install a Note module (using NPM) from the Web Control Panel.

 

 

 

UX Component - Form View Control - Tab Control - Conditional Show/Hide Expressions - You can now define show/hide expressions for Tab Controls and Tab Panes in the Form View control.

 

UX Component - Download Manifest Action - on Complete Event - When you use the PhoneGap Manifest action in Action Javascript to download a manifest to a device, the onComplete action now can reference to additional properties in the obj object that is available in your Javascript code:

 

 

PhoneGap - Instant Update - Miscellaneous improvements to the user interface when building Instant Updates.

 

UX Component - List Control - In-place Editing - Security Groups - You can now control whether the Edit Row and Add Row icons appear in each row when in-place editing is turned on based on the current user's security groups.

You can also define Javascript functions that determine if these icons should be shown. If you want to change the display of these icons after the List has been rendered, you must call the List's .refresh() method.

 

Bugs

Git Repositories - UNC Path - Fixes an issue with making a Web Project into a Git Repo if the workspace was opened from a UNC path.

SQL Query Builder -Filter Pane -  Fixes a regression in the Filter tab pane of the SQL Query Builder

UX Component - List with Detail View - Fixed an issue where an error would be generated if you tried to synchronize edits to a record that had been been deleted from the database. Now, the record is removed from the List.

Grid Component - Radio Buttons - Fixed an issue where value in Radio Button controls was not available in the e._currentData variable in an Ajax callback.

UX Component - List Control - Free-form Layout - Formatting Directives - In-place Editing - If you have controls in a free-form layout and these controls used formatting directives in the template, in-place editing did not work.

Grid and UX Component - Advanced Search Control - Date and Time Searches - Pre-defined Ranges - Searches using pre-defined data ranges, such as This Year, were not working correctly.

Security Framework - TabbedUI - Expanding Menus - If you have a TabbedUI configured to use Expanding Menus for the menu bar, or a UX component with an Expanding Menu control, and if some of the items in the Expanding Menu are only visible for certain security groups, a runtime error would occur when Alpha Anywhere tried to render the Expanding Menu.

 

 

Alpha Anywhere V4.6.1.3 - Build 6232-5386 12-NOV-2019

Hotfix - Expanding Menus - UX and TabbedUI Component - Fixes an issue with Expanding Menus. Note: TabbedUI components can be configured to use Expanding Menus.

Hotfix - Grid and UX Component - Advanced Search Control - Date and Time Searches - Pre-defined Ranges - Fixes and issue with searches using pre-defined data ranges, such as 'This Year'.

How to install a hotfix

Videos

UX Component Weather Control The UX Component comes with a pre-build control for displaying weather for a particular city. The weather data comes from Accuweather.com and you are required to get an API key from Accuweather.com in order to use the control.

In this video we demonstrate how you can add a weather control to a UX component.

Watch Video

Date added: 2019-08-09
UX Component - List Control In-place editing By default, a List control is used to display data, not to edit data. It is possible to edit the data in a List using either a List Detail View, or using in-place editing.

In this video we show how you can configure a List to use in-place editing.


Watch Video

Date added: 2019-08-19
UX Component - List Control In-place editing - Dropdown Control In this video we show how a dropdownbox can be defined for in-place editing of data in a List.

Watch Video

Date added: 2019-08-19
UX Component  - List Control In-place editing - Dynamically changing choices in a dropdownbox at runtime. In this video we show how the choices in a dropdown box used for in-place editing can have the choices shown in the dropdown box dynamically changed at run-time.


Watch Video

Date added: 2019-08-19
UX Component  - List Control In-place editing - Putting all rows into edit mode. A common pattern when using Lists that allow in-place editing is to configure the List so that all rows in the List are in edit mode (rather than requiring the user to put individual rows into edit mode before making edits).

In this video we show how you can execute Javascript to put all of the rows in the List into edit mode.


Watch Video

Date added: 2019-08-19
UX Component  - List Control In-place editing - Free-form Layouts In place-editing in a List control can also be used in free-form List Layouts.

In this video we show a List that has a free-form layout and how in-place editing can be used.

Watch Video

Date added: 2019-08-19
UX Component - List Control Using in-place editing to edit data in a List based on a SQL table To edit data in a List that is based on a SQL database, the List/Detail View pattern is typically used. However, it is also possible to use in-place editing in a List and then persist the edits made to the List back to the SQL database.

In this video we show how a List that is based on a SQL database is configured to allow edits to the SQL database to be made using in-place editing in the List.

Watch Video

Date added: 2019-08-19
UX Component - List Control Data validation for in-place editing When you use in-place editing to edit data in List row you can use Javascript code to validate the edited data before it is saved.

In this video we show how a validation rule is added to check that the user enters a value into the City field.

Watch Video

Date added: 2019-08-19
UX Component - List Control In-place editing - Auto-suggest You can define an auto-suggest control for in-place editing. You can also dynamically filter the choices in the auto-suggest based on other data entered into the List row being edited.

In this video we show how an auto-suggest control that shows choices from a SQL database is defined. We then add a dynamic filter to the auto-suggest so that it only shows choices that are filtered by some previously entered data in the List row.


Watch Video

Date added: 2019-08-19
UX Component - List Control In-place editing - Displaying images in a pick-list for Edit-combo or Auto-suggest When you define the data to be shown in the pick-list for an edit-combo or auto-suggest control, you can include images. In this video we show how the pick-list for an edit-combo is configured to display images

Watch Video

Date added: 2019-09-09
UX Component - List Control In-place editing - Displaying multiple columns in a pick-list for Edit-combo or Auto-suggest When you define the data to be shown in the pick-list for an edit-combo or auto-suggest control, you can specify that multiple columns of data should be shown in the pick-list. You can also specify that when the user makes a selection from the pick-list that other fields in the List row you are editing should be filled in. In this video we show how this is done.

Watch Video

Date added: 2019-09-09
UX Component - List Control In-place editing - Enable/Disable controls When you are editing the data in a List row using in-place editing, you may want to dynamically enable/disable controls in the row.

In this video we show how you can define an enable event to dynamically disable controls in the List row you are editing.

Watch Video

Date added: 2019-09-09
UX Component - List Control Decode coded Values It is common when designing databases to use coded values for certain fields (i.e. a category field might have values of 1, 2, 3, etc. rather than Beverages, Condiments, Confectionary, etc.). When displaying the data in the List you might like to display the decoded value for each coded value. In this video we show how this is easily done.

Watch Video

Date added: 2019-10-05
UX Component - ControlBar Control Dropdown Menu A common pattern when designing a ControlBar is to include buttons on the ControlBar that display dropdown menus. These can either be cascading or expanding menus. In this video we show how you can add a dropdown menu to a ControlBar.

Watch Video

Date added: 2019-11-05
     

 

 

 

Changes

twilio_send_sms() function - Now returns .f. if Twilio reports an error. Previously, this function only returned false if there was an error making the call to the Twilio endpoint.

UX Component - Live Preview and Working Preview - If you open a component (from (say) Web Project 'Project1') in the UX Builder then then you subsequently change the Web Control Panel to a different Web Project (say 'Project2'), without first closing the previously opened component, when you go to preview the component you will now get a warning saying that the current web project is different than the project in which the component was defined. The reason for displaying the warning is that the component will not run correctly if it loads any resources from the web project folder.

 

Web Security - The Web Security options dialog has been changed to a menu. This is purely cosmetic. There is no change in functionality.

 

 

UX Builder - Show line number in Controls list Property - This property has been removed from the Advanced section in the UX Builder properties page because line numbers can now be toggled by clicking on a button in the Controls toolbar

 

Features

 

UX Component - List Control - In-place Editing - The List control now supports in-place editing of data. Previously, the only way to edit data in a List control was using the List Detail View. In-place editing can be used in conjunction with the List Detail View.

NOTE If you want to use in-place editing to edit data in a SQL database, you must turn on the List Detail View. See the section below: Updating Data in a List Bound to a SQL Database

The image below shows a List with in-place editing enabled. Notice the icons in the first column of the List. These icons allow the user to edit a row or to add a new row to the List. You can also configure the List to support double-click to edit a List row. Once a row is in edit mode, a second double-click on the row will save the edit and return to view mode.

 

To turn on in-place editing for List, check the Allow in-place editing property in the List Builder on the List Properties pane.

 

 

The image below shows a List control with the first row in List in edit mode.

 

You can configure the List to only allow one row at a time to be in edit mode, or you can allow multiple rows at a time to be in edit mode, as shown in the image below:

 

 

You can put a row into edit mode by clicking the Edit icon in the row.

You can add a new row of data to the List by clicking the New Record icon

The image below shows the List after the New Record icon has been clicked. Notice that an empty new row appears in the List immediately after the row in which the icon was clicked. The fields in the new row can have default values that are computed using Javascript.

 

 

You can save the new row by clicking the Save icon (the checkmark icon), or you can abandon the new row by clicking the Cancel icon (the X icon).

 

 

You can add the in-place edit icons to a List row by selecting the <In-placeEditingIcons> item from the list of Available Fields.

 

 

By default, you can also put a List row into edit mode by double clicking on the row. Once the row is in edit mode, a second double click will save the edits and return the List row to its 'non-editable' state.

If you use the double click method to put a List row into edit mode, then it is not required to add the <In-placeEditingIcons> to your List layout. However, without these icons, you will not be able to add a new row to the List unless you use some Javascript code.

Here is the Javascript code to add a new row to a List and to cancel the new Row:

 

var lObj = DLG1_DlgObj.getControl('list1')

//add a new row below row 1 (zero based)
lObj.editInPlaceAddRow(1);

//cancel the new row (zero based)
lObj.editInPlaceCancel(2);

 

 

You can configure whether double-click can be used to put a List row into edit mode and other List in-place editing settings by clicking the smart field for the In-place editing settings property.

 

 

When you click the smart field, the following dialog will open:

 

This dialog allows you to specify:

The Javascript events fire before a List row goes into editing mode, when the edits in a row are saved, when a new row is added to the List, or when edits are cancelled. All of these events allow you to cancel the event by returning a false value.

NOTE: The Before add new row event could be used to set default values for fields in a new row, and the On edit save event could be used to define data validation, but, as described later, you can use define Default value and Validation code for each field in the List.

 

Defining In-place Editing Properties at the Field Level

Once you have turned on in-place editing for a List you can define in-place editing properties for each field in the List. To define in-place editing settings for individual fields, go to the Fields pane in the List builder.

 

 

 

 

For each field you can specify:

 

For example, the the image below, the City field has a validation rule that has been violated:

 

The validation rule for the City field was defined as:

 

if(newData.City == '') {
    return 'This is a required field.\nPlease enter a non-blank value.';
} else {
    return '';
}

 

 

Control Settings

Click the Control Settings smart field to open the In-place Edit Control Properties dialog (as shown below).

This dialog allows you to select the control type to be used for in-place editing and to set properties for each control type.

 

 

 

All of the available control types have a With property which defines the width of the control when it is placed in a free-form List layout.

 

 

Each different control type exposes a different set of properties. Some of the control types (dropdown, edit-combo, auto-suggest) allow the user to pick a value from a list of choices. See Control Choices below for more details.

The Textarea control exposes these properties:

 

 

Control Choices

The Dropdown, Edit-combo and Auto-suggest control all display a pick list of choices for the user to select from.

This pick list can be based on:

 

You can define a filter for the choices. For example, you might only want the choices in a Dropdown to show cities in the USA.

For the Edit-combo and Auto-suggest you can also define a dynamic filter. A dynamic filter is a filter that is based on data that has been entered in other fields in the List row being edited.

For example, say you have defined an Edit-combo control to edit the City field. Say that the List also has a Country field. When you are editing a List row and you click the down arrow to display the list of choices for the City field you might only want to display Cities for the Country entered into the Country field.

 

Free-form Layout

You can use in-place editing in both Column List layouts and in Free-form layouts. In a free-form Layout you can specify the width of each control when the row is in edit mode.

 

Updating Data in a List Bound to a SQL Database

It is common to build List controls that are populated with data from a SQL database. You can easily use the List to make edits to the data in the SQL database by defining a Detail View for the List.

You might want to make these edits using in-place editing, rather than by entering edits into the List's Detail View.

Even though you intend to make edits using in-placed editing, you should still turn on the List's Detail View. However, you need not actually define any Detail View controls.

When you edit the data in a List row, an orange icon will appear in the edited List row to indicate the the List row has been edited, but not yet synchronized.

When you are ready to synchronize your edits you can click the Synchronize button (just as you would have had the edits been made in a standard List with Detail View).

 

Watch Video

 

 

How to Dynamically Change the Choices in a Dropdown Control Used for In-place Editing

The choices in a dropdown control can be dynamically changed at run-time using Javascript.

For example, in the code below, the choices for the Country field dropdown box are changed to 'alpha', 'beta', 'gamma'. In the case of 'gamma', a stored value of 'g' is defined.

var lObj = {dialog.object}.getControl('list1');
lObj._inplaceEditing.choices.Country = ['','alpha','beta',['gamma','g']];

 

Editing All Rows At Once

When a List is initially rendered, you might want all of the rows in the List be in edit mode (so that the user does not have to manually put a row into edit mode before making edits).

The following Javascript methods of the List can be used:

 

.editInplaceEditAll() - puts all rows into edit mode

.editInplaceSaveAll() - saved all rows with edits

.editInplaceCancelAll() - cancels edits in all rows that are in edit mode.

 

For example:

var lObj = {dialog.object}.getControl('list1');
lObj.editInplaceEditAll();

 

Styling Edit-combo and Auto-suggest Pick Lists

You can define several properties to control the styling of the pick-lists displayed for edit-combo and auto-suggest controls..

 

 

You can control the height of the pick-list window that is displayed for edit-combo and auto-suggest controls. You can use the special listHeight value to specify a value relative to the List height. For example: listHeight * .3

 

 

 

 

 

Conditionally Controlling with Controls Allow In-place Editing

You can define a Javascript function to determine if a particular field in the list should be editable when the List row is put into edit mode. You can also specify security groups to control whether a particular field is editable.

By default all of the fields that have their Allow edit property checked become editable when the row is put into edit mode. However, if you specify a Javascript function that returns false, then when the List row is put into edit mode, the field will not be editable.

You can specify global windows functions, functions defined in the scope of the UX component (e.g. {dialog.object}._functions.somefunctionname), or functions defined in the scope of the List control (e.g. [scope].somefunctioname);

 

 

 

 

To define the Security Groups for a field, set the Security Groups property in the Fields pane in the List Builder. See image above.

Controlling the Pick-List Window Size for Edit-combo and Auto-suggest Controls

You can set the width and maximum height of the pick-list window for edit-combo and auto-suggest controls. The default window width is the width of the control.

 

 

 

Calculated Fields

When you are editing the data in a List row, you can specify that the value in a particular field should be computed from other data in the List row. Your JavaScript code that computes the calculated value can reference the current (i.e. edited data) in the List row, the original data in the List row, or data from other rows in the List.

To define a calculated field, specify code in the control's calculated event.

For example, if the List has these columns: price, quantity and total, you might specify this code for the calculated event for the total field:

return Number(newData.price) * Number(newData.quantity)

 

Notice that the Number() function is used to ensure that the value for price (newData.price) is a numeric value.

The value for price is prefixed with newData (as opposed to oldData) to indicate that you want to use the current (edited) value that the user has typed into the price field. oldData.price refers to the value before the user made any edits.

 

 

Dynamically Enabling In-place Editing Controls

You can dynamically enable/disable controls in the List row you are editing.

 

See video

 

To enable or disable a control while you are editing a List row, define an enable event. Your event can reference data in the row you are editing and also the original data (before edits were made). If your code returns false, the control is disabled. Otherwise the control is enabled.

When radiobutton and checkbox controls are disabled an opaque overlay is shown over the control to give a visual clue that all of the controls in the control group have been disabled.

 

 

In-place Edit - CheckBox and RadioButton Controls

You can specify that the data in a List column should be edited using either a CheckBox or RadioButton control. When you define the choices for these control types you can define a static list of choices. Each choice can define an optional stored value in addition to a displayed value. The individual radiobutton or checkbox controls can be rendered using a horizontal, vertical or snaking layout (multiple columns that snake from left to right, top to bottom within the defined width of the List column).

In the image below, the RadioButton control has been defined to use a vertical layout.

 

 

 

Auto-suggest and Edit-Combo - Multi-column Pick List and Fill in Fields

When defining auto-suggest and edit-combo controls for in-place editing in a List you can specify that the Pick List that is displayed should have multiple columns. You can also specify that when a selection is made from the Pick List other fields in the List row you are editing should be filled in with values from the Pick List (the source fields for the fill in definition do not have to be displayed in the Pick List).

 

Watch Video

 

In the image below, the City field is defined as an edit-combo control and the Pick List shows two columns - City and Country. You can specify the column headings and the column widths. (See below).

 

 

To specify that the Pick List for an edit-combo or auto-suggest control has multiple columns, select the columns to display by setting the Fields to display property.

 

 

 

If you are displaying more than one field in the Pick List you can customize the template used to display the Pick List. Click the smart field for the Template property.

You can control the order in which the columns are displayed (by clicking on the Up and Down buttons) and you can set these properties:

 

 

 

When the user makes a selection from a Pick List you can fill in other fields in the List row you are editing. To define which fields should be filled in, click the smart field for the Fillin fields property.

 

 

 

Displaying Images in a Pick List

The image below shows a Pick List with two columns. The data in the second column is displayed as an image (this is done by setting the Column type to Image in the Template).

In the first row a built-in SVG image is displayed. In the second row an image referenced by a URL is shown and in the third row a built-in image is shown.

 

Watch Video

 

 

 

Events

You can now define the following events for in-place editing controls

 

NOTE: Not all input-editing control types support the full list of events.

 

 

Placeholder Text

You can define placeholder text to be displayed in the input controls used for in-place editing.

In the image below, placeholder text is displayed in the input controls for Lastname and City in the new row

 

 

To define placeholder text for a field, set the Placeholder text property in the In-place Edit Control Properties dialog.

 

 

PhoneGap - iOS - Alpha WkWebViewPlugin - iOS Quick Look - The Alpha WkWebView Plugin now supports the ability to view and edit a directory of local on device files using a native iOS Quick Look Preview Controller. The list of files in the local directory are presented in a native iOS control that includes a tableview list of the files. When a row is tapped, the Quick Look Preview Controller will open and display the respective document, media or image file.

The Quick Look Framework is used by many native iOS apps (Mail, Notes, etc.). It can open specific types of documents fo previewing. These include iWork documents (Pages, Numbers, Keynote), Microsoft Office documents, PDF files, Images, Text files, Rich-Text Format documents, CSV files, Video files, Audio files and USDZ files for viewing AR content. If the app is compiled with Xcode 11 and the device is running iOS 13 or greater, movies, PDF's and images may be edited. If the file is edited and saved the current local file is overwritten. The edited file can be easily shared.

One of the easiest ways to download all of the files you may need display to the device is through the use of a manifest. A manifest can be easily built in Alpha Anywhere (See Web Projects Control Panel | Tools | More... | On-device-data builder for PhoneGap applications). Once the manifest is created, you can load a manifest and it's associated files programatically. The device needs to be online to load the manifest and download the files however, once the files are loaded into the local file system, all of the files will be available for offline display.

The Alpha WkWebView plugin defines a custom protocol handler to expose the functionality of the iOS Quick Look Preview Controller. To view a directory of files, the source of an HTML image tag can be used to point to the local directory. Since the alpha-local:// custom protocol is used in the URL, it will be recognized and handled by the Alpha WkWebView plugin. The HTML image tag is simply a placeholder and it's source url is handled by the alpha-local:// protocol. It does not need to be visible.

To display a directory of files that may include any of the Quick Look supported formats, add the prefix:

alpha-local://viewdir?url=file:///pathToLocalFile/local/directory



Here's an example to the localFiles/project1 directory from a test app:


alpha-local://viewdir?url=file:///var/mobile/Containers/Data/Application/1920522B-3AA6-4BAE-8007-5B4E8AEACC14/Library/NoCloud//localFiles/project1/


For additional information see the plugin readme file: Cordova-plugin-alpha-wkebview-engine

We will be providing further documentation, videos and a sample application that uses numerous manifests and the Quick Look Preview Controller soon.

NOTE: Editing requires the PhoneGap App to be built with Xcode 11(not currently supported by PhoneGap Build) and the iOS device must be running iOS 13 or greater. Because Xcode 11 is not currently supported by PhoneGap you must build your PhoneGap app using the CLI on a Mac.

 

 


List of files in directory

Viewing an Excel spreadsheet

Viewing and Sharing a PDF File

Editing a PDF Docucment

   

   

 

UX Component - Control Bar - Dropdown Menu - You can now easily add dropdown menus to a ControlBar. The menus can either be cascading or expanding.

 

Watch Video

 

The image below shows an expanding menu.

 

The image below shows a cascading menu:

 

To add a dropdown menu to a ControlBar, open the ControlBar Builder, go to the Items tab and click the Add ControlBar Item menu button.

 

 

 

Then select the button-dropdownMenu item type.

 

 

To configure the dropdown menu choices, click the smart field for the Menu definition property.

 

 

 

This will open the menu builder.

 

 

 

The properties that you can set in the menu builder include:

 

 

 

UX and Grid Component - File upload to s3 - Parentheses in S3 Object Name - There is a bug in the Amazon's S3 method for signing URLs to upload files to S3. As a result of this issue, you cannot upload a file and assign an object name with ( ) in the name. Therefore, object names with ( ) are automatically converted to [ ].

Web Application - Searching Web Projects - Search in the files in a web project for s specific string has been optimized. The performance gain will only be noticeable in extremely large projects.

UX Component - List Controls - Server Side Xbasic - List Information - When server-side Xbasic is executed (for example, in an Ajax callback, afterDialogValidate event, etc), a new property is now available in the e object that is passed to the server side code.

The e.listInfoJSON property has information about each of the Lists controls on the UX component.

For example (assuming the component had two lists, LIST1 and LIST2 and each of these lists had the checkbox column enabled):

 

e.listInfoJSON = "[{'list': 'LIST1','checkedRows': [0,1]},{'list': 'LIST2','checkedRows': [2,3]}]"


 

Tabbed UI - Server-side OnLogout Event - Redirect - You can now redirect to another page when a user logs out of a TabbedUI component that has integrated login enabled.

 

In the server side onLogout event, add this code:

e.rtc.redirectURL = "re-direct url"

for example

e.rtc.redirectURL = "http://www.google.com"
 

Web Applications - Encrypting Published Files - When you publish a web application you can now specify that certain of the file types should be encrypted. This allows developers who deploy application at on-site client locations to protect their work. Not all file types are encrypted. Specifically, Grid components, Javascript files, .a5w pages and static resources (such as images) are also not encrypted. UX Components, TabbedUI and PageBuilder components are encrypted. Xbasic function libraries and modules are also encrypted.

 

To enable encryption, open the Project Properties dialog and select the Design-time Properties tab. Then check the Encrypt published components property.

 

 

Xbasic - pdf_fillinFields_merge() Function - You can now specify a URL for a remote PDF file and you can now also specify that the resulting PDF file should be uploaded to an Amazon S3 bucket.

Syntax

L flagResult=pdf_fillinFields_merge(C pdfFileIn,C  pdfFileOut, c  jsonData [, c storageConnectionString [,C s3objectname]])

 

Where:

 

 

Xbasic - email_send_SendGrid() Function - You can now send email using the SendGrid service. The parameters for this function are identical to the email_send_SparkPost() function.

You can use the email_send_SparkPost() function to send email using the SendGrid service by prefixing your api key with sendgrid: For example:

 

dim key as c = "sendgrid:12345676878990"

dim ms as p

ms.send_to = "fred@acme.com"
ms.reply_to = "fred@acme.com"
ms.from_email = "fred@acme.com"
ms.from_name = "Sales" 'friendly name - optional
ms.subject = "Information You Requested"
ms.message_html = "Here is the <b>information</b> you requested."
ms.message_text = "Plain text version of the message"
pp = email_send_sparkpost(key,ms)

 

TransForm API Tester - Beta - You can now test TransForm API endpoints against the TransForm Beta site.

 

 

UX Component - List Control - Decode Values - You can now specify that a field in a List is a coded value and that it should be decoded before it is displayed in the List. For example, you may have a field in the List called categoryId. This field may have values like 1, 2, 3, etc. When the List is rendered, you would like to display the decoded value for each of these values (e.g. Beverages, Food, Condiments, etc.).


Watch Video

 

In order to specify that a List field should be decoded, check the Decode value property on the Fields tab in the List Builder.

 

 

Once you check this property, a new property ( Decode lookup list ) is shown. This allows you to define the list of values (the decode list)  that will be used to decode the value when the List is rendered.

 

 

 

The decode list can be based on static or dynamic values or a Javascript function. If the decode list is based on dynamic values,  you can specify a database query, or a custom Xbasic function to get the values for the decode list.

The decode list is a CRLF delimited list of values of the form codedValue|displayValue

For example

1|Beverages

2|Condiments

3|Confections

 

If a value cannot be decoded, the coded value is displayed.

When the List data are refreshed, the decode list is also refreshed (assuming that the decode list was defined to be dynamic).

The decode list is stored as a property of the  List Object. For example, for a field called category, the decode list for this field would be stored in:

 

<listObject}.lookupvalue.category

Where <listObject> is a pointer to the List Object.

For example

var lObj = {dialog.object}.getControl('list1')

lObj.lookupvalue['category'] = [

    {value: '1', html: 'Beverages'},

    {value: '2', html: '<b>Condiments</b>'},

]

 

Notice that the html property can be any HTML markup that you want.

After you modify a field's lookupvalue property you must refresh the List using the <listObject>.refresh() method.

 

Sorting Columns with Coded Value

When you do a client-side sort on a column that has a coded value, the resolved values (as opposed to the raw values) are sorted.

 

Contrast the Decode value feature with the Lookup Columns feature

The Lookup Columns feature is similar to the Decode value feature in that both allow you to display a decoded value for a coded value in the List. The Decode value feature is probably easier to use as you can define the decode list as part of your List definition and it does not add additional columns to the List as the Lookup Columns feature does.

 

Resolving Coded Values Programmatically

You can resolve a coded value using this method of the List:

<listObject>.resolveCodedValue(fieldName,fieldValue)

 

Web Applications - Security Framework - Using Security Tables from a Different Project - When you enable the Security Framework for a Web Application you can specify if the security data (users, roles, etc.) should be stored in .dbf tables or in a SQL database. If you have previously used a SQL database for the security tables in another web project, you can now re-use those same tables.

When you are configuring the Security Framework for a Web Project, the Security Table Type property now has a new option. When you click the smart field for Security Table Type the dialog that is shown has a new option: Use 'SQL Database' from a Different Project.

 

 

 

UX Component - List Control Export to Excel - You can now customize field sizes and column headings when exporting the data in a List to Excel (using the List query as the data source). Previously, this option was only available if you used the data in the List as the data source.

IIS Server - A5W Page Caching - A5W page caching is only available running under IIS (which includes Alpha Cloud) and takes advantage of IIS kernel and user mode (web application) output caching. It allows the output (response) of an a5w page to be computed once and then cached making subsequent requests extremely fast since the response does not need to be recomputed.

Most a5w pages are dynamic by nature and won't benefit from caching since the response needs to be recomputed each time to reflect the current state of the data. However, some a5w page are the equivalent to being static or may only need accurate data for certain time spans. For instance, a stand alone login.a5w page will usually just have prompts and buttons and is the same for every user. This page can be safely cached after the first time it is computed. Another page may do a complex calculation that only needs to be updated every 30 seconds. The page caching can be set to keep the response in the cache for 30 seconds. After 30 seconds elapses the next request for that page will rerun the page and then cache that result for 30 seconds.

Cache options for a page
The cache settings for a page can be reached by right clicking on the page in the Web Project Control Panel and then selecting Cache settings....


A dialog for selecting the settings will then be displayed:



NOTE: If a page or components on a page contains language tags and the language selection is based on the <culture> of the request the Page contains language tags option will need to be selected. This is needed so that different versions of the page will be cached for each language in use.

 

NOTE: A5W pages cannot be cached on POST requests

 

 

Xbasic - DECLARE, DECLARESTRUCT, UNDECLARE Commands are Deprecated - If you use these commands in an Xbasic script you will now received a warning.

 

UX Component - List Control - KanBan Layout - onBeforeMove Event - A new event is now available. The onBeforeMove event fires when the users tries to move an item from on category to another. If the event returns false, the move is cancelled.

 

 

UX Component - List Control - KanBan Layout - onMove Event - The variables that are available to your code when the onMove event fires have changed. The variables that are available are now:

 

 

 

SQL Query Builder - Format SQL - When you build a SQL statement using the SQL Query Builder, the SQL statement is formatted to help improve readability. However, in some cases it might be preferable to show the unformatted SQL statement. The builder now has a new option to turn SQL formatting off.

 

 

 

 

UX Components - Action Javascript - Menu - In-line Style and Class - You can now set the in-line style and class name for the menu shown by the Dropdown Menu action.

Here is how the menu renders when the in-line style sets the background color to pink:

 

 

Grid and UX Component - Advanced Search Control - Default Search Operator - You can now define a default search operator for the textbox control. Previously the default search operator was set to Equals.

 

 

 

UX Component - List Control - WHERE and ORDER BY Clause Arguments - You can now make a List component more versatile by defining the SQL statement using a special type of argument.

Normally, arguments are used to supply values in a where clause. For example:

Select * from customers where city = :whatcity

 

The List now supports a special type of argument that can supply the entire Where clause. For example:

Select * from customers :whereclause

 

The argument value for the Whereclause argument could be defined as:

where country  = :whatcountry

 

TIP You can also define the ORDER BY clause using an argument. For example:

select * from customers :whereclause :orderbyclause

 

IMPORTANT: The argument value for an argument that supplies a WHERE clause must start with WHERE. The argument value for an argument that supplies the ORDER BY clause must start with ORDER BY. To specify that there is no WHERE clause, set the argument value to WHERE none. To specify that there is no ORDER BY clause, set the argument value to ORDER BY none.

 

A use case for this feature could be a TabbedUI where you have buttons that show a UX component with a List.

The same component could be used for (say) 2 different buttons in the TabbedUI

In the first case the TabbedUI would define these argument bindings

In the second case, the TabbedUI would define these argument bindings

 

Classic Application Server - Reduced Memory when Serving Static Files - The Classic Application Server has been enhanced to serve static resources from disk more efficiently. File content is now streamed directly from disk to the client for maximum performance with minimal memory utilization. This can lead to a noticeably reduced server memory footprint on a busy server.

Classic Application Server - Caching of Gzipped Output - The Classic Application Server now automatically caches gzipped output when the request is a static file, such as a style sheet, plain HTML, or image file on disk. Gzip allows the response to be transferred to the client more quickly so generally improves application performance. However it can be CPU intensive on the server to perform the Gzip compression which may limit the perceived performance improvement. The addition of this change restricts any negative impact on performance to only the first request for a resource.
 

 

PhoneGap App Builder Genie - Android Only -  Added Option To Allow Clear Text HTTP Traffic - By default, apps built for Android using cli-9.0.0 with a target SDK API version of 28 (which is required to publish the app to the Google Play Store) will not allow clear text HTTP traffic. The PhoneGap Builder now automatically adds the required entries to the PhoneGap project config.xml file to allow clear text http traffic if the URL specified for Ajax callbacks uses the http:// protocol.

If the Ajax callback URL uses the https:// protocol, and you are using cli-9.0.0 and targeting Android SDK API version 28, you will see an option to Allow Clear Text HTTP Traffic. If you enable this option, the entries required to allow clear text http traffic will be added to the PhoneGap project config.xml file. This allows you to use use the http:// protocol in XHR requests to any web service that may be using the http:// protocol.

 

UX and Grid Component - Lookup Grid - Right-to-Left Layout - When defining a Lookup Grid you can now specify that the Grid should be rendered right-to-left. This is done by adding a directive (<direction:rtl> ) as a prefix to the Window title property.

 

 

 

Reports - Printing QR Codes - To print a QR code on a free-form report, you must create a calculated field using the printQRCode() function. Previously, it was not possible to set properties for the bitmap size on the report and as a result, the QR Code bitmap was printed very small. Now you can set bitmap properties by right clicking on the object on the report and selecting the Best Fit option for the Display mode.

 

 

UX Component - List - SQL Database Source - Record Count - When a List control is based on a SQL data source, by default, the SQL query for the List data is executed two times. The first time is to get a count of the number or records in the List query and the second time is to get the actual List data. In some cases it may be undesirable to execute the SQL twice (for example, the query may actually modify the data using a trigger, or the query may be very expensive).

You can now instruct the List to not perform the initial query to count the records.

NOTE: In most cases turning off the count query will not be problematical. The main reason for the need to know the count of the records in the List is when the List is paginated and the pagination method is set to Navigation Buttons. If you don't have a count of the records in the List, it is not possible to compute the number of pages of data. In this case, AA uses a large number as a estimate of the number of pages of data.

 

 

 

 

UX Component - Data Bound UX Component - Server-side Save Data Action - A refresh query after CRUD action has been performed is no longer executed if the After Submit action is not set to Edit Record Just Submitted. Depending on the speed of your database, this will result in a noticeable performance improvement.

 

UX Component - List Control - Refresh List Action -Ajax Failed - The Refresh List action now allows you to specify Javascript to call if the Ajax callback fails, or if the device is offline.

 

 

UX Component - Weather Control - The UX now has a new control type to display weather in a specified city.

 

Watch Video

 

Here is an example of how the weather control looks.

 

To add a Weather control to a UX, select the [More...] item in the Data Controls section of the UX toolbox. Then open the genie to configure the control. You will need to specify an API key, which you can get from Accuweather.com.

 

 

Xbasic - a5_accuweather_forecast() Function - Gets current weather conditions and a forecast for a particular city from AccuWeather. Requires an API key from AccuWeather. The result is returned as a JSON string.

c resultJSON = a5_accuweather_forecast as c (C apikey,C city )

 

UX Component - ViewBox Control - Local SVG - You can now define local SVG for a ViewBox. Previously, the local SVG had to be defined at the Component level, which meant that the ViewBox definition was not completely stand-alone.

 

 

UX Component - List and ViewBox Control - Custom Datasource - When you specify that the control has a Custom datasource, you can now define the Xbasic functions as part of the control rather than in the Xbasic Function Declarations section. By defining the Xbasic as part of the control, the control becomes 'self-contained' as is then easier to copy to other components.

 

 

 

UX Component - List Control - onChange Event - A new event has been added to the List control. The onChange event fires whenever the List's value changes.

The List value is defined by the Return Value property in the List Builder. For example, assume that the Return Value is set to the Lastname field. If the user clicks on a row in the List that has a Lastname value of "Smith", the List value is "Smith". This is also the value that would be returned by the .getValue() method for the List.

 

UX Component - PhoneGap - PhoneGap cli-9.0.0 - Added support for the latest PhoneGap cli version.

The following articles may be of interest :

https://blog.phonegap.com/cli-9-0-0-support-has-been-added-to-phonegap-build-da92fff6d588

https://developer.android.com/distribute/best-practices/develop/target-sdk?source=post_page
 

UX Component - List Control - Detail View - beforeCRUDExecute Event - Display Sync Progress -  The beforeCRUDEvent executes when a List with a Detail View is synchronized. The event fires before each CRUD operation is executed. Two additional parameters are now passed to the event: total and number. total is the count of the number of CRUD operations to be executed. number is the number of the CRUD operation about to be executed.

For example, assume you have a UX with two Lists, customers and orders. Assume that there is a parent-child relationship between the two lists and that the data are pre-fetched (so the UX will work offline). Now assume that the user edits two orders for the first customer and three orders for the second customer.  In total, there will be five CRUD operations needed to synchronize the data. The beforeCRUDExecute event will fire five times. The total parameter will be 5 each time the event fires, but the number parameter will cycle from 1 to 5, allowing you to display a progress bar while the data are being synchronized on the server.

 

UX Component - Bulk Operation - Starting with Build 5982, an internal change was made to the internal stored format for UX Components. While no change is needed on your part to run UX components build before 5982 with build 5982 or higher, you can optimize performance of these older UX components by editing them and resaving then with build 5982 or higher. When you resave the component, the internal stored format is updated to the newer format. You can also do this conversion using a Bulk Operation by selecting Edit, Bulk Operation, Update UX Components to V4.6.1. format.

It is recommended (but it is NOT required) that you perform this bulk operation and then republish your site.

 

NOTE: You will still be able to edit your UX components with older versions of the UX Builder after you run this conversion.

 

 

UX Component - Added optimization for the window resize event to not fire the event too often.

Bugs

Application Server - Classic Server - Vulnerability - A vulnerability was found in the Classic Application Server which could allow an attacker to execute a CRLF injection attack in an attempt to execute HTTP Response Splitting. This has now been resolved and the server no longer has the vulnerability.

The Application Server for IIS was not impacted by this vulnerability.

More information on HTTP Response Splitting is available at https://www.owasp.org/index.php/HTTP_Response_Splitting

 

UX component - List and ViewBox Control - AllowTextSelection - If this property was turned on, the user was still not able to select text.

UX Component - Tab Control - Method for Selecting Active Tab - If the method was set to 'Automatic', 'Timer', or 'Programmatic' the Tab Band was not hidden as it should have been.

UX Component - Generate PDF From Container - Absolute Container -  Background Image - If an Absolute Container had a background image, the image did not render when the Container was rendered as a PDF.

Application Server - Memory Leak - Fixed a memory lead the property_recurse_assign() function. Since this function is used in both the UX and Grid components, web applications that used these components could see server memory increasing over time.

UX Component - Radio Buttons - Render as Button List - Get Value - The .getValue() method was not working when the radio button control was rendered as a button list.

AlphaDAO - Postgres - Timestamp Fields - Fixed an issue with timestamp fields which were being recognized as Date fields rather than Datetime fields.

printQRCode Function - Size Parameter - The size parameter in the function was not being honored if you had not set the flagUseGoogle parameter to .t.. When the flagUseGoogle parameter is set to .t., printing QR codes can be quite slow because each QR code is rendered by making an API call to Google. The default value for this parameter is .f., which makes printing QR codes very fast, as an internal library is used to generate the QR codes.

UX Component - TextBox and TextArea - Sub-themes - Sub-themes were not being honored.

UX Component - Repeating Section - Data Bound - Transactions - Fixed an issue when doing data entry of a new record in a data bound UX component with Repeating Sections. If the Server-side action to save edits had the Use Transactions flag turned on, a error would be reported when the user tried to enter a new record into the Repeating Section.

UX Component - Maps - Action Javascript - Add multiple markers to the map - Client-side Data - Fixed multiple issues when properties such as 'Overlay' were bound to client-side data.

HTML Editor - A5W Pages - Live Preview Pane - If you switched to the Live Preview pane in the HTML editor, the a5_application.a5i file was not created as it should have been.

Application Server - Security Framework - Fixed a regression introduced in a recent pre-release build. The regression prevented a user from logging in to the security framework.

UX Component - Signature Capture Control - Fixed a regression adding the Signature Capture control to a UX component.

UX Component - Component Builder - Fixed a regression that occurred when a text string in any label in the component contained the // characters.

UX Component - Tab Controls - Fixed a regression for UX components with deeply nested Tab Controls (i.e. Tab Controls within Tab Controls)

UX Component - Client-side Show/Hide Expressions - Fixed an issue that would result in a control that should have been hidden being shown. The issue would arise under the following condition: The control has both a server-side show/hide expression or server side security setting, and also a client-side show/hide expression and the component was pre-rendered (and server-side security was set to be applied client-side)

Application Server For IIS - Fixed an issue where server was trying to access a file in the c:\bugs folder.

UX Component - Ajax Callbacks - Chunked Responses - Fixed an issue that occurred when the chunked response was very large.

 

Alpha Anywhere V4.6.1.2 - Build 6012-5338 02-AUG-2019

 

 

Hotfix - SQL Query Builder - Fixes an issue with tables that have columns with spaces or special characters in the column name.

 

How to install a hotfix

 

 

Features

UX Component - Added optimization for the window resize event to not fire the event too often.

Bugs

Application Server For IIS - Fixed a regression (introduced in build 6010) where server was trying to access a file in the c:\bugs folder.

UX Component - Ajax Callbacks - Chunked Responses - Fixed an issue that occurred when the chunked response was very large.

 

 

Alpha Anywhere V4.6.1.2 - Build 6010-5337 01-AUG-2019

 

Hotfix - Various Fixes - UX Builder - Adding multiple textbox controls at once with the Label Position set to 'Watermark'. IIS - Running UX Components that were build using an older build and not yet edited in the current build.

 

How to install a hotfix

 

 

 

Videos

Xbasic Debugging Server-side Javascript You can run Javascript code from Xbasic using the xbasic_execute_javascript() function. You can also debug into the Javascript code while it is executing as shown in this video.

Watch Video
Date added: 2019-07-26
UX Component Step Indicator Control - Repopulating and setting Direction The Step Indicator control is a convenient way for showing progress through a task. In this video we show how the list of steps can be dynamically changed at run-time and how the direction of the steps can be changed to support right-to-left languages such as Hebrew and Arabic.

Watch Video
Download Component

Date added: 2019-07-30

 

 

Features

 

Excel Files - Extension - When Alpha Anywhere generates Excel files it typically uses the .xls extension. You can now force AA to use the .xlsx extension by setting a property in Web Project Properties.

 

 

TabbedUI Component - Expanding Menu - Close Expanding Menu On Item Select, Close Sibling Branches When A Branch is Expanded- In a Tabbed UI component you can display Tree Controls as Expanding Menus. If you choose to display a Tree Control as an Expanding menu, there are now new menu options that allows you to close all branches on the Expanding Menu when the user makes a menu selection in the Expanding Menu, or close a previously opened menu branch when another branch is expanded.

 

 

UX Component - Step Indicator Control - Right-to-Left - The Step Indicator control now supports the right-to-left direction.

 

Watch Video

 

To set the direction, open the builder and set the Direction property.

 

xbasic_execute_javascript() Function - If the Javascript to be executed contains errors, this function now returns the line and column of the error and it also returns a stack trace.

For example:


{
	"error": true,
	"errorText": "m is not defined ( line: 9 column: 1)",
	"errorLine": 9,
	"errorColumn": 1,
	"errorStack": "ReferenceError: m is not defined\r\n    at foo ( :4:19)\r\n    at bar ( :7:4)"
}			
			

 

Xbasic - Debugging Server-side Javascript - The xbasic_execute_javascript() function allows you to execute Javascript code from Xbasic. Now, you can debug into the Javascript code while it is executing. Just add the debugger; statement into your Javascript code at the point where you want to start debugging and then open the Chrome dev tools Node debugger.

To do this, open Chrome and navigate to:

chrome://inspect/#devices

The click the Open dedicated DevTools for Node hyperlink.

Once you have opened the DevTools for Node window, you can execute the Javascript using the  xbasic_execute_javascript() function and your code will pause when a debugger; statement is hit.

Watch Video

 

You can also use __log() and console.log() statements in your Javascript. If the debugger is open, the console.log entries will be shown in the debugger's Console window. The __log() statements will be shown in a special console window.

 

Xbasic - a5_excel_to_sqlite() Function - Generates a SQLite database file from the 'tables' defined in an Excel file. Each sheet in the Excel file represents a table in the SQLite database. The sheet names in the Excel file must not contain special characters or spaces.

Syntax

p result = a5_excel_to_sqlite(c excelFilename, c sqliteDBFilename)

 

Where:

 

Each sheet in the Excel file must have column names in the first row. The column name can include a special decoration to indicate that the column is the table's primary key. (See image)

If there is no columns with the (primaryKey) decoration, a new column called __primaryKey is automatically added to the SQLite table. This column contains the row number of the row.

 

 

 

Xbasic - a5Helper_createSQLiteDBFromJSONDefinition() Function - The a5Helper_createSQLiteDBFromJSONDefinition() function allows you to create a SQLite databse programatically.

Syntax

 

p result = a5Helper_createSQLiteDBFromJSONDefinition(c json,c sqlitedbfilename[,c arguments [,c xbfunctiondefinition]])

 

Where

 

Example:


dim json as c 
json = <<%str%
[
	
	{
		"tableName": "table2",
		"definition": {
			"type": "SQL Query",
			"sql": {
				"connectionString": "::Name::northwind",
				"sqlstatement": "SELECT customerid,contactname,city,country from customers",
				"sqlstatement": "SELECT * from customers where country = :whatcountry",
				"primaryKey": "CustomerID",
				"portableSQL": true,
				"primaryKeyIsAutoIncrement": true,
				"indexes" : [{"name" : "index1" ,"columns" : "country"}]
			}
		}
	},
	{
		"tableName": "table3",
		"definition": {
			"type": "Static Data",
			"static": {
				"dataArray": [
						"ID=INTEGER (Primary Key),FirstName=TEXT,LastName=TEXT,Salary=NUMERIC",
						"1,Fred,\"Smith\",87234",
						"2,Tom,Jones,45234"
					],
				"indexes" : [
					{"name" : "index1","columns" : "LastName,FirstName"}
				]
			}
		}
	},
	
	{
		"tableName": "table4",
		"definition": {
			"type": "Xbasic",
			"xbasic": {
				"function": "xb1",
				"indexes" : [
					{"name" : "index1", "columns": "field1"}
				]
				
			}
		}
	}
]
%str%



dim xb as c 
xb = <<%str%
function xb1 as c (e as p)
xb1 = <<%txt%
ID=INTEGER (Primary Key),FirstName2=TEXT,LastName2=TEXT,Salary=NUMERIC
1,Fred,"jones",87234
%txt%
end function 
%str%

dim args as sql::arguments 
args.add("whatcountry","france")

dim pResult as p
pResult = a5Helper_createSQLiteDBFromJSONDefinition(json,"c:\data\sq1.db",args.xml,xb)


			
			

 

Bugs

UX Builder - Fixed numerous issues with the UX Builder.

Tips

 

 

Alpha Anywhere V4.6.1.1 - Build 5991-5333 24-JUL-2019

Bugs

UX Builder - Fixed miscellaneous regressions in the UX builder.

SOAP Services - Fixed a regression in the SOAP Service builder.

 

Alpha Anywhere V4.6.1.0 - Build 5982-5332 20-JUL-2019

 

Videos

UX Component Debugging Javascript Code Alpha Anywhere has an embedded version of Chrome, which means you can use the Chrome debugger to debug your client-side Javascript code.

In this video we show how you can step through client-side Javascript code in the Chrome debugger and how you can use the debugger's Console window to watch the value in different variables in your Javascirpt code.

Watch Video

Date added: 2019-06-07
Creating a REST API Using a Genie to Expose Tables in a SQL Database Alpha Anywhere has a powerful REST API feature that allows you to create REST APIs for many different tasks. A common use case for a REST API is to expose data that is stored in a SQL database. The REST API Genie makes it easy to create an API that allows data to be retrieved from a SQL database and also to be updated/inserted.

In this video we show how you can use the Genie to create a REST API that exposes data in selected tables in a SQL database.

Watch Video - part 1
Watch Video - part 2
Watch Video - part 3

Date added: 2019-06-13
UX Component - List Control Using HTML Templates in the List, ViewBox and Free-form HTML Layout Control The UX builder comes with several attractively designed HTML templates than can be used when designing List controls, ViewBox controls and Free-form HTML Layout controls. In this video we show how to use the pre-defined HTML templates to create some very attractive UX components.

Watch Video - part 1
Watch Video - part 2
Watch Video - part 3

Using HTML Templates in the ViewBox Control
Watch Video - part 4

Using HTML Templates in a Free-form HTML Container Control
Watch Video - part 5
Watch Video - part 6

Download files

Date added: 2019-06-30
     

 

 

Notice

    Windows XP - Alpha Anywhere no longer supports Windows XP

Features

Alpha Cloud - IP Restrictions - You can now set IP restrictions for Alpha Cloud applications. For more information, see these documentation links:

Applications:  https://documentation.alphasoftware.com/pages/Guides/Alpha%20Cloud/Alpha%20Anywhere%20Developers%20Guide/Managing%20Applications.html#ManagingIPRestrictions

 

Deployments:  https://documentation.alphasoftware.com/pages/Guides/Alpha%20Cloud/Alpha%20Anywhere%20Developers%20Guide/Managing%20Deployments.html#ManagingIPRestrictions

 

Portable SQL - CASE Statement - Portable SQL now supports the CASE statement. Most native syntaxes support a CASE statement directly, but some native syntaxes (e.g. Access, Excel, Paradox), do not. In these cases, the portable CASE statement is converted to nested IIF() function calls.

Example

 

SELECT
CASE City
    WHEN 'London' THEN 'English
    WHEN 'Madrid' THEN 'Spanish'
    ELSE 'Something Else'
END,
count(*)
FROM Customers
GROUP BY
    CASE City

        WHEN 'London' THEN 'English'
        WHEN 'Madrid' THEN 'Spanish'
        ELSE 'Something Else'
    END
ORDER BY 1
 

 

 

 

PhoneGap - Alpha WkWebView Engine Plugin - Instant Update - Channels - Publishing to different channels when using Instant Update is now supported when the Alpha WkWebView Engine plugin is being used.

UX and Grid Component - Advanced Search Control - Combolist and Suggest Control Types - The combolist and suggest control types allow you to define a SQL query as the data source and they also allow you to specify a different display and stored value.

For example, say you add CustomerId as a search field and you define the control as a combolist with CustomerName as the display value and CustomerID as stored value.

At runtime, the user might select (say) 'Alpha Software' in the dropdown for the CustomerId search field and previously, the stored value (of say 123) would be displayed in the search field. When the query was submitted, a query for CustomerId = 123 would be executed. While this is all correct, the user experience was less than optimal. It would be easier for the user to understand their query if the value 'Alpha Software' was shown in the Advanced Search control after the user made the selection from the dropdown and then when the query was run, the value 'Alpha Software' was resolved to 123 before the actual SQL query was executed.

Alpha Theme - Edit Control Animation - When you give focus to an edit control, a pulse animation shown on the control (see image below). If you turn the pulse effect off, the animation is not shown.

 

Xbasic - xbasic_execute_javascript() Function - This function now has two additional optional parameters, (validateCode and openConsoleWindow)

Syntax

p result = xbasic_execute_javascript(c js, [l flagSandbox [, l validateCode[, l openConsoleWindow]]])

Where:

Xbasic - Arrays - .dump_json() Method - A new method is available for property arrays. The dump_json() method allows  you to create a JSON string from data in a property array (this method is similar to the .dump_properties() method).  You specify a pattern to define the shape of the JSON that should be generated.

 

For example, assume the following JSON object that represents the data in an Xbasic property array.

 

 

dim json as c = <<%str%
[
	{"Firstname": "John", "Lastname" : "Smith",  "Address": { "Street" : "14 Main Street", "City" : "Boston", "State" : "MA"}}, 
	{"Firstname": "Henry", "Lastname" : "Rhodes", "Address": { "Street" : "4 Circle Drive", "City" : "New York", "State" : "NY"}}, 
	{"Firstname": "Allison", "Lastname" : "Berman", "Address": { "Street" : "11 Beaver Avenue", "City" : "Los Angeles", "State" : "CA"}}
]
%str%			
			

 

This JSON can be parsed into an Xbasic property array as follows:

dim p as p = json_parse(json)

 

Assume that the following pattern  (a JSON string) to define the required shape of the JSON to be dumped out:

Notice that the pattern can specify property names (and corresponding default value) for properties that may not exist in the source property array. For example, the pattern specifies a Married property with a default value of true.

 

dim pattern as c = <<%str%
{
    "Lastname": "",
    "Married": true,
    "Address": {
        "City": ""
    }
}
%str%
 
				

The  .dump_json() method can be called on the Xbasic property array. For example:

var resultJSON = p.dump_json(pattern)
			

The resulting JSON from the method is shown below:

 
 [
    {
        "Lastname": "Smith",
        "Married": true,
        "Address": {
            "City": "Boston"
        }
    },
    {
        "Lastname": "Rhodes",
        "Married": true,
        "Address": {
            "City": "New York"
        }
    },
    {
        "Lastname": "Berman",
        "Married": true,
        "Address": {
            "City": "Los Angeles"
        },
    }
]

 

NOTE: Like the .dump_properties() method, the .dump_json() method takes an optional second argument to filter the data in the array.

UX Component - Show/Hide Controls - Improvements have been made to the way in which controls are hidden. Now, the extra space taken by the break after a control is also hidden when the control is hidden.

Xbasic - HTML_to_PDF() Function - Page Size - You can now specify page size (height and width) and margins (top, bottom, left, right) for the HTML_to_PDF() function. The page size is defined in a JSON string inside an HTML comment in the HTML to convert to PDF. For example:


<!--PAPER:
	{
	"width": "11in",
	"height": "8.5in",
	"margin": {
		"left": "0in",
		"right": "0in",
		"top": "0in",
		"bottom": "0in"
	}
}
-->
			

 

 

Xbasic - a5_file_get_access_control() Function - Function allows you to get a list of file permissions for a specified file/folder. The result if return in JSON format. For example:

			
?a5_file_get_access_control("c:\dev")
= [
    {
        "group": "BUILTIN\\Administrators",
        "read": true,
        "write": true,
        "append": true,
        "delete": true
    },
    {
        "group": "NT AUTHORITY\\SYSTEM",
        "read": true,
        "write": true,
        "append": true,
        "delete": true
    },
    {
        "group": "BUILTIN\\Users",
        "read": true,
        "write": false,
        "append": false,
        "delete": false
    },
    {
        "group": "NT AUTHORITY\\Authenticated Users",
        "read": true,
        "write": true,
        "append": true,
        "delete": true
    }
]

			

UX Component - PhoneGap - Instant Update - Channel Properties - When you define a new channel for Instant Updates, you can now set properties for the channel. These properties include:

For example, on your <Default> (i.e. production channel), you might be using a component called 'MyApp'. But on the test channel, you might want to use a different UX component (for example 'MyAppV2').

 

In the PhoneGap Instant Update dialog, when you create a new channel, the dialog also allows you to set properties for the channel (you can't set properties for the <Default> (i.e. production) channel.

 

 

When you click the Set Channel Properties dialog the following dialog appears:

 

UX Component - List Control - Detail View - Synchronization - beforeCRUDExecute Event - When the edits in a List with Detail View are synchronized there can be multiple CRUD statements that are executed. A new event (beforeCRUDExecuted) can be defined for a List (or, in the case of a hierarchy of Lists, for the top-most List in the hierarchy) that fires before each CRUD statement is executed.

The motivation for this new event is to handle the following scenario:

Say you have made many edits  to the List and you then execute a synchronization operation. Because there are a large number of edits, it may take a significant amount of time on the server to complete all of the CRUD operations. However, if the server does not send a response back to the client before the callback times out, the client will stop listening and when the server finally completes the work and sends a response to the client, the client will not get the response (because it has stopped listening). As a result, all of the rows in the List that were dirty will remain dirty (even though on the server, all of the CRUD operations may have been completed).

However, if you send a response to the client before each CRUD operation takes place you can ensure that the client will still be listening when the server sends its final response back to the client indicating which rows in the List should now be marked as clean.

In order to use this new event, you must turn on chunked responses. This is done by passing a parameter to the .saveListEdits() method. For example:

 

{dialog.object}.saveListEdits('LIST1',{rows: 'allRows', chunked: {allow: true} });

 

 

To define the beforeCRUDExecuted event, edit the top-most List and open the List Events dialog and then select the Detail View Events category:

 

UX Component Builder - Right Click Menu - Goto Container End/Goto Container Start - A new menu item on the right click menu, when right clicking on a Container control (including Tab Control, Frame, PanelCard, PanelLayout and PanelNavigator) allows you to go to that container's end (or start) control.

 

 

UX Component - HTML Templates - New sample HTML templates are included. These templates can be used in the List control, the ViewBox control and in the Free-form HTML Container control.

 


Watch Video - part 1
Watch Video - part 2
Watch Video - part 3

Using HTML Templates in the ViewBox Control
Watch Video - part 4

Using HTML Templates in a Free-form HTML Container Control
Watch Video - part 5
Watch Video - part 6
 

Samples of the new HTML templates are shown below:

 

 

 

 

 

UX Component - List Controls - Restoring Lists From Storage - When a List is persisted to storage, the data in the List as well as the List 'state' (i.e. client side filter, client side sorting, etc.) are also persisted.

In some cases when the List is restored from storage, a Javascript error may occur when setting the List state to the persisted state.

You can now specify that when a List is restored, the data, but not the state, should be restored by setting a flag in the List's onInitialize event:

For example:

this._restoreListState = false;

 

 

 

UX Component - Action Javascript - PhoneGap - open File with Native Application Action - Report - Client-side Filename - This action now allows you to define a Javascript function to return the client-side filename for the report.

 

 

Xbasic - AlphaDAO - FullText Searching - Portable SQL - A new function (FullTextColumnContains()) has been added to Portable SQL to make it possible to do full text searches on columns for select databases (MySQL, MariaDB and SQL Server) where portable SQL is required.

 Syntax

FullTextColumnContains(<column>, <text>)


For most syntax handlers, the function is mapped to <column> LIKE ‘%’ + <text> + ‘%’, so it is not particularly useful.

However, for MySQL and MariaDB, the function is mapped to:

MATCH(<column>) AGAINST (<text>)


To use this function on MySQL or MariaDB, You must first create a full text index on the appropriate column.

For example:



ALTER TABLE customers ADD FULLTEXT companies_fulltext (CompanyName);

 

For more information, click here.

 

For SQL Server, the syntax is mapped to:

Contains(<column>, <text)
 

Note: You must have the SQL Server Full-Text Engine installed. For more information, click these links:

https://docs.microsoft.com/en-us/sql/relational-databases/search/full-text-search?view=sql-server-2017

https://www.techrepublic.com/blog/data-center/adding-sql-full-text-search-to-an-existing-sql-server/ 

 

 

 

UX Component - Expanding Menu Control - Selected Item Style - You can now set the style for the selected menu item.

 

-

UX Builder - Adding Buttons and Static Text Controls - Now, when you add a Button control the builder prompts for the button text (and also an optional button sub-theme). Similarly, when you add a Static Text control the builder prompts for the text. This is a convenience because previously a generic button label was used and you would then typically change the label in the control's Property Sheet. You can turn this new behavior off if you wish.

 

UX Component Builder - Performance - The UX Component builder has been substantially reworked to improve performance when editing large UX components. The following optimizations have been made:

Web Control Panel - Git Integration - Customize Push/Pull Commands - You can now customize the commands to push and pull repositories. This allows you to connect your repository to an server other than GitHub.

To define custom push/pull command click the Git Settings hyperlink on the Web Control Panel.

 

 

The, define the commands you want to use to Push and Pull your repository.

 

 

PhoneGap - cli-8.1.1 - Support has been added for the latest PhoneGap cli version.

SQL Query Builder - Formatted SQL Statements - When a SQL statement is shown in the SQL window of the SQL Query Genie, the statement is now formatted with line breaks to make the SQL easier to read.

 

UX Component - Ajax Callbacks - Chunked Responses - a5AjaxChunkedResponseWrite() - The a5AjaxChunkedResponseWrite() function now takes an optional second parameter.

The a5AjaxChunkedResponseWrite() is used inside an Xbasic function that handles an Ajax callback. This Xbasic function gets called with a parameter called 'e'. You can now pass this 'e' object into a5AjaxChunkedResponseWrite() as an optional second parameter.

Syntax

a5AjaxChunkedResponseWrite(c javascript [,p e])

 

If the Javascript that you pass to the a5AjaxChunkedResponseWrite() includes placeholders (e.g. {dialog.object}, or {dialog.componentname} ), then you must pass in e to the function in order that the placeholders may be resolved.

 

Web Control Panel - Git - Create Project from Repository - Private Repository - You can now create a new project from a private repository. You will be prompted to enter your Git username (must not include '@' ) and your password.

Web Applications - Security Framework - Summary For a Security Group - The dialog where security groups are defined now has a new option (Show pages/components authorized for selected group) that allows you to see all of the pages and components, reports, etc. in the Project that the selected Group is authorized to see.

 

When you click on the hyperlink the summary dialog is show. The top list contains all files that are allowed (because these files do not require a login). The bottom list shows all files that are only allowed to users who are logged in and are members of the specified group.

 

REST API - Genie - Expose Tables in a SQL Database - A new genie is available when you create a new REST API. The Genie allows you to create a REST API to expose data in a SQL database. The API will allow you to query the data in a table (returning the results in a JSON format) and to update, insert and delete records. The genie automatically creates the REST API definition and also the Xbasic class that backs the REST API. The generated code supports authentication of each endpoint using an API key.

When the REST API that is created by the Genie can be used "as is", the primary purpose of the Genie is to give you a starting point in creating a customized API of your own.

 

Watch Video - part 1
Watch Video - part 2
Watch Video - part 3

 

In order to use the new genie, set focus to the Web Services category on the Web Control Panel and then click the New button.

 

Click the Create a new definition to create a REST service button.

 

 

Click the Use Genie to Create REST Service to Expose Database Tables button.

 

 

This will open the Genie, as shown below:

 

 

  1. Specify the connection string to the database that contains the tables you want to expose.
  2. Select the tables/views you want to expose.
  3. For each selected table or view, select the operations you want to expose
  4. Specify the name for the service
  5. Finally, click the OK button to create the service - An Xbasic class and a Service definition will be generated.

For each table/view the following operations are available:

 

 

Once you click the OK button, the service is created. The genie creates a file with the name of the service and a .a5svc extension (this is the service definition), and another file called sqlcrud.<name of the service>.a5xbclass. This file contains the Xbasic class that defines the code that is executed for each of the REST end points.

 

 

After the service is created, you will be asked if you want to test the API.

 

 

If you specify that you do want to test the API, the Development Server will be started (if it is not already running) and your browser will be opened showing the test page for the service.

The page shows all of the end points in your API.

 

 

 

To test a particular end point, click the button to the left of the end point. For example, in the image below, the customers_select end point is being tested. This the end point that exposes the select operation for the customers table.

 

Since this is a POST end point, the POST body must be specified using a JSON format.

In the image shown below, the properties in the POST body have been specified:

 

 

 

 

When the click the Execute button, The Curl command used to make the API call is shown and the result of the API call is shown

 

 

 

Understanding Arguments

Arguments can be used in place of literal values in name/value pair parameters and WHERE clauses. For example, the expression below is a WHERE clause that uses arguments.

fname=:c_firstname AND dob=:d_date1

 

This expression uses two arguments (c_firstname and d_date1). Notice that in the WHERE clause the argument name are prefixed with a colon (:).

The argument values are defined in a comma delimited list of name/value pairs. For example

c_firstname=Fred,d_date=12/18/1972

 

Notice that each argument name must start with a single letter, followed by an underscore. The single letter defines the data type of the argument value.  The available types are C (character), D (date), T (date/time), L (logical), N (numeric). For example

 

How to Enable Authentication

The generated service definition and Xbasic class include methods for authenticating access to the API, but the authentication is not turned on. The authentication is done by passing in an API key when the API request is made.

If you open the service definition (see image below), you will notice that each of the methods that are exposed in the API (indicated by the green icon) has a lock icon to the right indicating that the method requires authentication.

 

 

If you click on the Define Authentication Methods button in the Service Builder you will see that named authentication methods have been define for each of the exposed methods.

For example, a named authentication method called customers_select_authenticate as been defined.

 

 

If you edit the definition of the customers_select method (by double clicking on it in the Available Methods list) you will see that authentication has been turned on and that the customers_select_authenticate method has been selected as the method that will be called to authenticate access to the end point that exposes the customers_select method.

 

 

The definition for both the customers_select method and the customers_select_authenticate method are contained in the sqlcrud.<servicename>.a5xbclass file that was generated.

The generated authentication method is shown below. Notice that the apikey is marked as an optional argument in the function definition (apikey = "").

To turn authentication on for the customers_select end point, you would change the function definition for the customers_select_authenticate method so that the apikey argument is required and you would then write your own code to determine if the function should return 200 (allowed) or 401 (not allowed), based on the value of the apikey that was supplied.

 

 

function customers_select_authenticate as n (apikey = "")
'to enable authentication
'    1) change the function prototype to make apikey required

'    (e.g. function customersupdateauthenticate as n (apikey as c ) )
'    2) write code that determines if the apikey allows this action
'    3) if allowed, return 200, if not allowed, return 401
customers_select_authenticate = 200
end function

 

 

In order to supply the APIKey at the time the API is called you would need to supply its value in the query parameters for the API end point. For example:

http://127.0.0.1:10444/LivePreview/northwind.a5svc/customers_select?apikey=12345

 

TIP: If you prefer to supply the apikey in the request header, then you would edit the Authentication Method and change the setting for Arguments to header.

 

Node -  A newer version of Node is now bundled with Alpha Anywhere. This version supports promises and the async/await pattern.

Chrome - A newer version of Chrome is now embedded into Alpha Anywhere. This version supports an improved debugger, including the ability to add watch variables to the console window.

Watch Video
 

Bugs

UX Component - Control Behavior Overrides - Fixed a regression.

UX Builder - List Control - Incremental Refresh - Timestamp Field - Fixed an issue with incremental refresh using a timestamp field when the List had an ORDER BY clause.

UX Builder - Fixes a cosmetic issue when you move the position of a control in the UX Builder (requires hotfix).

Web Control Panel - Fixes a crash when you have added a custom column to the Web Control Panel and that column has more than 260 characters.

Phone Gap - Instant Update - Fixed an issue where Instant Update would fail if the Web Project was on a network drive.

Application Server - Web Sockets - Under certain conditions, if Web Sockets had been turned on, the Application server would become unresponsive.

Tips

 

Reports - Text Dictionary - UTF8 Characters - The labels on Layout Reports can be translated at print-time into different languages by defining a Text Dictionary for the report. The Text Dictionary contains translated values for all of the specially tagged labels in the report definition. For example, you might have a Label on a report with this text

<a5:t>Report Header</a5:t>

 

At print-time the Text Dictionary is accessed to find a translated string for Report Header in the specified language. In certain cases when the translated string contains certain UTF-8 characters, the labels on the report will not render correctly. This is a limitation that results from the code page of the machine where the server is running.

To work around this limitation, use the HTML control instead of the Text control on your report.

 

 

For example, add an HTML control to the report then edit the HTML control to add the label text.

For example

<a5:t>Report Header</a5:t>

However, this is not sufficient to work around the problem. You must also add this meta tag to the HTML (in the HTML head section).

<meta charset="utf-8">

 

 

Alpha Anywhere V4.6.0.1 - Build 5887-5315 04-JUN-2019

 

 

Hotfix - Various Fixes - Web Control panel - Fixes an issue where a custom column in the Web Control Panel was more than 260 characters, UX Builder - Fixes a cosmetic issue when you move the position of a control in the UX Builder, Web Control Panel - GitHub - Fixes an issue when pushing to GitHub if an existing _netrc file was not found.

 

Hotfix - Fixes an issue with the ControlBar Action action in Action Javascript

 

How to install a hotfix

 

 

Web Control Panel - Git - Color Settings - You can now customize the colors uses to show the different states of files in a Git repository.

To open the dialog to customize colors, click the Git Settings hyperlink, then select the Customize color coding menu item.

 

 

The following dialog will be shown:

Web Control Panel - Git Repository - Color Coding - The files shown in the Web Control Panel are now color coded if the project is a Git Repository.

For example, in the screen shot shown below it is easy to pick out the file that has been modified but not yet committed (shown in red) and the file that is currently not being tracked (shown in orange).

 

 

Web Application - oAuth Events - A new server side event fires when an oAuth authentication flow is complete. This event can be used to store the tokens returned by the oAuth provider.

 

 

Web Control Panel - Git - Creating Git repositories for projects with a large number of files is now significantly faster.

 

Components - LIve Preview - Server Address -  When you live preview a component, the URL uses localhost as the server address. In some cases (for example, when testing different oAuth providers), you might want to use 127.0.0.1 as the server address.

You can now specify the server address for Live preview. To set this property open the Project Properties dialog and go to the Design-time Properties pane.

 

 

UX Component - Password Fields - Enter Key - Password fields in a UX component are automatically wrapped in <form>...</form> tags to prevent Google Chrome from logging a warning in the console window. Now, you can specify that you do not want password fields to be wrapped in <form> tags. To do so, uncheck the Wrap password fields in form tags property in the Advanced section of the Properties pane in the UX builder.

 

 

Application Server - OpenSSL - Version 1.1.1c - The version of OpenSSL used in Alpha Anywhere has been updated to version 1.1.1c

Two Factor Login - Suppress 2nd Factor - In some cases, even though a user has turned on two-factor authentication, you might want to suppress the 2nd factor dialog.

 

You can now specify the name of an Xbasic function (in both the TabbedUI and UX component) to call before the 2nd factor dialog is shown. If the code in your Xbasic function sets:

e.suppress2ndfactorLogin = .t.

then the 2nd factor dialog will not be shown and the user will be logged in.

 

 

 

 

New Build Available Message - Suppress - When the Alpha Anywhere IDE or the Runtime version is launched, a message box is shown if a new version is available. In some cases (for example, Runtime applications), you might want to suppress this message for ever appearing.

You can now do this by creating a file called suppressNewBuildMessage.txt. The contents of the file is irrelevant. This file should be placed in the executable folder, or in the workspace folder.

 

UX Component - List Control - Checkbox Select Column - Selected Row Class Name - You can now specify a classname for rows that have been selected.

 

UX Component - Action Javascript - OAuth - Get Token - This action now allows you to suppress or customize the confirmation dialog.

 

Bugs

UX Component - Password Fields - Enter Key - Password fields in a UX component are automatically wrapped in <form>...</form> tags to prevent Google Chrome from logging a warning in the console window. Now, when the user is in a password field and presses Enter, the Form that wraps the password field is no longer submitted.

Windows Commands - The Cascade, Tile Horizontally, Tile Vertically and Arrange Icons commands on the Windows menu now all work as expected.

 

UX Component - List Control - Keyword Searches - Date and Time Fields - Fixed an issue when a data for time field was included in a keyword search.

Desktop Applications - Forms - Chrome Control - Fixed some issues related to using a Chrome control in a Form.

Alpha Theme - Pulse Effect - Menu Items - If the pulse effect was turned on, clicking buttons in menu items did not fire the click event.

Web Control Panel - Git - Network Drives - Feature to make a Web Project folder into a Git repository was not working correctly if the Web Project was not on same drive as the executable folder, or was on a network drive.

 

 

 

Alpha Anywhere V4.6.0.0 - Build 5864-5310 23-MAY-2019

Videos

UX Component - List Control Alternating Row Colors In this video we show how you can configure a List control to show alternating colors for even and odd rows.

Watch Video

Date added: 2019-03-24
UX Component - List Control Map Layout A List control can have multiple Layouts. The most common Layouts are columnar and freeform. But a List can also have a Kanban layout and a Map layout.

The Map layout displays a Map control in the List and shows markers on the map for each row of data in the List.

In this video we show how the Map layout is configured.

Watch Video

Download files

Date added: 2019-03-24
Security Framework - Two-factor Authentication  Demonstration  Two-factor authentication is more secure than single-factor authentication because even if a user's password is stolen, the user account is still protected because the person who stole the password will likely not be able to get the authentication code to complete the login to the application.

In this video we demonstrate a login component that utilizes two-factor authentication.

Watch Video
 
 Date added: 2019-04-10
Security Framework - Two-factor Authentication Configuring the Extended User Information Table Before you configure a web project to use two-factor authentication, you first have to create an Extended User Information table for your web project.

This video shows how to create an Extended User Information table.

Watch Video
 
 Date added: 2019-04-10
Security Framework - Two-factor Authentication Configuring a Web Project to use Two-factor Authentication In order to use two-factor authentication in a web project you  must configure settings in the application Project Settings.

In this video we show how two-factor authentication settings are defined.

Watch Video
 
 Date added: 2019-04-10
Security Framework - Two-factor Authentication Setting User-preferences for Two-Factor Authentication Two-factor authentication is a preference setting for each user in your application. Some users may elect to turn two-factor authentication on, while others may prefer single factor authentication. If a user turns two-factor authentication on, they must specify which option they wish to use - SMS, Email or Goggle Authenticator.

A sample UX component is provided to allow users to set their two-factor authentication preferences. In this video we show how to use this sample UX component.

Watch Video
 
 Date added: 2019-04-10
UX Component - Ajax Callbacks Chunked Responses - Sending Intermediate Responses to the Client Normally, when you make an Ajax callback from an UX component, the Xbasic function that handles the callback completes its processing and then returns Javascript to the client. In some uses cases where your Xbasic function takes a "long" time to execute, you might want to send some type of intermediate message to the client telling them that the function is still processing and perhaps letting the user know what stage the function is at.

In order to send back intermediate responses to the client while the Xbasic function is still processing, you can set the Ajax callback to allow chunked responses.

In this video we show how you can configure an Xbasic function to do chunked responses.

Watch Video

Download files

Date added: 2019-05-02
Git Repositories Working with Git Repositories The Web Control Panel is tightly integrated with Git and GitHub. You can make any Web project into a Git repository and you can connect this repository to a remote GitHub repo. You can perform many of the basic Git commands (such a committing files, pushing to a GitHub repository and pulling from a GitHub repository directly from menus on the Web Control Panel.

In this video we show how to make a Web Project into a Git repository, how to connect this repository with a remote GitHub repository, how to push files to the remote Git repository and how to create a new Web project that is cloned from a remote GitHub repository.


Watch Video - part 1
Watch Video - part 2
Watch Video - part 3

Date added: 2019-05-15

 

 

 

Changes

Grid Components - Time Fields - Default Display Format - When you add a Time field (this is actually a Date/time field), the default server side Display Format is now set to time("{grid.clientSideDateFormat} 0h:0m 0s am",<value>). Previously it was set to time("{grid.clientSideDateFormat}",<value>), which meant that the time portion of the date/time value was stripped off.

Features

Grid Component - Client-side Events - onAjaxCallbackFailed - a new client-side event has been added. The onAjaxCallbackFailed will fire if the server does not send a response back to the client within the the default timeout period that the client waits for a response.

UX Component - List Control - Synchronization - Write Conflicts - Improvements in the way in which write conflicts are determined have been made.

Consider the following scenario:

 

Previously, the user would have received a write conflict error because the original value for the City field (i.e. 'Boston') no longer matches the current value in the City field (i.e. 'London').

However, now, this scenario will no longer trigger a write conflict error because the user is trying to change the value in the City field to a value that is currently in the City field (i.e. 'London').

Had the user tried to change the City field to (say) Madrid, then they would get a write conflict error.

 

 

Xbasic Functions - excel_to_sqlite() - Creates a SQLite database file from data in an Excel file.

Syntax:

excel_to_sqlite(c excelfilename, c sqlitefilename)

Where:

excelfilename - filename of the Excel file

sqlitefilename - filename of the SQLite database to create

Each sheet in the Excel file becomes a table in the SQLite database. The sheetname is the table name. If the first column in each sheet is numeric data and there are no duplicate values in the column data, that column is the primary key of the table in the SQlite database.

 

Alpha Cloud - Publishing - Only Publish Changed Files - The Alpha Cloud publish dialog now has a new option to only publish files that were changed since the last time a full publish was done.

 

 

Web Projects Control Panel- Git Integration - Git and GitHub support is now integrated into the Web Control Panel. When the Web Control Panel is displayed you will notice a Git icon at the extreme right of the toolbar in the Control Panel.

IMPORTANT: You must install Git on your machine to use this feature. Git is a free install. You can find the installer at: https://git-scm.com/downloads. When you install Git be sure to select the option that adds Git to your path:

 

Watch Video - part 1
Watch Video - part 2
Watch Video - part 3

 

You can make an existing project into a Git repository by clicking the Git icon.

This will display the Git Menu dialog as shown in the image below.

You can make the current project into a Git Repository by clicking on the Yes - Make a Git Repository button, or you can clone an existing GitHub repository.

 

 

 

Warning: If you convert a large Web project into a Git repository, (and you check the Add all files checkbox prompt shown in the image above) Git may take a significant amount of time to add all of the files to the Repository.

 

Once you have made your Web project into a Git repository the Web Control Panel will show a Git toolbar under the main toolbar shown in the Window.

The Git toolbar shows you the number of Untracked and Modified files in your project.

 

 

 

 

 

To commit any modified files, or to add untracked files to your repository, click the Git button on the toolbar, or click directly on the Untracked files or Modified files message on the Git toolbar.

 

 

When you click the Git button you will see the Git Commit window where you can select which files you want to commit and which currently untracked files you wish to start tracking. You must enter a commit message before you can click the Commit button.

Once you have committed files, the modified files and untracked files count in the Git toolbar will update.

 

 

 

 

Connecting your Git repository to a remote GitHub repository

You can connect your local Git repository to a remote GitHub repository. Once you have done this you will be able to push and pull to and from the GitHub repository using the Push to GitHub and Pull from GitHub hyperlinks on the Git toolbar.

 

In order to connect your repository to a remote Git repository, click the Git Settings hyperlink in the Git toolbar.

First, select the Save User ID and password for GitHub to enter your credentials for your GitHub account.

Next, select the Register/change remote GitHub repository command. This will open a dialog (shown below) where you can enter the URL for your remote GitHub repository.

 

 

 

 

 

Editing the .gitignore file

Your web project may have certain files that you do not wish to be part of your Git repository. The list of files and file types that you want to ignore is defined in the .gitignore file. You can edit the .gitignore file by selecting the Edit the .gitignore file from the Git Settings menu.

 

Creating New Projects

When you create a new Web Project (by clicking the New Project button in the Web Control Panel), you can specify if the new project should be a Git repository. You can also create a new project from a remote GitHub repository.

 

 

 

 

 

Web Projects Control Panel - Command Window - You can now open a command window for the folder where the current Web Project is located. This is particularly useful if you want to execute a Git command from the command line.

To open a command window, click the icon shown with a yellow highlight in the image below.

 

 

UX Component - PhoneGap - Cordova-Sqlite-Evcore-Extbuild-Free Plugin - Added support for the latest version, 0.9.10 of the Cordova-Sqlite-Evcore-Extbuild-Free plugin which is required when building Android PhoneGap apps with cli-8.0.0. This plugin uses a special Android NDK sqlite database access library (C-language implementation), 
with some premium improvements to the internal JSON interface between the Javascript and native Android implementation, to provide significant performance and memory usage improvements on the Android platform.
 

UX Component - List Control - Column Layout - Persist and Restore Layout Definition - At run-time, a user can adjust the Layout of a columnar layout by hiding columns, adjusting the column order and by adjusting the width of each column. You can persist this state using the {dialog.object}.persistListColumnLayout() method.

You can restore a previously persisted List column layout using the {dialog.object}.restoreListColumnLayout() method.

The persisted column layout is store in the browser's localStorage using the List GUID and the Layout name as the key.

Each List has a unique GUID property.

When you use the {dialog.object}.restoreListColumnLayout() method, the method checks localStorage to see if there is a persisted Layout that matches the List's GUID property and the name of the Layout that is currently active. (List's can have multiple Layouts.). You can only restore the Column Layout of a columnar List Layout.

Example:

 

{dialog.object}.persistListColumnLayout('list1')  //persist layout of List1

 

{dialog.object}.restoreListColumnLayout('list1')  //restore layout of List1


 

SQLite Databases - Auto-increment Primary Key - When Alpha Anywhere creates a SQLite database with a table based on a SQL table where the primary key is an auto-increment field, the primary key in the SQLite database is now also an auto-increment field.

Xbasic - REST Service Definition - OPTIONS Pre-flight Request - The Xbasic REST API Builder now allows you to define an handler for the OPTIONS pre-flight request.

 

 

UX Component - List Control - Server-side Sorting - Column Title Sort Icons - When performing server-side sorting on a List control, the sort icons in the column headings are now set. Previously, these icons were only set for client-side sorting.

Xbasic - AlphaDAO - SAP HANA - A new syntax handler for SAP Hana is available. To use this syntax handler you must have v2.0 or greater of the SAP HANA ODBC driver installed. Create an ODBC connection string and select the SAPHANA syntax.

UX Component - PhoneGap Applications - WkWebView Plugin - A new PhoneGap plugin, developed by Alpha Software, is available for iOS applications. The UIWebView plugin, which PhoneGap applications currently use, has been deprecated by Apple, and will be removed from a future version of iOS. It will be critical that you switch your PhoneGap applications to use the WkWebView plugin before the next version of iOS is released.

Full details about this plugin are available here.

 

 

NOTE: As a result of the recent Apple update of iOS to version 12.2 the following actions no longer work in PhoneGap applications (that use the UIWebView plugin):

Camera access using the HTML5 option (PhoneGap camera access continues to work)

File Upload - Amazon S3 - This action no longer will bring up the image selector.

With the new WkWebView plugin, HTML5 camera access is working.

 

UX Component - Ajax Callbacks - Chunked Responses - You can now send back intermediate responses (i.e. "chunked" responses) from an Xbasic function that handles an Ajax callback. Previously the Xbasic function would need to run to completion before sending a response to the client (i.e. the browser).

To enable chunked responses, check the Allow chunked responses property in the Action Javascript builder.

Watch Video

 

IMPORTANT: In order to use chunked responses on IIS (or Alpha Cloud), you must turn on the JIT Sessions option. On Alpha Cloud this option is available on the Deployment dialog.

 

When you turn this property on, you can also set these properties:

 

 

The use case for this feature is when you have a callback function that is long running and you want to send periodic messages to the browser telling them that their request is still being processed.

In order to send an intermediate message to the client, your Xbasic function must use the

a5AjaxChunkedResponseWrite() method. For example:

 

dim js as c

js = "$('div').innerHTML = 'Still working...'

a5AjaxChunkedResponseWrite(js)

 

 

 

UX Component - List Control - Data Source - Excel File - CSV File - You can now set the data source of a List control to either an Excel file, or a CSV (comma separated values) file.

At run-time, the file is downloaded and the data are extracted from the file and then used to populate the list. When the List is refreshed, the remote file will be fetched again and the List will be repopulated.

In the image below, the List Data Source Type has been set to Excel file.

The builder exposes the following properties

 

 

 

Application Server - Classic Server - Security Settings Cache - The security settings are now automatically cleared on every publish of your application and are reloaded at the time of the first request. Previously, in the cases where the publishing method was non-optimized FTP, or LAN, the security settings were cached and only reloaded on a server restart.

 

Xbasic - AlphaDAO - SQL::Connection.ResultSetFromJSON() Method - A new method has been added to the SQL::Connection object. You can now convert a JSON array of objects into a SQL::Resultset object.

 

Example:


dim json as c = <<%json%
[
    {"ID":"1","Company":"Company A","Last_Name":"Bedecs","First_Name":"Anna"},
    {"ID":"2","Company":"Company B","Last_Name":"Solsona","First_Name":"Antonio"},
    {"ID":"3", "Company":"Company C", "Last_Name":"Axen","First_Name":"Thomas"}
    ]
 
%json%
 
dim rs as sql::ResultSet
dim cn as sql::connection
rs = cn.ResultSetFromJSON(json)
sql_resultset_preview(rs)
 

Xbasic - Number of sheets in an Excel file - a5_analyzeExcelFile() - The a5_analyzeExcelFile() function can be used to return the number of sheets in an Excel file

 

Example

dim fn as c = "filename of excel file";

?a5_analayzeExcelFile(fn).sheetnames
= people
companies
products
 

UX Component - List Control - Excel Import - Then action to import an Excel spreadsheet into a List that is based on a SQL database has been changed to use the libXL library (which is bundled with AA) rather than Microsoft ODBC drivers for reading the Excel file. As a result of this change Excel files that have columns with mixed data types (character and numbers) can now be imported.

 

Xbasic - excel_to_resultset() Function - Takes an Excel file and returns a SQL::Resultset object. You can optionally specify the name of a sheet in the file. If you do not specify a sheetname, the first sheet in the file is assumed.

 

Xbasic - excel_to_json() Function - Takes an Excel file and returns a string of JSON data.

Syntax

c result = excel_to_json(c filename [, c filter [, c order [,sheetname]]]])

where:

UX Component - Data Series - Date Values - By default, if you have a Data Series that is based on a SQL database, any date or time (date/time) values in the Data Series are rendered using the server's regional settings (i.e. MM/dd/yyyy for US or dd/MM/yyyy - international). However, in the case of the Chart control, it is necessary to provide data values in yyyy-MM-dd format. Therefore, the Data Series builder now allows you to define a date format.

UX Component - Array arguments - Session Variables - Arguments can be bound to session variables. Array arguments can also be bound to session variables and the session variable must be set to a comma delimited list of values in order for the array argument to be argument to be correctly populated. Now, the session variable whose value is a JSON array can also be used to populate an array argument.

UX Component - List Builder - SQL Statement - Portable SQL - Previously if you had turned off the Portable SQL property in the List Builder and you clicked on the smart field to edit an existing SQL statement, Alpha Anywhere would open the SQL Query Builder if it was able to parse the existing SQL statement. Now, if the Portable SQL property is off, when you click the smart field a simplified editor is opened (regardless of whether the SQL statement can be parsed).

UX and Grid Component - HTML Editor - Insert Image - When you insert an image into the HTML editor you can now specify the image height, width and padding. If you enter a number without units (e.g. 200) then pixels are assumed. You can use any CSS units (e.g. 20%, 2in, etc).

 

 

Security Framework - Two-factor Authentication - You can now use two-factor authentication for logging into to your applications. Two-factor authentication can be implemented as a user-preference (i.e. some users of your application may choose to enable it while others might want to continue using single-factor authentication). Users who elect to turn two-factor authentication on can then select the way in which they will get the authentication code. If you want to force all users of your application to use two-factor authentication you can write Xbasic code (discussed below) to automatically set the user preference.

Two-factor authentication provides a more secure way for users to log into an application. The log-in process is divided into two stages. In the first stage the user is prompted for their userid and password. If the userid and password are successfully validated, the log-in process advances to the second stage where the user is prompted to enter an authentication code.

If the user enters the correct authentication code they will then be logged into the application.

There are various ways in which the user can get an authentication code after their userid and password have been validated in the first stage. The options are:

How to Set up Two-Factor Authentication
Before you can turn on Two-Factor Authentication you must first define an Extended User Information table for your Web Project.

This table is used to store each user's preferences for Two-Factor Authentication. For example, if a user specifies that they want to use SMS to receive their authentication code, the user's mobile phone number will be stored in this table. If the user specifies that they want to use Email to receive their authentication code, the user's email address will be stored in this table.

Once you have defined the Extended User Information table for your Web Project you can set up your Two-factor Authentication properties.

 

 

Allowing Users to Set their Two-factor Authentication Preferences
Your Web Application will typically have a page where user's can go to define their two-factor authentication preferences. A sample UX component is provided for you to include in your Web Application. You can customize this sample component. To use this sample component, create a new UX Component and select the SecurityFramework-Two-FactorAuthenticationPreferences template. See Two-factor Authentication Preferences Component below for more information.

 

IMPORTANT You cannot use Two-factor Authentication with a Login Component. Two-factor Authentication can only be used with the integrated Login feature in the TabbedUI and UX Components.

 

 

Two-factor Authentication Preferences Component

A sample UX component is provided to allow you to let users of your application specify if they want to turn on two-factor authentication, and if so, what their preferred method is for getting the authentication code.

If you want to allow users of your application to choose whether or not to use two-factor authentication then you will want to include this sample component in your application.

 

When you create a new UX component, select the SecurityFramework-Two-FactorAuthenticationPreferences template.

 

Here is how the component will look for a user who has turned two-factor authentication on and who has selected the Google Authenticator app as their method for obtaining the authentication code.

 

 

If a user selects Google Authenticator as their method, the user can then click on the hyperlink shown in the above image to obtain a QR code that can be used to configure the Google Authenticator app on their mobile devices.

If the user selects SMS, the dialog will allow the user to enter their mobile device's phone number.

If the user select Email, the dialog will allow the user to enter the e-mail address where the authentication code should be sent.

 

How to Programmatically Set A User's Two-factor Authentication Preferences

Two Xbasic functions make it easy to get and set a user's two-factor authentication settings. These are:

a5_setTwoFactorAuthenticationSettings() and a5_getTwoFactorAuthenticationSettings()

 

Setting Two-factor Authentication Options

Syntax:

p result = a5_setTwoFactorAuthenticationSettings(c userid,c  json)

 

Where

result - an object with error and errorText (if error is .t.) as properties.

userid - the user's user id

json - JSON string defining the two-factor options. For example:
 

{
    "requireTwoFactorAuthentication": true,
    "method": "Google Authenticator",
    "mobilePhone": "",
    "email": ""
}

 

 

Getting Two-factor Authentication Options

Syntax:

c result = a5_getTwoFactorAuthenticationSettings(c userid)

 

Where

result - a JSON string showing user's settings. (Use json_parse() to convert the string to an Xbasic dot variable)

userid - the user's user id

 

An example of what the returned result might be:

{
    "requireTwoFactorAuthentication": true,
    "method": "Google Authenticator",
    "mobilePhone": "",
    "email": ""
}

 

How to Require All Users to Use Two-step Authentication

By default, the security framework uses single-step authentication. Once a user has entered a valid user id and password they are logged into the application.

If you want to force all users to use two-step authentication you must programmatically set their two-step authentication preferences. This must be done on a user by user basis since each user's settings are unique (unless the method is Google Authenticator). Settings are unique for each user because in the case of SMS, it is necessary to store the user's mobile phone number and in the case of Email, it is necessary to store the user's email.

Each user's initial log in to your application will be a single-step login. However, in the server-side onLogin event you can redirect the user to a page where you can prompt for their mobile phone number or email address and then you can store their preferences.

On subsequent logins the user will go through the two-factor login process.

 

Token Expiration

If a user elects to receive their two-factor authentication via SMS or Email you can set an expiration on the token. The default expiration is 2 hours (7200 seconds). If a user does not use the token they received to complete stage 2 of their login within the allowed time, the token will expire and the user will have to start their login flow from scratch. You can set the token lifetime in the Web Project Properties.

 

 

Sample Login Components

When you create a new UX component there are three sample template components that you can use for user login. These are:

Each of these sample components has been updated to support two-factor authentication (if two-factor authentication is turned on for that user). If the user does not have two-factor authentication turned on, then these components will use a single step login process.

IMPORTANT When creating a Login component as a UX you should be sure to set the permission for the component and for the page that hosts the component as Always Allowed.

 

TabbedUI Component

The TabbedUI component allows you to integrate a login window as part of the component. The TabbedUI builder now has a section for customizing the UI that is shown when the prompt for the authorization code is shown.

 

 

Tabbed UI - Integrated Login - Horizontally Center Prompts - When you add an integrated login window to a Tabbed UI component you can now specify that the prompts for user name/password should be centered (horizontally).

 

 

Xbasic - a5wcb_googleAuthenticatorQRCode() Function - Displays a QR code to register a new application in the Google Authenticator mobile app.

The Google Authenticator App is used to display a time based token. In order to register a new application in the Google Authenticator app, a QR code is scanned. The a5wcb_googleAuthenticatorQRCode() function can be used to generate this QR Code.

Syntax:

C a5wcb_googleAuthenticatorQRCode(C issuer ,C userid ,C secret [,N width[,N height[,L returnB64image]])

 

Where

Xbasic - Email_send_web() Function - A new Xbasic function for sending email in a Web application is available.

The email_send_web() function will send an email using settings defined in the Web Project Properties. The email will be sent using an internal SMTP server, or using the Sparkpost REST service, depending on the preference defined in the Web Project properties.

Syntax:

 

P email_send_web(C from ,C from_alias ,C to ,C cc ,C bcc ,C subject ,C message [,C attachments])

 

 

UX Component - Switch Control - Switch Width - The previous Switch Width property has been renamed Control container Width and a new Switch Width property has been added. This gives you more control over the appearance of the Switch control.

 

 

IMPORTANT: This change is a breaking change. Your UX component switches will continue to render as they have in the past until the Switch control is edited. Once the switch control is edited, the overall size of the switch control will be based on the Control container width and Switch width property values.

 

PhoneGap Applications - Default Configuration - iOS Media Playback Requires User Action Property - The recent iOS 12.2 update changed the way media files are handled in the PhoneGap web view. In order for the UX Audio Player and Audio Player/Recorder controls to work with iOS 12.2, the iOS Media Playback Requires User Action property must be disabled in the PhoneGap configuration. This is now the default value for new PhoneGap projects.
 

To change this setting in existing projects, check the Show Advanced Options property in the PhoneGap App Builder Genie and uncheck the Media Playback Requires User Action option.

 

Application Server - Classic Server - TLS/SSL Settings - The TLS/SSL settings for the Classic Application Server and the Development Server now allow TLS 1.3 to be specified as the minimum protocol version. As this is currently the highest version of the protocol, it also means that this setting will force the server and all client to use TLS 1.3 exclusively.

It should be noted that not all clients support TLS 1.3 so this may prevent some users from accessing a server. Specifically, Microsoft Internet Explorer and Edge browsers do not have any support for TLS 1.3. More details on compatibility of browsers can be found at https://caniuse.com/#feat=tls1-3

 


 

 

UX Component - Container - Subtype 'None' - Content Alignment - Container controls (with a sub-type of 'None') allow the developer to set the content alignment to left, center, or right. If you select center or right, the way in which the content is aligned is now done using CSS Flexbox. If you find that this option causes an unexpected change in your component's layout you can revert to the old method by unchecking the Use CSS Flexbox property.

UX Component - Container - Subtype 'None' - Container Content Vertical Alignment - A new property is available to control the vertical alignment of a row of controls in a Container whose alignment property is Center or Left.

The Container content vertical alignment property can be set to Top, Center, or Bottom.

 

 

The images below show content in a Container for each of the three possible settings.

NOTE If the content alignment is Center or Right, all controls in the Container will display on a single line if possible. Break settings are ignored.

 

 

 

 

 

 

 

UX Component - List Controls - Window Resize - When the browser window is resized and is made smaller, the data in a List column row may wrap. Now, the List columns automatically resize (assuming their width is set to a flex value) and row data will not wrap.

UX Component - Client-side Events - onWindowResize - A new event is now available in client-side events. The onWindowResize event will fire when the browser window is resized.

Xbasic - Time Based Tokens - Time based tokens are typically used in features like two factor authentication. A time based token is a token that automatically expires after a short period of time. You can now generate and validate time based tokens in Xbasic using the nodeservices::timebasedtoken class.

 

Examples

'generate a time based token

'NOTE: in many cases the user will use an App like Google Authenticator

'to generate the token

dim tbt as nodeservices::timebasedtoken

dim secret as c = "abcdefghijklmnop" 'secret should be 16 characters if you plan to use Google Authenticator

dim token as c

token = tbt.Token(secret)

 

'validate a time based token

'NOTE: in many cases the user will use an App like Google Authenticator

'to generate the token

dim token as c

token = "123456"

dim flagValid as l

flagValid = tbt.CheckToken(secret,token)


 

Xbasic - Optimized Multiple File Download - A new Xbasic method is available to download multiple remote files very efficiently.

The extension::curl::DownloadMultiple() method takes a CRLF delimited string in the format:

local filename|remote file URL

 

Example:

 

dim filelist as c = <<%str%

localfilename1|remote url1

localfilename2|remote url2

%str%

result = extension::curl::DownloadMultiple(filelist)
 

Important: The remote URLs must be URL encoded. For example: https://www.myserver.com/my+image.jpg.

 

UX Component - List Control - Map Layout - List controls can have multiple layouts (e.g. columnar, free-form, kanban). Now, a List control can also have a Map layout.

The Map layout displays a Google Maps control in the body of the list and it displays markers on the map for each row of data in the List. Each row of data must have either latitude/longitude values, or an address.

Watch Video

 

UX Component - List Control - Alternating Row Colors - You can now configure a List to display alternating row colors for even and odd rows. Previously, this could only be done using code.

 

Watch Video
 

 

 

 

 

UX Component - Control Bar - Titles - It is common when designing a ControlBar to use the html item to place a title in the ControlBar. However, if the device width is insufficient to display all of the text, rather than wrapping the text you might prefer to truncate the text and display ellipsis to indicate that the text was truncated.

In the images below the Control Bar title is shown on a wide device and then a narrow device. On the narrow device the title text is clipped.

 

 

 

In order to implement title text as described above, the Control Bar now supports a new item type, htmlTitle.

 

 

Unlike a html item, the htmlTitle item can be the only item in a Control Bar Layout Line section. For example, in the image below, the Control Bar Layout line is shown for a Control Bar. Notice that the htmlTitle item in the Middle section is the only item in this section.

 

 

 

Reports - PDF - Remote Images - A common practice is to store images on a remote server (such as Amazon S3) and then include a reference to the image in a database table. When creating PDF reports from a table that has remote images, the report would take a long time to complete because the images were fetched from the remote location sequentially.

Now, a new optimization is used for creating these types of reports. All remote images referenced in the report are now pre-fetched (using a highly optimized parallel operation) and are stored in a temporary local folder. As a result, the report creation is now substantially faster.

IMPORTANT: In order for the optimization to work, the field must be marked as an Image Reference Field. This is done when defining the report data source. This is done by clicking the Advanced Options button in the Data Source builder.

 

 

Grid and UX component - Date Format - Culture - You can now specify that the date format, day names and month names for a component should be automatically selected based on the 'Accept-language' property in the request header when the browser makes a request. This makes it easier to build applications that seamlessly adapt based on the user's locale setting.

To use culture settings, set the date format to

<cultureDateFormal>

or

<cultureDateFormat> <cultureTimeFormat> (if you want the default format to include a time portion)

 

Set the day names to <cultureDayNames> and set the month names to <cultureMonthNames>.

 

 

 

UX, Grid and TabbedUI Components - Language and Text Dictionary Tags - <Culture> - The component builders allow you to wrap strings in either <a5:r>...</a5:r> or <a5:t>..</a5:t> tags so that you can define strings in different languages. At runtime you can specify which language definition to use by setting the value in a special session variable (session.__protected__activeLanguage).

Now you can automatically select a language definition by setting the component's Active Language property to <culture>.

You must define language definitions to match the culture code. For example, a user whose machine is configured for UK English will have a culture code of en-GB. Therefore, you must define text dictionary and language dictionary settings for a Language called en-GB.

 

UX Component - List - Check-box Select Control - Customization - You can customize the appearance of the checkbox-select control by clicking the smart field for the Check-box select control customization property.

 

 

When you click the smart field, a builder is opened.

 

 

You can control whether the icons used are SVG or bitmaps (bitmaps would be preferable if you are using a legacy style such as GrBlue). You can choose custom icon.

If you use the default SVG icon you can set the size, fill and stroke color of the SVG icons

 

 

Check-box select control using bitmap icons

 

Check-box select control using SVG icons with customized stroke and fill colors.

 

You can also control whether an icon appears in the column header to allow the user to check or un-check all rows in the list at once.

Xbasic - AlphaDAO - If a SQL commands fails because the database is in a deadlocked state, Alpha Anywhere will automatically retry the command.

OpenSSL - New version of OpenSSL. Version 1.0.2r.

 

UX Component - List Control - Checkbox Selector - You can now add a checkbox select control to List to allow the user to select rows. This is particularly useful if your List has a Detail View because you cannot turn on the multi-select option which allows the user to select multiple rows.

 

 

The following Javascript method can be used with Lists that have a checkbox-select control

  • <listObject>.getCheckedRows() - returns an array of row number (zero based) of rows that were checked.
  • <listObject>.getCheckedValues() - returns an array of values for the rows that were checked.
  • <listObject>.setCheckedRows(array) - takes an array or zero based row numbers and checks the specified rows.
  • <listObject>.setCheckedValues(array) - takes an array of values and checks the rows with the specified values.  For example, if a List based on the Northwind Customers table is set to return the CustomerID, then you could use this method to check the rows for 'ALFKI' and 'BOLID'.
  • <listObject>.checkAllRows() - checks all of the rows in the List.
  • <listObject>.unCheckAllRows() - un-checks all rows in the List.

To turn on the checkbox select feature, check the Has check-box select control property.

 

 

Then, add the <CheckBoxSelect> control to your List.

s

Xbasic Editors - Functions - A common error when editing Xbasic functions is to forget to return a value from the function. All functions (other than those of type v) should return a value.

There are two ways to return a value from a function

  1. Use the return statement
  2. Set the function name to the return variable.

Now, if you define a function (that is not of type v) and the function does not return a value, the Xbasic syntax checker will report an error.

 

 

TabbedUI - Login Feature - Chrome 72 and Above - In Chrome 72 and above Google made changes to the way password fields are handled. As a result of this change the first input control in a component shown in the TabbedUI was getting pre-filled with data. This issue is resolved in the build by wrapping the login controls in a dummy <form> element.

 

Xbasic Function Libraries - Compiled AEX files - You can now add a special directive into an Xbasic Function Library file that will cause the file to be compiled into an .aex file at publish time.

Add the

'compileaex

 

comment anywhere in the Xbasic Function Library file.

At publish time, any Xbasic Function Library file in the Web Project that contains this directive will be compiled into an .aex file. The .aex filename will be

__AAFunctionLibrary_<Xbasic function library name>.aex

 

NOTE: It is not necessary to add the name of the .aex file to the list of AEX files in Web Project Properties

 

At run-time, if a component specifies that a Xbasic Function Library should be loaded, the function library will only be loaded if an associated .aex file is not found.

The benefit of this is minimal for small function library files. However, very large Xbasic function library files can take a noticeable amount of time to load and compile. By eliminating this step and loading an .aex file instead you will get a small performance boost.

 

UX Component - Client-side Date Format - PhoneGap Applications - When you render a UX component in a Web Application, the client-side date format is set at runtime based on the setting stored in the component. This value can be overwritten, however, by setting a special session variable (__protected__clientSideDateFormat) so that a user in the UK (for example) can set a preference for their client side date format as dd/MM/yyyy while a user in the USA can set their preference to MM/dd/yyyy.

PhoneGap applications are different in that when the app is launched it is loaded directly from the device (i.e. the component is not served up by the AA server). As a result, it is not possible to change the client-side date format at run-time when the component is loaded (since the component is not loaded by making a call to the server). Therefore, in a PhoneGap application that is designed for use in both the US (when the date format is MM/dd/yyyy) and the rest of the world (where the date format is likely dd/MM/yyyy) it is necessary for the user to be able to set their date format preference at run-time after the app has been loaded. This preference can then be persisted to local storage so that there is no need to set it again.

The {dialog.object}.setClientSideDateFormat() method can be used to set the client-side date format for the component (used, for example when formatting date fields in a list control). This method, however, will not set the date format used by date pickers.

In order to set the date format for a date picker, you must get a pointer to the control and then call the .setFormat() method. For example, assume you have a control called 'DOB'. To set the date format for this control's date picker:

var obj = {dialog.object}.fieldHelpers('DOB');

obj.setFormat('dd/MM/yyyy');

 

Bugs

Style Sheets - <Project Style> - Fixes for cases where the <Project Style> was set to a version 4 style (e.g. 'Alpha', or a style inherited from Alpha)

UX Component - File and Image Download Actions - The option to set the client-side filename for the downloaded file by calling a Javascript function was not implemented.

Component Builders - Property Grid - Fixed a number of issues with the Property Grid in the various component builders.

Xbasic - JSON_Generate() Function - The json_generate() function now encodes CRLFs as \r\n. Previously, these were encoded as \n.

Action Javascript - Email a Report - Fixed an issue when the method to send the report was 'Internal' (as opposed to Sparkpost or Mandrill).

Components - <ProjectStyle> - Fixed an issue where components were not getting the correct style sheet when the component style was set to <ProjectStyle>.

Desktop Applications - Network Optimize - Refreshing a shadow database would fail if the master database was on a mapped driive that pointed to a network share.

SQL Server Reporting Services - Fixed an issue when printing a SSRS report with many parameters.

Grid, UX, TabbedUI, PageLayout Components - Live Preview - <ProjectStyle> - When doing a Live Preview from a component builder, the style was not being published if it had been set to <ProjectStyle>.

UX Component - .UpdateTableRow() Method - Fixes an issue when using this method on a child List. The parent List was not getting marked as dirty.

Reports - International Characters - Improvements have been made in the way international characters in reports are rendered.

Web Applications - APIs - Fixed bug when publishing API - The host name in the <serviceName>.json file was getting hard coded to the Live Preview URL if you had done a live test of the API while developing the API subsequently to the last time you edited the API.

Grid Component - Advanced Search Control - Failed if the Grid was opened on an Ajax callback.

Grid Component - Arguments - Page Variables - The option to bind an argument to a Page Variable was missing.

 

Alpha Anywhere V4.5.5.0 - Build 5667-5254 16-FEB-2019

Bugs

Application Server - Fixed a race condition that could potentially lead to a server crash.

Control Panel - Fixed some issues that primarily affected Desktop applications.

 

Alpha Anywhere V4.5.4.9 - Build 5663-5253 14-FEB-2019

Videos

UX Component - List Control Setting the order and visibility of columns in a List Layout You can allows users to dynamically show/hide List columns at run-time and also to change the order in which the columns appear in the List by adding a List column show/hide button to a UX component.

In this video we show how a List column show/hide button can be added to a UX and we show how it can be used to change the columns in the List are run-time.

NOTE: In the video we show how an event is fired when the List layout is changed. This event is defined in the List builder - onListColumnSelectorChanged event.

Watch Video

Date added: 2018-02-13

 

 

Features

UX Component - List Control - Column Show/Hide and Re-order - The List columns show/hide feature has been enhanced and you can now also control the order in which the List columns are shown.

You can add a List column show/hide button to your UX by selecting the List column show/hide control in the Defined Controls section in the UX builder.

When you click on the button at run-time you will see a drop-down menu (as shown in the image below). To turn a column's visibility on/off, click on the checkbox. To change the order of a column, drag on the hamburger icon and drop the column at the desired position.

When the user makes a selection in the show/hide menu, a client-side event in the List is fired (onListColumnSelectorChanged). This event could be used to persist the state of the List.

Grid Component - Search Part - Initial Value for Date Fields - Client-side Date Format - In some cases you may have a Grid that is running on a server that uses US Regional Settings (for example, Alpha Cloud). In your Grid you may have defined the client-side date format to use a dd/MM/yyyy format.

In order to set the initial value in a search field to today's date (honoring the client-side date format defined in the Grid) you can now use the {grid.clientSideDateFormat} placeholder in your initial value expression.

For example

=time("{grid.clientSideDateFormat}",date())

 

 

 

Bugs

Reports - Memory Leak - Fixed a memory leak in freeform report that had an embedded bitmap as the report background.

Control Panel - Maximize - Fixes focus problems when the Control Panel is maximized.

 

HTML5 Input Range Control - Panel Cards - iOS Devices - The HTML5 Range control implements a slider. On iOS devices, if the control is inside a Panel Card, the slider could not be moved by dragging on it. This is now supported.

If you do have a Range input control in the Panel Card, it is recommended (but it is not strictly necessary) that you wrap the Range control inside a DIV and then add this code to the onRenderComplete client-side event:

 

This will improve the user experience when dragging on the Range control's slider.

 

var ele = {dialog.object}.getPointer('DIV_1'); //DIV_1 is the id of the enclosing DIV.

A5.u.drag.add(ele,'prevent');
 

 

 

Alpha Anywhere V4.5.4.8 - Build 5647-5251 09-FEB-2019

Bugs

UX Component - List Builder - Fixed a bug in the Property Grid when editing column properties. This bug was introduced in build 5644.

Layout Table Reports - Fixed an issue with rendering HTML reports in a pop-up window or Tabbed UI pane. This bug was introduced in build 5644.

 

Alpha Anywhere V4.5.4.8 - Build 5644-5250 07-FEB-2019

 

 

Hotfix - List Control Builder - Fixes a problem in the Property Grid for editing column properties in a Columnar Layout.

Hotfix - Layout Table Reports - Rendered as HTML in a window or Tabbed UI Pane - Report content was not displayed.

 

How to install a hotfix

 

 

UX Component - Pinch to Zoom - A new property has been added to Panel Cards to allow you turn on support for the pinch gesture to zoom the size of a Panel's contents.

 

 

UX Component Builder and TabbedUI Builder - Security Groups - When working with large components, it can be difficult to get a good overview of which controls has security settings. A new option allows you to get a quick overview of the security settings for all controls in a component.

 

To open the Bulk Security Settings dialog, click the lock icon on the toolbar above the control list. This will open the dialog as shown below.

The dialog can operate in two different modes. When you open the dialog the mode you last selected is automatically selected. In Control mode (shown in the second image below) you can see what security groups have been assigned to the selected control. You can change the security groups for the selected control and you can set security groups for multiple controls at once by multi-selecting controls in the left hand list.

 In Security Group mode you can see all of the controls that have the selected security group(s).  For example, in the mage below you can see that only the 4th control (a button) has Administrators in its security groups. You can multi-select Security Groups in the left hand list to see all controls that have all of the selected Security Groups. You can also set security groups for the controls that you select in the right hand list.

 

Bulk Security Dialog in Security Group Mode

 

Bulk Security Dialog in Control Mode

 

UX Component - List Control - Action Javascript - List Control Actions - Refresh Data Action - You can now specify that when you refresh data in a List any server-side order and filter expressions that were applied by the user should be retained. To set this option, check the Preserve current filter/order property. If this property is not checked, then when the List data are refreshed, if the user has applied a server-side filter and/or order to the List, the filter and order are removed.

 

 

UX Component - Panel Navigator - onBeforeRemove Event - If a Panel Navigator is configured to use a TabBand to change the active Panel, a new Javascript event is available. The onBeforeRemove event will fire before a Panel is removed. Dynamic Panels can be removed from a Panel Navigator when the user taps on the close button in the Tab for the Panel. Panels can also be removed programmatically using the {dialog.object}.panelRemove() method. If the onBeforeRemove does not return true, the Panel is not removed.

 

 

NOTE: Your Javascript code can reference arguments[0] to get an object with information about Panel being removed.

 

UX Component - Javascript - {dialog.object}.panelRemove() Method - Allows you to remove a Panel from a Panel Navigator. You can either specify the Panel name or title. For Dynamic Panels, it is likely that you will only know the title and not the name.

Syntax:

{dialog.object}.panelRemove(panelNavigatorName, panel, type)

 

Where:

UX Component - List, ControlBar, ViewBox and FormView Builder - Javascript Functions - You can now import and export functions defined at the object level.

UX Component - ActionSheet - Events - The events now wait till the Action Sheet is closed before firing.

Bugs

Desktop Applications - Browse - Toolbar and Menus - In some circumstances when you opened a Browse window, the correct menu and toolbar was not shown until you first gave focus to some other window and then returned to the Browse window.

UX Component - List Control - Kanban Layout - User Defined Edits to Kanban CSS - User edits to the system generated Kanban CSS were getting overwritten when the List definition was saved.

 

UX List with Detail View - Media Files - Errors Uploading Media Files  - If you have a List with a Detail View and the List has media files (pictures, audios, etc), then when you sync the List, in normal operation the media files get uploaded first and then once all media files are uploaded, the data is synced. If there were any errors while uploading the media files, the rows in the List that contained the media files with errors should not have been synced. These rows should have remained dirty so that on the next sync attempt, a second attempt would be made to upload the images.

 

 

 

 

Alpha Anywhere V4.5.4.8 - Build 5581-5237 10-JAN-2019

Web Component Builders - Property Grid - Hover Style - You can now specify that when the mouse is over a property in a Property Grid that a hover style should be shown. For example, in the image below, the mouse is over the Height property and therefore, the row is displayed using the hover style.

 

 

 

To turn on the hover style select View, Settings from the menu and navigate to the Preferences, Propgrid section. You can also customize all aspects of the Propgrid appearance, by setting the Propgrid style to custom. This allows you to define a custom "CSS like" stylesheet which can be stored in a file called propgrid.style in the Alpha Anywhere executable folder. Sample syntax for the propgrid.style file can be found in the sample_propgrid.style file (also in the Alpha Anywhere executable folder).

 

UX Component - List Control - Columnar Layout - Hide Columns - You can now set the initial state of a column to hidden. The user can subsequently show the column if your UX component contains a Show/HideList Columns  control (see below for more information).

 

 

UX Component - ControlBar - Pre-defined Button Builder - When you add a new button item to a ControlBar, the Pre-defined Buttons genie now allows you to create Docked Panel Controller buttons.

 

 

UX Component - List Control - Show/Hide List Columns - You can now control the visibility of columns in a List control.

 

For example, in the image below, a column selector is shown. You can toggle the visibility of any column by clicking on the column name in the menu that is shown when the column selector button is clicked.

 

 

To add a List Column Selector button to a UX, select the List columns show/hide item from the Defined Controls section of the UX Builder toolbox.

 

 

UX Component - Javascript Library - .listColumnSelector() Method - A new method has been added to the UX component's Javascript library. The {dialog.object}.listColumnSelector() method displays a pick-list of all columns in the currently active columnar List layout (a List can have multiple Layouts some of which are columnar, others might be freeform or Kanban). By clicking on the items in the pick-list you can toggle the visibility of columns in the List layout.

Syntax

{dialog.object}.listColumnSelector(ele,listName [, maxHeight]);

 

Where:

 

UX Component - List Control - Word-wrap - A new option is available when you turn on word-wrapping for columns in a List control. The break-word option will allow long words that do not have spaces to be broken. By default if you have a long word with no spaces (i.e. there is no break point in the word), the word is truncated and ellipsis are displayed at the truncation point.

 

 

Web Components - Backups - When you edit a component (i.e. Grid, UX, etc.) a backup copy is automatically made. The folder where the backups are stored can become quite large over time. You can now specify that backups that are more than a certain number of days old should be purged. When purging old backups you can also specify the maximum number of backups to retain and the minimum number of backups to retain.

 

 

Xbasic Functions - Return Value - You can now use the RETURN keyword to indicate the return value of a function. For example:

 

function f1 as c ()

 return "some value"

end function

 

Previously the function would have to be defined as:

 

function f1 as c ()

f1 =  "some value"

end function

 

Both styles are now supported.

 

Xbasic -  ENDIF Statement - You can now use ENDIF in addition to the END IF statement.

 

UX Component - TransForm Data Viewer Control - Data Groups - You can now add and delete items in the form data when using the TransForm Data Viewer Control.

NOTE: When you add or delete a group, the data are immediately saved.

 

 

UX and Grid Components - Action Javascript - Convert to Javascript Action - You can now convert actions in an Action Javascript to a Javascript Action.

For example, here is the onClick event handler for a button (notice that the event has 3 separate Actions and no Javascript Actions are defined):

 

 

And here is the onClick event handler after the first two actions are converted to a Javascript Action:

 

 

convert_color_name_to_hex() Function - Converts a color name to a hex value. To get a list of all supported color names, call the function specifying the name argument as <showcolors>.

UX and Grid - Switch Year for 2 Digit Dates - The default switch year for 2 digit dates has been changed from 20 to 30. This means that a date value of 12/25/22 is now considered to be 12/25/2022 rather than 12/25/1922. You can specify a different default value for the switch year in Project Properties.

 

OpenSSL - Alpha Anywhere is now built using OpenSSL version 1.0.2q

 

AlphaDAO - MySQL - utf8mb4 (and not utf8) is now the character set for the MySQL and MariaDB drivers. MySQLV4 – used for older versions of MySQL is unchanged.


 
cn.tostring("SELECT * FROM performance_schema.session_variables WHERE VARIABLE_NAME IN ('character_set_client', 'character_set_connection','character_set_results', 'collation_connection') ORDER BY VARIABLE_NAME;")


 
= character_set_client             utf8mb4
character_set_connection           utf8mb4
character_set_results              utf8mb4
collation_connection               utf8mb4_general_ci
 

Property Grid - Grid lines - The new property grid that was introduced in a recent build now displays horizontal and vertical grid lines (like the old property grid did). You can customize the color of the grid lines by selecting View, Settings from the menu and navigating to Preferences, PropertyGrid.

 

Bugs

UX Component - Signature and Ink Controls - Touch Enabled Screens and Browsers - On a touch enabled screen, when using a touch enabled browser (such as Chrome) you could only draw on the control using the mouse. Now you can also use a finger or stylus.

Lookup Grids - Fixed a Javascript error for nested Lookup Grids.

Application Server for IIS - Fixed an issue with the Context.Session.SetSqlCredentials() method. Fixed an issue with setting active language, client side decimal character and client side thousands separator character using __protected__ session variables.

 

Xbasic Script_schedule() function - Under some circumstances, this function failed to execute the target script.

Grid Component - Arguments - If you specified that an argument should be set the the id of the current logged in user, or to data from the Extended User Information table, the argument value was not getting set correctly on the initial Grid load.

Advanced Search Control - Daterangepicker Control -  If you used a 'daterangepicker' control in the Advanced Search control, the option to set the filter type (e.g. 'Starts with', 'Ends with', 'QBF syntax') is now suppressed and the 'QBF syntax' option (which is the only relevant option) is now assumed.

AlphaCloud - Publishing - After publishing to AlphaCloud, Windows Explorer was opened showing content of the temporary CloudLocal folder.

UX Component - List Control - Client side conditional style - Fixed bug in Javascript expression validation.

 

 

 

Alpha Anywhere V4.5.4.7 - Build 5487-5217 27-NOV-2018

Hotfix - List Control - Client-side conditional style - Javascript expression validation, Style Builder - copying a style, Grid - setting an argument to current logged in user id.

 

Hotfix - Under some circumstances, a UX component built with an older version of AA will not run. This hotfix fixes this issue. The hotfix must be applied to both the IDE (developer version) and also the Server. The circumstance under which this issue occurs is as follows: If a UX component uses the 'Alpha' style and it has not been edited using build 5487 (i.e. the component was built using an older build) and if the UX has one or more controls that have security settings or server-side show hide expressions, and if the UX is not pre-rendered, the error will occur. If the UX is pre-rendered and the 'Apply security and server-side show/hide expressions client-side' is checked, the issue will not occur.

 

Hotfix - Under some circumstances when running a Grid for which arguments have been defined you will get an error: Script:A5_ArgGetValue() line:61 Variable "flagInquery" not found.

 

How to install a hotfix

 

 

Features

Component - Editing Styles - Inherited Styles - When you try to open an inherited style in the style builder (e.g. 'Alpha-Rose'), you now have the option of creating a 'detached' version of the style (i.e. a style that is no longer inherited from its base style). The advantage of creating a detached copy of that you can then use the style builder to modify all aspects of the style. If you edit an inherited style in the style builder you can only add new sub-themes. You cannot edit all aspects of the style.

 

UX Component - List Control - Client-side Group Breaks - Javascript - You can now automatically collapse or expand all or selected groups in a List.

You can select which groups to collapse or expand using a function.

If your List contains multiple level of grouping you can collapse/expand groups at a particular level

Syntax

<listObj>.setGroupCollapse( groupSelectionObject, flagCollapse, flagAnimation)

 

where

 

 

Examples

var lObj = {dialog.object}.getControl('list1')

lObj.setGroupCollapse({groups: 'all'},true,false); // collapse all groups without animation
lObj.setGroupCollapse({groups: 'all'},false,true); // expand all groups with animation
 

Assume list has two levels of grouping - 'Country' and 'City'

lObj.setGroupCollapse({groups: 'level', level: 0},false,true); // expand all "country" groups with animation

lObj.setGroupCollapse({groups: 'level', level: 1},true,false); //collapse all "city" groups without animation



Setting certain groups to be collapsed:


lObj.setGroupCollapse({groups: 'match', match:
    function(groupName,groupData){
        if(groupName.match(/^[A-z]/)) return true; // match any group with a name starting with a character
        return false;
    }},true); // collapse all groups that the passed in function returns true for
 

 

UX Component - TransForm - TransForm FormDataView Control - A new control type can be added to the UX component. The TransForm FormDataView control allows you to display the data in a TransForm form using a control that looks the same as the manner in which form data is displayed in the TransForm Central Management Console. You can also edit data in the form with the TransForm FormDataView control.

To add a TransForm FormDataView control to a UX, select the [More..] item in the Data Controls section.

 

 

Then select the TransFormDataViewer control.

 

Click the smart field for the Custom Control properties to configure the control. The configuration dialog is shown below.

 

 

The TransForm FormDataView must be populated with both the form data to display and also the form definition for the form you are displaying. You can specify where this data should come from. The choices are

The TransForm FormDataView control exposes a number of methods. Information about these methods can be obtained by clicking the hyperlink in TransForm FormDataView configuration dialog (shown in the above image).

 

Web Applications - Xbasic and Javascript Editors - When editing Xbasic files (function libraries, modules, scripts) or Javascript files, the editor toolbar has a new button that opens a selector window allowing you to quickly switch between open editors, create a new file, or open an existing file, without having to first return to the Web Control Panel

Bugs

HTML Reports - Fixed an issue that prevented HTML reports from printing.

Internet Explorer - Fixed some issues with running components using IE.

Internet Explorer - Fixed issue with certain controls (such as date picker) not working when using IE

Web Applications - Style Builder - The Style Builder would give an error when trying to edit a style that was inherited from the 'Alpha' style (e.g. 'Alpha-Green')

UX Component - List Control - Condition Style - Logical Javascript expressions that used the || operator did not work. Logical Javascript expressions that used a property of a field (e.g. data.Country.length > 10) were being incorrectly flagged as invalid.

UX Components - List Controls - SQL Data Source - Fixes a problem that was introduced in build 5445 with paginated Lists based on SQL data sources

SSRS Reports - Fixes a problem with SSRS reports not rendering.

iOS Scrolling - Fixes a problem with scrolling on iOS devices.

 

Alpha Anywhere V4.5.4.6 - Build 5447-5206 08-NOV-2018

Hotfix - Web Style Builder - Editing an Inherited Style

Hotfix - Action Javascript - Menus - Menus with security settings

 

How to install a hotfix

Bugs

UX Components - List Controls - SQL Data Source - Fixes a problem that was introduced in build 5445 with paginated Lists based on SQL data sources

SSRS Reports - Fixes a problem with SSRS reports not rendering.

iOS Scrolling - Fixes a problem with scrolling on iOS devices.

 

Alpha Anywhere V4.5.4.6 - Build 5445-5205 07-NOV-2018

 

Videos

UX Component - List Control Consuming Complex (Hierarchical) JSON Data in a List The JSON data you display in a List control may contain nested arrays of data. In this video we show two different ways in which the nested arrays of data can be displayed.


Watch Video

Download files

Date added: 2018-07-30
UX Component Understanding the screen.height Property When setting the height of a container you cannot use percentages. However, you use the special screen.height variable to represent 100% of the available height.

In this video we show how a container's height can be set using the screen.height property.

Watch Video

Date added: 2018-07-30
UX Component Ad-hoc SQL Query Builder This video shows a sample UX component that allows users to perform ad hoc SQL Select queries against any table in a database. The results can be viewed in a tabular format or exported to Excel.

Watch Video

Date added: 2018-08-03
UX Component - ExpandingMenu Control Dynamically Populating an Expanding Menu with Ajax Callbacks This video shows how you can dynamically populate an Expanding Menu control with data computed in an Ajax callback.


Watch Video - Part 1
Watch Video - Part 2

Download files

Date added: 2018-08-09
UX Component Displaying an "Action Sheet" A common user-interface technique in iOS applications is an Action Sheet - a popup menu with a series of options. In this video we show how easy it is to add an Action Sheet style menu to a UX component.

Watch Video

Date added: 2018-08-29
UX Component - Advanced Search Control Using the AdvancedListSearch Control to Search in a List Based on SQL Database For UX Components that contain List controls that are based on SQL databases,  the Advanced Search control exposes powerful features for users to search for specific records in a List. The Advanced Search Control allows users to define complex queries and to save these queries to a repository for future reuse.

In this video we show how the Advanced Search Control is added to a UX component and how it is configured.

Watch Video - Part 1
Watch Video - Part 2

Date added: 2018-09-08
Grid Component - Advanced Search Control Adding an Advanced Search Control to a Grid Component The Advanced Search Control provides an alternative to the Grid Search Part for enabling users to search for data in a Grid. The Advanced Search Control has advantages over the Grid Search Part in that it allows the user to search on all of the fields in the Grid, not just the fields selected for the Search Part.

In this video we show how the Advanced Search Part is added to a Grid component and how it is configured.

P.S. You may find it  helpful to watch the videos for using the Advanced Search Control in a UX component before watching the videos on using the Advanced Search Control in a Grid.

Using the Advanced Search Control in a Grid
Watch Video - Part 1
Watch Video - Part 2

Using the Advanced Search Control in a UX Component
Watch Video - Part 1
Watch Video - Part 2

Date added: 2018-09-08
UX Component - Transient Messages Displaying Transient Messages A common design pattern in Web and Mobile application is to display "transient" messages to the user. The messages typically confirm that an action was done or display progress to the user. The GMail web application, and also the GMail mobile applications make extensive use of transient messages.

In this video we show how you can easily add transient messages to the UX component using Action Javascript (transient messages are also available in the Grid component).

Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

Date added: 2018-09-21
UX Component - Kanban Layout Introduction to Kanban List Layouts Kanban Lists display data organized by category. Users can move List rows from one category to another using drag and drop. Users can also re-order the data within a category using drag and drop.

In this video we show a List control with both a columnar and a Kanban layout.

Watch Video
Download files

Date added: 2018-10-03
UX Component - Kanban Layout Creating a List with a Kanban Layout In this video we show how a Kanban layout can be defined for a List.

Watch Video - Part 1
Watch Video - Part 2

Download files

Date added: 2018-10-03
UX- Component - Kanban Layout Adding Color Coding and Summary Values to a Kanban Layout In this video we show some advanced features of a Kanban layout. We show how you can add color coding to the layout (so that List rows in different categories are colored differently and how you can summary data to each category.

Watch Video - Part 1
Watch Video - Part 2

Download files

Date added: 2018-10-03
UX Component Persisting Edit in a Kanban List to a SQL Database In this video we show how a Kanban List can be based on a SQL database and how edits to the List can be saved in the database.

Watch Video - Part 1
Watch Video - Part 2

Download files

Date added: 2018-10-03
UX Component - List Control Responsive Columns In this video we show how to make a responsive List control where columns in the List are automatically hidden when the List width falls below a specified value.

Watch Video

Download files

Date added: 2018-10-17
UX Component - List Control Horizontal Scrolling When a List has a large number of columns, you may prefer to enable horizontal scrolling for the List rather than trying to dynamically adjust the width of each List column so that all columns are visible.

Watch Video

Date added: 2018-10-17
AlphaDAO - Multi-tenant Applications How to Create a Multi-tenant Connection String When you build multi-tenant SASS applications that use a shared database, each table in the database must  have a tenant id field and all of your SQL queries must include the tenent Id. When you use a multi-tenant connection string, the tenant id is automatically injected into all SQL statements before the statement is sent to the database. This makes it easier to build multi-tenant SASS applications, or to convert an existing application to a multi-tenant application because you do not have to manually adjust all of your SQL statements.

In this video we show how a multi-tenant connection string is defined and then we show the results when a SQL SELECT and INSERT statement are executed.

Watch Video - Part1
Watch Video - Part2
Watch Video - Behind the scenes


Date added: 2018-10-21
UX Component Defining Manifest for On-Device Data When you build PhoneGap applications for offline usage, you may want to store files on a mobile device so that these files can be accessed when the device is offline. The UX builder has an action in Action Javascript that allows you to download all of the files defined in a 'manifest'. This video shows how this manifest can be created.

Watch Video - Part1
Watch Video - Part2

Date added: 2018-10-27
Xbasic Audit-trail Driver This video shows how you can create a custom AlphaDAO connection string to create an audit trail every time a CRUD operation is performed.


Watch Video - Part1
Watch Video - Part2

Date added: 2018-10-28
UX Component - List Control Page Navigation Bar In a Grid component you can add a Navigation Bar to allow the user to navigate from one 'page' or records to another. In a List control (that is based on a SQL database, has pagination tuned on and has the pagination method set to Navigation Buttons), you can also add a Navigation Bar to allow the user to navigate from one 'page' or records to another.

In this video we show how to configure a List control to display a Navigation Bar.

Watch Video

Date added: 2018-11-05
     



Breaking Changes

 

File/Image Upload - UX and Grid Component - A change was made to this action to disable the Upload button while the file upload is in progress. As a result of this change it may be necessary (in some cases it was not necessary - depends on when the Action was last edited) to edit and resave the file and image upload actions in Action Javascript in order to re-generate the Javascript code for the function.

Features

REST Services - Calling - Xbasic Proxy - REST services are called from Xbasic by making an HTTP request. Typically, HTTP requests are made from Xbasic using one of the built-in http functions (e.g. http_get(), http_post(), http_fetch(), etc.), or by using the Xbasic CURL object.

Now, a new way of calling REST APIs from Xbasic is available.

You can now create an Xbasic proxy class and then call methods on this proxy class. The methods on the Xbasic proxy class correspond to the various API endpoints exposed by the service.

In order to create the Xbasic proxy for the REST service, you can supply the Swagger definition for the service, or you can select one of the pre-configured Google services (of which there are many) or you can generate a definition from a CURL command.

The following example will make it easier to understand what an Xbasic REST proxy is. In this example we will:

 

1. Create the Xbasic Class with a Method Called getCustomer

 

define class reasapi::class1

    function getCustomer as p (customerid as c )

        dim cn as sql::Connection

        cn.open("::Name::northwind")

        dim args as sql::arguments

        args.add("id",customerid)

        dim sql as c

        sql = "select * from customers where customerid = :id"

        dim flag as l

        flag = cn.Execute(sql,args)

        dim json as c

        json = cn.ResultSet.tojson()

        getCustomer = json_parse(json)

    end function

end class

 

2. Create a REST Service to Expose the getCustomer Method

 

The REST API service is called myservice. To create a new REST service, select the Web Services category in the Web Control Panel , then click the New button and select Create a new definition to create a REST service button.

 

 

Next, get the Swagger definition for the service. Click the Swagger definition button at the bottom left of the API Service Builder dialog.

 

Copy the Swagger definition to the clipboard. You will need it for the next step when the Xbasic Proxy is created.

Also, click the Live Test the API button. This will publish the REST Service to the LivePreview folder in the webroot of the Development Server.

When you Live Test the API, the browser will open and show a page for testing the API. Make a note of the URL shown in the browser address bar - You will need this address when you define the Xbasic Proxy. The URL should look something like this:

 

http://127.0.0.1:10444/LivePreview/__a5_system/swagger/index.html?url=/livepreview/myservice.a5svc/api-docs

 

The parts of the URL that we care about are highlighted in red. Taking the parts that are highlighted, we can construct the URL for your web service:

http::localhost:10444/livepreview/myservice.a5svc

This is the URL where your Web Service has been published.

 

3. Make an Xbasic Proxy For This Service

To make an Xbasic Proxy for your web service, select the Web Services item in the Web Control Panel, then click the New button at top left of the Web Control Panel.

Select the Create a new definition to consume a REST service button.

 

 

This will then bring up a dialog where you can name your Xbasic proxy.

Enter any name you want (for example, myxbasicproxy1) and then click the Import Swagger... hyperlink.

 

A dialog will open where you can paste in the Swagger definition for your service. (Recall that in an earlier step where you defined the service, you clicked the Swagger definition button to see the definition for your service and you copied this definition to the clipboard).

 

 

Paste in the JSON for your Swagger definition and then click the OK button.

 

A new dialog will be shown where you can configure the Xbasic proxy.

The dialog has a prompt for the Resource URL. This is the address of the service your Xbasic proxy will be accessing.

Paste in the URL that you constructed in a previous step. It should look something like (your URL will be different if you are running the server on a different port, or you gave your service a different name).

http::localhost:10444/livepreview/myservice.a5svc

 

Click the Save button to save your Xbasic proxy.

 

4. Use the Xbasic Proxy to Call the Service Endpoint

Next we want to use this Xbasic proxy to call your service. We will use another Genie that helps construct the Xbasic code for using the proxy.

We will create an Xbasic script to test the Xbasic code that uses the Xbasic proxy. To create a new Xbasic Script, select the Xbasic category in the Web Control Panel, then click the New button.  Then click the Create a new Xbasic Script button.

 

An editor will open where you can enter Xbasic code to test.

Right click on white space in the editor and select REST Reference Call from the Genies.. menu item.

 

 

 

The next window shows all of the Xbasic REST proxies that you have defined as well as some built-in proxies. Select the Xbasic proxy that you defined. This proxy only has a single method (getCustomer), but if the service that you are proxying had more than one method, you would then select which method you wanted to call.

The bottom part of the dialog shows the Xbasic code to use the proxy.

 

 

Click the OK button to insert the code into your Xbasic Script. Before you can run the code you will need to specify which Customer's information you want to retrieve. Set the args.customerid variable to some value as shown below.

 

 

dim obj as RESTReferences::myxbasicproxy1
dim args as p
dim args.customerid as c = "Bolid"

dim result as l = obj.getCustomer(args)

if result then
showvar( obj.result )
else
ui_msg_box("error",obj.error)
end if
 

 

Now click the lightening bolt icon on the toolbar to run your code.

You should see a window pop up with the result of the API call.

 

 

 

UX Component - List Control - Conditional Row Style - Syntax - You can now specify that the logical expressions in a conditional row style definition should be Javascript, rather than an intermediate syntax that gets converted to Javascript.

 

 

UX Component - List Control - Fields - Conditional Style - Client-side - You can now define client-side conditional styles for fields in a List control. You can define a conditional style for the field itself and also for the cell in which the field is rendered (columnar layout only).

 

The image below shows a List with:

 

 

To define conditional field and cell styles, set the Conditional style and Conditional cell style properties in the List builder, Fields tab as shown in the image below.

 

 

To define a conditional row style, set the Client-side computation property in the Conditional Row Style section of the property grid on the List Properties pane.

 

 

Xbasic - FTP - FTP over SSL and FTP over SSH - Two new .Net classes have been exposed to allows FTP over SSL and FTP over SSH.

You can read more about these classes in the documentation.

FTP over SSL

FTP over SSH

 

 

UX Component - Button List Control - Select Button - You can now use the Enter or Spacebar key to select a button in a Button List. The button that has focus is selected.

NOTE: Some styles (such as 'Alpha' and styles inherited from 'Alpha') do not currently indicate which button in a Button List has focus.

 

UX Component - Action Javascript - Dropdown Menu Action - Window Size - When you use Action Javascript to define a dropdown menu you can now specify a height and width for the dropdown window.

 

 

 

UX Component - List Control - SQL Data Source - Paginated - Navigation Bar - You can now automatically add a Record Navigation Bar to List controls that are based on a SQL data source and have pagination turned on (with the Pagination method set to NavigationButtons).

Watch Video

 

The image below shows a List with a Navigation Bar. The Navigation bar has been configured to show an input control for the current page number. The user can enter a target page number into the input control and press Enter to navigate directly to the target page. The Navigation Bar also shows a 'records per page' selector so the user can dynamically change the number of records per page.

The number of target buttons before and after the current page number can be configured. In the image below, the Navigation Bar has been configured to show a total of 6 target buttons.

In the image below, the Navigation Bar does not show a 'records per page' selector. The current page number is shown using a disabled button (rather than an input control as shown in the above example) and there are no target buttons before or after the current page number.

Also, the Navigation Bar has been configured to display in the List itself (in the List Footer section). In the above example, the Navigation Bar display outside the List at a location specified by a placeholder DIV in the UX component.

 

 

If you are using a 'version 4' style (e.g. 'Alpha', or any style inherited from 'Alpha', such as 'Alpha-Rose') you can choose a compact style for the Navigation Bar buttons, as shown in the image below.

 

 

To turn on the Navigation Bar, check the Has Navigation Bar property in the List Builder on the Data Source pane.

 

To configure the Navigation Bar, click the Navigation Bar settings smart field.

This will open the builder where you can set properties for the Navigation Bar.

 

 

 

UX Component - List Control - SQL Data Source - Server-side Column Sorting - You can now turn on server-side column sorting for all of the columns in List by checking the new Server-side sorting property. Previously, you had to go to each column in the List layout to turn on server-side column sorting for that particular column.

 

 

 

 

Web Control Panel - Xbasic Scripts - You can now create Xbasic Scripts from the Web Control Panel. The sole purpose of Xbasic Scripts is to allow you to develop and test Xbasic code from within the Alpha Anywhere IDE. Xbasic scripts are not published when you publish your application and are not intended to be used at run-time.

To create a new Xbasic Script, select the Xbasic category in the Web Control Panel, then click the New button.

Click the Create a new Xbasic Script button.

Enter the code you want to test and then click the lightening bolt on the toolbar to execute the code.

 

 

Xbasic - word_unique_c() function - A case-sensitive variant of the word_unique() function is now available.

Example

dim txt as c

txt = comma_to_clf("NO,no,NO")

?word_unique_c(txt,crlf())

= NO

no

 

Web Applications - Stylesheets - Alpha Theme - The Alpha style sheet has been enhanced. New sub-themes are available for buttons, button lists, and lists.

Many of the sub-themes can use a 'pulse' effect (inspired by Google Material Design). The pulse effect can be turned on/off using the Show 'pulse' effect property.

 

 

The list of available sub-themes for a button is shown below:

 

 

The image below shows the appearance for some of the new button sub-themes.

 

 

The 'pulse' effect is available for ButtonList, Switch and List controls.

For the 'Alpha' style you can turn the 'pulse' effect on or off by setting the Show 'pulse' effect property.

TIP: You can turn the 'pulse' effect on for just a portion of a component by enclosing that portion in a container and setting the container class to 'pulse'.

 

 

 

AlphaDAO - Custom Connection String - Audit Trail Driver - A new sample driver is available when you create a new connection string and select the Custom option. This driver automatically updates an audit table when CRUD operations are executed.

NOTE: Contrast the Audit-trail driver with the built-in Audit Trail feature which is turned on by going to the Web Project Settings dialog. The built-in feature does not require a special connection string, can automatically create the audit-trail table and is therefore easier to set up. The image below shows the relevant section of the Project Properties dialog where you can turn on the built-in audit trail feature.



 

A sample Xbasic class that implements an audit-trail driver can be selected when you define a Custom connection string.

The Audit driver is a "pass-through" driver (i.e. SQL commands are passed through to the base SQL connection) but a new record is added to the audit table for each successfully executed CRUD statement.

Watch Video - Part1
Watch Video - Part2

 

When you create an audit driver you must specify these properties in the connection string definition dialog:

 

 

The audit table must have this structure (the actual field names can be different as the connection string builder allows you to map the actual field names) :

 

PhoneGap and TransForm Applications - On-Device-Data Genie - When you build TransForm applications, or regular Alpha Anywhere mobile applications (that use PhoneGap), you may want to store data (SQLite databases, images, movies, audio files, PDF files, etc.) on the mobile device so that the files can be accessed when there is no internet connection.

Watch Video - Part1
Watch Video - Part2

 

In Alpha Anywhere applications you can use Action Javascript / PhoneGap Manifest actions to define an action that downloads all of the files specified in a special manifest.

In TransForm applications you can go to TransForm Central to specify the manifest URL for On-device-data (Note: This feature may not yet be turned on for your TransForm account at this time).

The new On-Device-Data Builder makes it easy to define the manifest and to upload the manifest files to an Amazon S3 bucket from where they can be downloaded to a mobile device.

To open the On-Device-Data Builder select the Tools/More.../On-device-data builder for TransForm/PhoneGap applications... menu item.

 

 

This will then open the builder, as shown in the image below.

 

 

The builder allows you to specify the data (i.e. files) you want to store on the mobile device. The builder allows you to define multiple item types of data.  The available types are:

For each item, you can also specify an optional version number. This is used by the Javascript method that downloads the manifest files to the device to determine if a file specified in the manifest must be downloaded. If a file has been previously downloaded it will not be downloaded again if its version number does not exceed the previous version number.

 

After you have defined all of the items in your manifest, you can save your definition by clicking the Save button. The settings are saved in a file in the Web Projects folder. You can then click the Generate manifest files button. This button will create the SQLite database files (if you specified that the SQLite database file should be created by executing queries) and it will create the necessary zip files (for example, for the Folder item type, all of the specified files are zipped into a single zip file).

Once the manifest files have been created, you can then upload them to Amazon S3. Click the Upload manifest files to S3 button to upload the manifest files. A manifest file will also be created and uploaded to S3. The manifest is a JSON file that describes each file in the manifest. The URL for this manifest file is used in your Action Javascript when you define an action to Fetch manifest files. For TransForm users, the URL for this manifest must be specified when you define the on device data for your account in TransForm Central.

After the manifest files are uploaded you can click the Show manifest URL/JSON to see the manifest URL and the actual JSON data in the manifest.

Before you can upload manifest files to S3 you must first click the Define S3 Properties hyperlink to define properties of the S3 bucket where your manifest files will be uploaded. You must specify the storage connection string that points to your S3 bucket (go to Tools, Storage connection strings when the Web Control Panel has focus) and the folder within this bucker where the manifest files should be uploaded.

 

 

List Control - Right Click - If you right-click on a row in a List, the List's onRightClick event is fired, but the system right click menu is not shown. Now if you add code in the List's onRightClick event that does this:

return true

the system right-click menu will be shown.

UX Component - E-mail Address - Client-side validation - You can now perform a client-side validation of an email address. To do so, add the following code to the input control's Validation Javascript property:

 

var flag = A5.emailValid(data);

if(flag) {return true;} else {return 'Not valid email';}

 

NOTE: Validation is performed using the RFC 2822 standard regex expression.

 

Thanks to Max Hammond for this suggestion.

 

UX Component - Pre-render - File Size - The file size of pre-rendered components (the .a5wcmp file) has been substantially reduced. This is achieved by storing the pre-rendered component definition as base64 encoded, gzipped data.

 

UX Component - Edit-Combo - Open List on Focus - You can now configure an edit-combo to open the pick-list when the control gets focus. Previously the user had to tap the icon to open the pick-list.

 

 

 

iPhoneX PhoneGap Styling - One-click Styling - Styling a PhoneGap app for an iPhoneX device can be tricky because special consideration has to be given to the notch and the soft home button. Apple has introduced special directives that can be used in your CSS classes to automatically account for the notch on the device.

Alpha Anywhere now makes it very easy to apply all of the necessary CSS to a mobile app so that it will render correctly on all iPhones, including iPhoneX.

In order to configure your PhoneGap app so that it will display correctly on an iPhoneX device check the Apply iPhoneX PhoneGap styling property.

NOTE: If you check this property, your app will still display correctly on other iPhone devices.

 

 

You can then set additional properties for your app.

 

 

AlphaDAO - Multi-Tenant Driver - SASS Applications - You can now create a new type of connection string for multi-tenant applications.

Watch Video - Part1
Watch Video - Part2
Watch Video - Behind the scenes
 

When you create a multi-tenant SASS application (using any development platform, not specifically Alpha Anywhere), you can either give each tenant their own database, or you can use a shared database for all tenants.

Giving each tenant their own database will work well if you do not have a large number of tenants. However, if your application has a large number of tenants, the only practical approach is to have a single database for the application that all tenants share.

If you use a shared database, you will need to have a 'tenant id' field in each table so that the records in the table can be associated with the correct tenant. Every time your code executes a SQL CRUD statement, you will need to remember to include the tenant id field in the SQL statement.

The Multi-tenant driver is used in cases where you have a shared database for all of the tenants. The multi-tenant driver will automatically inject the tenant id field into the SQL so you do not have to remember to do it.

For example, assume you have defined a multi-tenant driver with these properties

 

 

Now, assume you execute the following SQL query:

SELECT * from Employees

 

The SQL statement that will be sent to the database will actually be (assuming that the value of session.mytenantid is 23) :

SELECT * from Employees WHERE tenantId = 23

 

In the case of an INSERT statement, the tenant Id will automatically be set to the value of the current tenant

For example,  your SQL statement:

INSERT into Employees (firstname, lastname) values (:fname, :lname)

 

will automatically be converted to:

INSERT into Employees (firstname, lastname, tenantid) values (:fname, :lname, 23)

 

If there are some tables in your multi-tenant SASS application that are shared by all tenants (i.e. the tables do not have a tenant ID field), then when you query these tables you will not use the multi-tenant connection string. Instead you will use the base connection string.

 

How to Create a Multi-tenant Connection String

 To create a Multi-tenant connection string, create a new connection string (from the Tools, AlphaDAO Connection Strings menu) and then when the Create SQL Connection String dialog appears, click the button for the Connection Type prompt

 

 

The Select an API dialog will appear. You can either select the MultiTenant option, or the Custom option. Select the Custom option if you want to customize the Xbasic class that implements the Multi-tenant driver.

 

 

If you select the MultiTenant option, the next dialog allows you to set the properties for your multi-tenant connection string.

 

The properties you must set are:

 

If you select the Custom option, you will get this dialog where you must specify the name of the Xbasic class that implements the custom driver. Click the Show Example.. hyperlink to get an example Xbasic class that implements a multi-tenant driver.

 

 

 

 

Then select the Xbasic class that you created from the examples and fill in the property sheet, as shown below.

 

 

UX Component - PhoneGap - You can now open the PhoneGap builder and build an Instant Update directly from the UX Builder toolbar. You no longer have to return the Web Control Panel.

 

UX Component - PhoneGap - Instant Update - AjaxURL - If you change the AjaxURL when you do an Instant Update, the next time you do an Instant Update, the URL that you set is now remembered.

 

Web Applications - Styles - 17 new styles are now available. All of these new styles are inherited from the base Alpha style. Because they are inherited styles, changes to the base Alpha style (such as the addition of new CSS classes and sub-themes) will be seen in each of these inherited styles.

 

 

UX Component - List Control - Horizontal Scrolling - By default, in a columnar List, the column widths for each column in the List are automatically adjusted so that all columns are visible. Column widths are automatically adjusted if a column specifies its width using the flex() option.

Watch Video

 

If a List has many columns, the adjusted width of each column might render the List in such a way that the data is not readable. For example see the image below:

 

If you enable horizontal scrolling, the column widths will not scale down below the specified minimum column width, and the List will scroll horizontally. See image below.

 

 

To enable horizontal scrolling, check the Horizontal scrolling property on the List Properties pane in the List. When you check this property you can specify the minimum and maximum column width. These settings are automatically applied to all List columns that use the flex() option (as long as the width settings does not specifically set a minimum or maximum width). For example, if a particular column sets its width to (say) flex(1,250px), then that column's width will not use the Minimum column width property (i.e. the minimum width for that column will be 250px regardless of the Minimum column width property value).

 

 

 

 

UX Component - List Control - Column Width - Flex - Minimum and Maximum Width - The width of each column in a List can be configured to adjust automatically based on the overall width of the List. This is done by setting the column width using the flex() syntax.

Now when you use the flex() syntax to specify a column width you can specify an optional minimum width and maximum width for the column. For example:

flex(1,150px) - the column width is 1 flex unit, but never less than 150px

flex(1,150px,300px) - the column width is 1 flex unit, but never less than 150px or more than 300px.

 

UX Component - List Control - Client-side Group Breaks/Kanban Lists - Collapsible - Expand/collapse using Javascript - If you have a Kanban List, or a List with client-side group breaks turned on and you have set a group break to be collapsible, you can now expand/collapse a group using Javascript.

 

Example:

var lObj = {dialog.object}.getControl('name_of_list_control');

var groupName = 'Argentina';

var mode = false //false == expand, true == collapse, '' == toggle

var showAnimation = true;

lObj.setGroupCollapse(groupName,mode,showAnimation)

 

 

UX Component - List Control - onResize Event - List controls now support an onResize event. This event fires when the List is resized. For example, if the List is inside a Panel Card and the List is set to fill the container, when the Panel Card is resized, the List's onResize event will fire.

 

UX Component - List Control - Responsive Columns - You can now show/hide columns in a columnar List layout based on the overall width of the List. For each column in the List you can specify a Responsive column property. This is a value in pixels. If a column's Responsive column setting is less than the List's width, the column will be hidden. If the List width is greater than the specified value, the column is shown.

Watch Video

The computation that determines which columns should be show/hidden is made when the List's onResize event.

The List onResize event will fire automatically if the List is inside a Panel Card and the List is set to fill the container. The event will fire when the Panel Card size changes.

 

 

 

AlphaDAO - Connection String Builder - SQL Server - Changes to the SQL Server connection string dialog and to the SQL Server connection string:
 
The connection string dialog now uses tabs to provide more options.

  1. The AdditionalParameters and InitialCommand connection properties are now fully supported in the connection string dialog.
  2. A new connection property TrustServerCertificate is now supported at connection and the dialog level for SQL Server.  This parameter can be set to true to allow a self-signed certificate to be used on SQL Server for testing.  The default value is false.
  3. A new connection property EnableColumnEncryption is now supported at the connection and the dialog level for SQL Server.  This parameter enables Always Encrypted for the connection.  The default value is false.
     

If TrustServerCertificate or EnableColumnEncryption is set to true in the dialog (the box is checked) and included in AdditionalParameters as well, the dialog value will supersede the hand coded value.


 

AlphaDAO - PostgresSQL - New PostgreSQL ODBC Driver (10.3) - The PostgreSQL ODBC client shipped with Alpha Anywhere and installed in SQLDatabases\ClientInstallers\PostgreSQL under the binary directory as psqlodbc_x86.msi has now been upgraded to version 10.3.
 
 

UX Component - List Control - Kanban Layout - Dynamically Adding Categories - You can add categories to a Kanban layout after it has been rendered using this Javascript:

 

var layoutName = 'Default'; //name of the Kanban layout

var newCategory = 'New Category';

var lObj = {dialog.object}.getControl('name_of_list_control');
lObj.layouts[layoutName].group.auto[0].groups.push(newCategory);

lObj.refresh()

 

UX Component - List Control - Client-side Group Breaks - Collapsible Groups - When defining a List control that has client-side group breaks, you can now specify that each group is collapsible. If you turn this feature on, the Group Header row will have an icon at the extreme right edge. If you tap the icon, the group is shown as collapsed (as shown in the image below for the group for Austria). Tapping on the icon for a collapsed group will expand the group.

The collapse/expand of each group is animated.

You can define event handlers for when the collapse or expand of a group has completed.

You can customize the icons used to collapse or expand a group.

 

 

UX Component - List Control - Kanban Layout - Collapsible Categories - When defining a Kanban layout, you can now specify that a category should be collapsible. When a category is collapsed, only the category header is shown. As a result, the category will be narrower and more categories can be rendered on each 'row' of categories.

 

 

 

Grid Component - Javascript Actions Editor - Easier Access - It is now easier to get to the Javascript Action editor. Simply click on the Javascript Actions item in the navigation tree at the left of the Grid builder.

 

 

UX Component - List Control - Kanban Layout - You can now configure List controls to display the List data in a Kanban layout.

A Kanban layout is useful if you have List data that can be grouped in categories and you want to be able to drag and drop a row from one category to another, or drag and drop a row with a category to change its order within the category.

Example of the types of data where a Kanban view could be useful include:

 

 

Watch Video - Part 1

Watch Video - Part 2

Watch Video - Part 3

Watch Video - Part 4

Watch Video - Part 5

Watch Video - Part 6

Watch Video - Part 7

 

 

In the image below, a Kanban layout is shown for sales pipeline data.

A List can have multiple Layouts. Any of the layout can be a Kanban layout. You can switch at any time from one layout (which might be columnar or freeform) to a Kanban layout.

 

 

 

In the image shown above each category has a group footer in which the total for the amount field in that category is shown. The user can click on the hamburger icon and drag the row to a new position within the category, or to a different category.

It is common that when you move a row, you will want to persist the data to a backend database. This is easily done by turning on the List's Detail View property and then putting a button on the UX to synchronize the List data.

To create a Kanban layout, set the Layout type to Kanban.

To configure the Kanban settings click the smart field for the Kanban settings property. This will open the Kanban Layout Setup Genie.

 

 

Properties of note in this dialog include:

Once you have defined the Kanban Layout properties, you will need to define the Kanban Layout. Defining the Kanban Layout is very similar to defining a Layout for a freeform List.

In the screenshot below the layout for the Kanban layout shown above is defined. The layout is an HTML template with placeholders for the data in each List row.

The {kanban:draghandle} placeholder is a special placeholder for the drag handle icon that displays in each row.

Note that the background color in the outer div has been set to: {@[scope].kanbancolor([root])}. This is the client-side templating syntax for calling a Javascript function. The value returned by the function will be used for the background color. See the documentation for client-side templating for more information on how to call Javascript functions in a template. Note that kanbancolor() is a special system generated function that will execute the code you defined in the Color Javascript property when you set the Kanban layout properties.

Note also that the list of placeholder at the left edge of the screen include the  {kanban:draghandle} placeholder.

 

 

 

When you are defining a new Kanban layout template, you can get a quick start by clicking on the Pre-defined Templates hyperlink. This will bring up a dialog (shown below) where you can select different sample layout templates.

 

 

 

 

If the data in the List are based on a SQL database, then it is likely that you will want to save the changes you make to the List back to the SQL database. For example, when you move a row to a new position within a category, or you move a row to a different category, you may want to update the underlying SQL database. This is easily accomplished. First, turn on the List's Detail View by setting the Has Detail View property.  If you want to edit the data in the List while you are offline, turn on the Persist data to Local Storage property.

 

 

You do not need to actually define a Detail View for the List. Simply turning on the Detail View property is sufficient.

Next, add a button to the UX to synchronize the List data. Your button should execute this code:

 

 {dialog.object}.saveListEdits('name_of_your_list_control',{rows: 'allRows', ajax: { timeOut: 15000, onAjaxFail: function() { } , onDeviceOffline: function() { } } });

 

TIP You can add the synchronize button to your UX by selecting the [List-Detail View-Buttons] item in the Defined Controls section of the UX builder. The advantage of adding the button using this technique is that Alpha Anywhere will add an appropriate Enable expression to the button so that it is only enabled if the List has edits that have not been synchronized.



 

 

 

Grid Component - Server-side Events - CanAjaxCallback and AfterAjaxCallback - The Grid component now supports two new server-side events

The CanAjaxCallback event can be used to authorize an Ajax callback. The AfterAjaxCallback event can be used to modify the Ajax response that is set to the client.

 

 

UX Component - Lists - Client-side Group Breaks - Multiple Layouts - If you define a List control with multiple Layouts, you can now define client-side group breaks for each Layout.

The property sheet for each Layout has a new property, Group breaks definition that can be set to <Use Default>, Custom-for this Layout, or None.

If you select <Use Default>, the client-side group breaks defined on the List Properties pane will be used.

 

TransForm - Reports - You can now use TransForm as a data source for reports.

The data in a TransForm form can be quite complex. For example, you may have multiple one-to-many relationships in the data (these are nested arrays in the JSON data) and each child may in turn have its own children (i.e. parent-child-grandchild relationships).

Data in this form is not suitable for the report writer, which needs a "flat" table of records. Therefore, when the data are retrieved from a TransForm form, it is "flattened" (search in documentation for json_flatten() for a description of what "flattening" means)

When you create a new report, the menu now shows <TransForm> as an option.

 

If you select the <TransForm> option, a dialog where you can configure the data source is shown:

 

 

Properties of note in the dialog include

 

You can filter on meta data fields. The meta data fields are different than the actual form data. The meta data fields include the id of the person who submitted the form, the form status, the timestamp (time on the server when the form was submitted) and the Forminstanceid (the primary key for the form instance)

You can filter on the following meta data fields

For the Person, Status and FormInstanceId properties, you can enter a comma delimited list of values, or you can use arguments. For example, you might set the Person filter to: :name_of_person

You can also filter and sort on the actual data in the form.

 

Field Data Type Overrides

By default, all data that is retrieved from TransForm is character data. You might want to explicitly change certain fields to be other types so that the report writer can do calculations and summaries with the data. For example, the form might have a field called Quantity which you would like to convert to a numeric field. The Overrides property allows you to set data type overrides.

Photo fields are an exception. Alpha Anywhere automatically sets photo fields to Image File Reference fields (so that the report writer will recognize these fields as images). You do not need to define overrides for photo fields.

You will need to define overrides for signature fields (use the Ink data type).

 

Web Applications Security - Export/Import Group Names - When you are setting up security for a Web application you can now export groups or import groups. The data interchange format is JSON.

 

 

UX and Grid Components - Transient Messages - A new action is available in Action Javascript to display transient messages.

A transient message is a message that is displayed for a short time and then automatically hidden (unless the user dismisses the message early, by clicking a close button).

Transient messages are used extensively by Google in their applications (for example in the GMail web and mobile applications). In the two images below, the transient messages in the Gmail web and mobile application are shown.

 

Transient Message in the GMail Web Application

 

Transient Message in the GMail iOS Application

 

Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

 

To create a Transient Message in the UX or Grid, define a new Action using Action Javascript and select the Message box - Transient action

 

The builder is then shown:

 

 

 

 

Properties that can be set in the builder include:

 

A transient message can have the following positions:

 

The images below show a transient messages in the UX component using the Google and Default appearance:

Transient message using the Default Appearance (the component style is Alpha)

 

Same as above message, but using the Google Appearance

 

The minimum amount of Javascript to display a transient message (using the Default Appearance) is shown below:

{dialog.object}.transientMessage('center','Record was deleted.',

    {
        buttons: [{html: 'Undo', onClick: function(){alert('undo')}}]
    }

)

 

UX Component - List Control - Client-Side Grouping - Default Groups - By default, the group breaks shown in a List when client-side grouping is turned on, are dynamically computed from the actual data in the List. However, you might want certain groups to appear in the List regardless of whether the List contains any data for that group. You can now specify a list of default groups that should always appear in the List.

In the image shown below, default groups for the Country group have been defined. These default groups are 'South Africa' and 'Zimbabwe'.

 

 

The image shown below shows how a List that does not have any data for either South Africa or Zimbabwe would be rendered. Notice that the actual HTML shown for these two empty groups is defined by the Javascript specified in the Javascript for HTML for default group property.

 

 

 

 

 

 

 

UX Component - List and ViewBox Controls - .focus() Method - These controls now have a .focus() method to set focus to the control.

Example

var lObj = {dialog.object}.getControl('my_list_control')

lObj.focus()

 


Xbasic - JSON_flatten_default() Function - Takes JSON with nested arrays and "flattens" the JSON so that there are no nested array. This is same as the JSON_flatten() function, but the template required by the JSON_flatten() function is automatically generated from the input JSON.

 

Syntax

C jsonOut = json_flatten_default(c JsonIn)

 

Example:

dim json as c 
json = <<%str%
[
	{"name": "John", "Lastname" : "Smith", "City" : "Boston", "State" : "MA", "Children": [
		{"Name" : "Callie", "Age" : 5},
		{"Name" : "Griffin", "Age" :3},
		{"Name" : "Luke", "Age" : 1}
		]
	}, 
	{"name": "Henry", "Lastname" : "Rhodes", "City" : "New York", "State" : "NY", "Children": [
		{"Name" : "Howard", "Age" : 15},
		{"Name" : "Robert", "Age" : 11}
		]
	}, 
	{"name": "Allison", "Lastname" : "Berman", "City" : "Los Angeles", "State" : "CA", "Children": [
		{"Name" : "Jeff", "Age" : 35},
		{"Name" : "Roxanne", "Age" :33},
		{"Name" : "Claudia", "Age" : 31},
		{"Name" : "Denzel", "Age" : 11}
		]
	}
]		
%str%
dim json2 as c
json2 = json_flatten_default(json)
?json2

= [
{"name": "John","Lastname": "Smith","City": "Boston","State": "MA","Children_Name": "Callie","Children_Age": 5},
{"name": "John","Lastname": "Smith","City": "Boston","State": "MA","Children_Name": "Griffin","Children_Age": 3},
{"name": "John","Lastname": "Smith","City": "Boston","State": "MA","Children_Name": "Luke","Children_Age": 1},
{"name": "Henry","Lastname": "Rhodes","City": "New York","State": "NY","Children_Name": "Howard","Children_Age": 15},
{"name": "Henry","Lastname": "Rhodes","City": "New York","State": "NY","Children_Name": "Robert","Children_Age": 11},
{"name": "Allison","Lastname": "Berman","City": "Los Angeles","State": "CA","Children_Name": "Jeff","Children_Age": 35},
{"name": "Allison","Lastname": "Berman","City": "Los Angeles","State": "CA","Children_Name": "Roxanne","Children_Age": 33},
{"name": "Allison","Lastname": "Berman","City": "Los Angeles","State": "CA","Children_Name": "Claudia","Children_Age": 31},
{"name": "Allison","Lastname": "Berman","City": "Los Angeles","State": "CA","Children_Name": "Denzel","Children_Age": 11}
]

Notice that each parent record is repeated for each record in the nested array.

 

Xbasic - JSON_flatten_single() Function - Takes JSON with nested arrays and "flattens" the JSON so that there are no nested array. Data from the nested arrays is represented in the parent data as a set of repeating fields.

 

Syntax

C jsonOut = json_flatten_single(c JsonIn[, depth])

 

Where

The function will only operate on one level of nested arrays. For example if a row in a nested array has another nested array, this array will be ignored.

 

Example:

dim json as c 
json = <<%str%
[
	{"name": "John", "Lastname" : "Smith", "City" : "Boston", "State" : "MA", "Children": [
			{"Name" : "Callie", "Age" : 5},
			{"Name" : "Griffin", "Age" :3},
			{"Name" : "Luke", "Age" : 1}
		]
	}, 
	{"name": "Henry", "Lastname" : "Rhodes", "City" : "New York", "State" : "NY", "Children": [
			{"Name" : "Howard", "Age" : 15},
			{"Name" : "Robert", "Age" : 11}
		]
	}, 
	{"name": "Allison", "Lastname" : "Berman", "City" : "Los Angeles", "State" : "CA", "Children": [
			{"Name" : "Jeff", "Age" : 35},
			{"Name" : "Roxanne", "Age" :33},
			{"Name" : "Claudia", "Age" : 31},
			{"Name" : "Denzel", "Age" : 11}
		]
	}
]		
%str%
dim json2 as c
json2 = json_flatten_single(json)
?json2

= [
{"name": "John","Lastname": "Smith","City": "Boston","State": "MA","Children_1_Name": "Callie","Children_1_Age": 5,"Children_2_Name": "Griffin","Children_2_Age": 3,"Children_3_Name": "Luke","Children_3_Age": 1},
{"name": "Henry","Lastname": "Rhodes","City": "New York","State": "NY","Children_1_Name": "Howard","Children_1_Age": 15,"Children_2_Name": "Robert","Children_2_Age": 11},
{"name": "Allison","Lastname": "Berman","City": "Los Angeles","State": "CA","Children_1_Name": "Jeff","Children_1_Age": 35,"Children_2_Name": "Roxanne","Children_2_Age": 33,"Children_3_Name": "Claudia","Children_3_Age": 31,"Children_4_Name": "Denzel","Children_4_Age": 11}
]

Notice that data from the nested arrays is represented in the parent record as a set of repeating fields. For example, Children_1_Name, Children_2_Name, etc.

 

WCF and SOAP Services - Xbasic - IMPORTANT! – If you are creating and using Web References or generating Web Service Clients in Alpha Anywhere to use with WCF or SOAP services, please test the generation and execution of your service client under the most recent pre-release. We have made changes to accommodate some web services, and want to be sure that no one is adversely affected by these changes before we release the next version of Alpha Anywhere.

 

Grid Component - Textbox - Readonly  - Textbox controls in the Grid and Detail View parts now have a readonly property.

 

UX and Grid Components - Advanced Search - A new option has been added to both Grid and UX components.

The Advanced Search feature can be used to search for records in a Grid component, or for records in a List control in a UX component. The List control must be based on a SQL database.

 

Using the Advanced Search Control in a UX Component

Watch Video - Part 1
Watch Video - Part 2

Using the Advanced Search Control in a Grid Component

Watch Video - Part 1
Watch Video - Part 2

 

 

When you define a Grid component with a Search Part, you (the developer), pick the fields that you want the user to be able to search in at run-time. Similarly with defining a search feature for a List control.

With the Advanced Search control, however, you let the user pick the fields that they want to search in (the fields from which the user is allowed to pick is controlled by you - the developer).

The searches that are entered into the Advanced Search feature can be saved and then later retrieved.

The controls that the Advanced Search feature can display are:

 

When the Grid or UX is initially displayed, the Advanced Search control is rendered as follows:

 

 

If the Allow Saved Query Load option is enabled, the Advanced Search control is rendered as follows:

 

 

NOTE: All text in the buttons shown in the Advanced Search control, and the icons are fully customizable. You can also use language tags or text dictionary tags to translate strings into other languages.

 

To start defining a new search, the user will click the Add new search field button. This will display a drop down menu of the fields from which the user can select. This list of fields (and the corresponding control type to use for the field) is defined when the Advanced Search is configured.

For example:

 

The user will select one of the available fields and a new search control is added to the screen.

At this point, the Advanced Search control will look like this:

 

(In this example, the City field was defined as a combolist list control, so it has a button to open a picklist of choices. In addition, since the Save query button is shown if the Allow save query option is enabled.)

 

 

The user can continue adding as many additional search fields as needed. When a second or subsequent search field is added, the Advanced Search control shows AND/OR buttons for each search field (except the last selected field). This allows you to specify if the search items are joined with an AND operator or an OR operator. In the example shown below, the search is for City = 'London' OR Country = 'France'.

 

 

Each new item added to the Advanced Search control will have these two icons:

The trash can icon is used to delete the item from the Advanced Search control.

The funnel icon is used to set search options for the field. When the user taps this icon, a menu with these options is shown:

 

For Date and Time fields (Time is actually a Date-time field), an additional button (with 3 vertical dots) is shown.  This is the date menu button.

 

When the user clicks the date menu button, a menu of pre-defined date ranges is shown. For a datepicker control, the choices in the menu are:

For a daterangepicker control, the choices in the menu are:

 

 

 

When the user clicks on the Calendar icon for a daterangepicker control, the dropdown window shows two calendars so the user can select the start date and the end date for the date range.

 

 

The menu options determine the type of search that is performed. For example, say you have added an item to the Advanced Search control to search in the LastName field and you have entered JO into the input control. If you set the menu to Starts with then records where Lastname is Jones or Johnson will be selected.

The QBF Syntax allows the user to use the standard QBF syntax supported by Grid and UX searches. This syntax is summarized below:

The QBF Syntax allows you to enter multiple search commands, separated by comma. For example

2018/9/1..2018/9/15,2017/9/1..2017/9/15

will find records where the search field value is between September 1 and September 15 in either 2017 or 2018.

 

 

Adding an Advanced Search Control to a Grid Component

To add an Advanced Search control to a Grid component, go to the Grid Properties pane in the Grid Builder and check the Has 'Advanced Search' feature property. This will then show the Advanced Search definition property. Click the smart field for this property to open the dialog where you can configure the control. (See below for details).

 

NOTE: If it possible, although unusual, to have both a standard Search Part in the Grid and also turn on the  Advanced Search feature.

 

 

 

Adding an Advanced Search Control to a List Component

You can add the Advanced Search control to a UX by selecting the [More..] item in the Data Controls section.

 

 

Then select AdvancedListSearch from the dialog.

 

 

This will add an AdvancedListSearch control to the List. You can configure the control by clicking the smart field for the Control properties property. This will open a dialog where you can configure the Advanced Search control. (See below for details).

 

 

 

 

NOTES:

 

 

Configuring the Advanced Search Control

 

The configuration dialog for the Advanced Search control in a Grid is shown below. The left hand list shows the fields that the user can select from when adding a new field to the search at run-time. You can add new fields to this list by clicking on the Add new search field... button. The Property Grid control on the right shows the properties for the selected item in the list on the left.

 

 

 

When you click on the the Add Field button a dialog is shown that allows you to pick one of the available fields in the Grid or the List control.

For each field you select, you must also select the corresponding control type for that field.

For example, if you pick a logical field, you will likely want to select the switch control for that field. On the other hand, say you pick a field called Lastname, you might want to select the suggest control for that field. This will display an auto-suggest list as the user starts typing values into the search field.

 

 

 

 

You can customize all of the icons and prompts shown in the Auto Suggest control. To do so, click the Customize Buttons and Strings for the Advanced Search Control button. This will display the dialog shown below. You can use language and text dictionary tags in the strings (e.g. <a5:r>...</a5:r> or <a5:t>..</a5:t> )

 

 

You can customize certain aspects of the Advanced Search control by clicking the Customize Search Options button.

This will display the dialog shown below:

 

 

You can enable/disable the ability to save and load previously defined advance searches. You can also specify if debugging information should be shown. If you turn on debugging information, the WHERE clause computed from the search definition is shown, as well as the argument values for the arguments referenced in the WHERE clause.

If you turn on debugging information, you must specify where this information should be shown. In the case of a UX component, place a Placeholder control on the UX. The dialog will prompt for the name of the placeholder.

In the case of a Grid component, specify the id of a DIV control where you want the debugging information to appear. You must add the appropriate DIV to your component. A convenient place to add this DIV is in the Before HTML property, in the Additional Customization Options dialog (see below).

 

For example, in the image above, the DIV for the debugging information is specified as:

{grid.componentname}.SEARCHDEBUGGING

 

NOTE: By including the {grid.componentname} placeholder in the DIV id, we ensure that there will not be any conflict with the ID should more than one instance of this Grid be displayed at the same time.

The Unique key property is show if either the load or save query options is enabled. This property is added to the name of the saved query in the Repository table where queries are saved (see below for more information on Loading and Saving queries). This property allows you to ensure that when you click the Load Query button, only saved queries that match the Unique key are shown.

 

In the case of the Grid component, the configuration dialog displays an additional button with customization options specific to the Grid component. When you click the Additional Customization Options button the following dialog is shown.

 

 

 

In the case of the UX component, the builder will display a prompt where you can set the name of the List that the Advanced Search will operate on.

 

 

 

Loading and Saving Queries

In order to save queries you must define a Repository table in the Project Properties dialog. To open the Project Properties dialog, click the Project Properties button in the Web Control Panel.

 

 

You can define the connection string to the database where the Repository table will be stored. You can link to an existing table or create a new table. Click the smart field for any of the properties to open a builder.

 

 

Configuring the Grid to Show Debugging Information

When you run a query in the Advanced Search control you can display the WHERE clause that Alpha Anywhere computed from your query definition.

To turn on debugging information check the Display debugging information property when the Customize Search Options dialog is shown.

In the case of the UX you can specify a Placeholder control where the debugging information will be shown. In the case of the Grid component you specify the ID of a DIV element. You must manually add this DIV to the component. For example, say you specify the ID or the DIV as {grid.componentname}.ADVANCEDSEARCHDEBUGINFO then you would need to add the following HTML markup to your Grid component:

<div id="{grid.componentname}.SEARCHDEBUGGING"></div>

This markup can be added in several possible places. For example in a Freeform Edit Region, in the HTML that displays above or below the Advanced Search control (see the  Additional Customization Options button on the configuration dialog ) , etc.

 

 

 

Property Grid - International Characters in Strings - The Property Grid will now display international characters, rather than the HTML encoded strings. For Example:

 

All Components - Property Grid - Right Click Menu - The Property Grid right-click menu (shown when you right-click on the left hand border bar in the Property Grid) now has additional options. Most useful is the Find option that allows you to search for a property in the Property Grid.

 

 

UX Component - List Controls - Open UX as an alternate editing view for current record - You can now use this action in Action Scripting to edit the currently selected row in a List control in another UX component.

 

 

Xbasic - Read data from the Extended User-Information Table - a5w_getExtendedUserInfo() Function - Reads data from the Extended User-Information table.

Syntax

p Result = a5w_getExtendedUserInfo(userid as c )

Where

 

Example

dim p as p

p = a5w_getExtendedUserInfo('john.smith@acme.com')

?p.error

= .f.

?p.json = <<%txt%

{

    "FIRSTNAME" : "John",

    "LASTNAME" : "Smith",

    "COMPANY" : "Acme Corp"

}

 

 

Xbasic - Save data to the Extended User-Information Table - a5w_saveToExtenedUserInfo() Function - Saves data to the Extended User-Information Table. If a record for the specified userid does not exist, a new record is created. If a record already exist, the existing record is updated.

Syntax

p Result =  a5w_saveToExtendedUserInfo(c userId,c json)

Where


Example:

dim json as c

json = <<%txt%

{

    "FIRSTNAME" : "John",

    "LASTNAME" : "Smith",

    "COMPANY" : "Acme Corp"

}

%txt%

dim p as p

p = a5w_savetoExtendedUserInfo("john.smith@acme.com",json)

 

 

Xbasic - Get Fields in Extended User-Information Table - a5wcb_extendedUserInfoTableFields() - Returns a list of fields in the Extended User-Information Table.

Syntax

c Fields = a5wcb_extendedUserInfoTableFields()

 

UX Sample Component - Editing Data in the Extended User-Information Table - A sample template component is available to edit data in the Extended User-Information Table for the currently logged in user.

When you create a new UX component, select the SecurityFramework-Edit_ExtendedUserInformation template.

The template automatically generates a form based on the fields you have defined in the Extended User-Information table for your web project.

 

UX and Grid Components - Security Framework - Arguments - When you define Arguments for a UX or Grid component, you can now bind an argument to the the id of the currently logged in user, or to the security groups of the currently logged in user.

If you have defined an Extended User Information Table, (see below for more information), you can also bind the argument to any value from the  Extended User Information Table.

In the case where you bind an argument to the security groups for the logged in user, you can define an array argument. A user can be a member of multiple groups. By defining an array argument (the argument name must start with ARRAY_) you can use the argument in a SQL IN clause. For example

select * from tasklist where group IN (:ARRAY_USERSECURITYGROUPS)

 

NOTE: If you are using Active Directory, or IIS (with the Alpha Anywhere plugin), the Security Groups are the actual names of the security groups. In the case of the classic Alpha Anywhere server, the security groups are the GUIDS for each group.

To specify that an argument gets its value from the currently logged in user, set the Get argument value from property to Get value for current logged in user. Then set the Value property.

 

 

When you click the smart field for the Value property you will get a dialog allowing you to select which attribute of the currently logged in user you wish to set the argument to.

If you have defined an  Extended User Information Table, for the current project, the pick list includes fields in the  Extended User Information Table.

 

 

Example

Filtering records in a Grid to only show records that are assigned to the currently logged in user.

Assume that the table that the Grid is based on has a field called userid. The Grid should only show the records where the value in the userid field matches the userid of the currently logged in user.

Click the Define Arguments button to define an argument and bind that argument to the userid for the currently logged in user.

Define a filter for the Grid (assume that the argument you defined was called ARGUMENT_USERID).

userid = :ARGUMENT_USERID

 

 

 

 

UX and Grid Components - Security Framework - Arguments - Xbasic - You can now set an argument to the result of an Xbasic function.

When the component is initially rendered and the argument values are set, the Xbasic function will be called and the argument's value will be set to the value returned by the Xbasic function.

To specify that an argument gets set by an Xbasic function, set the Get argument value from property to Xbasic, and then specify the name of the Xbasic function to call. The Xbasic function can be defined in the component, or in a linked Xbasic Function Library.

 

 

Security Framework - Extended User Information Table - When you use the Security Framework in an Alpha Anywhere application, the table that contains the list of users and their passwords (or password hashes) is a system table and you cannot modify its structure to add additional fields to store additional information about each user.

In order to store additional information about each user in your system it is necessary to create another table in a SQL database. This table is called the Extended User Information Table. It can have any structure that you like, but it must have a primary key field that contains the user id of the user. This field should be indexed.

To create the Extended User Information Table open the Web Security dialog by clicking the Web Security button on the Web Projects Control Panel. Then launch the Security Settings dialog and click the Extended user-info table hyperlink at the bottom of the dialog.

 

 

This will bring up a dialog that will allow you to specify an existing table, or create a new table in the target SQL database.

 

 

 

 

If the user logs in from a UX or Tabbed UI (i.e. not the Login component), a client-side Javascript object will be created with values for each of the fields in the Extended User Information Table.
This object is called A5.extendedUserInformation 

 

TIP If your Extended User Information Table has a specially named field called ActiveLanguage then the value in this field can be used to set the active language for the app. Normally the active language is set by specifying the language in the session.__protected__activeLanguage variable.

 

UX Component - Action Sheets - A common user interface design in iOS mobile applications is the Action Sheet. An action sheet is a series of menu options that animates into display from the bottom of the screen. The menu can be divided into logical sections, as shown in the image below.


 

 

 

The {dialog.object}.actionSheet() method is used to display an Action Sheet. This syntax for this method is:

 

{dialog.object}.actionSheet(menu [, width]);

 

Where:

 

 

Example:

The following Javascript produces the Action Sheet shown in the image above

			
var menu = [
	[
		{html: 'This is the help text above the Action Sheet. It does not have an action'},
		{html: 'Save', action: function(){alert('save')} },
		{html: 'Save As...', action: function(){alert('saveas')} }
	],
	[
		{html: 'New', action: function(){alert('new')}},
		{html: 'Open...', action: function(){alert('open')}}
	],
	[
		{html: 'Cancel', action: function(){alert('cancel')}}
	]
]

;
{dialog.object}.actionSheet(menu);
			
			

UX Component - Action Javascript - Action Sheets - A new action in Action Javascript allows you to create Action Sheets.

 

 

Grid and UX Component - Dropdown Messages - Action Javascript - A new action in Action Javascript makes it easy to create Dropdown Messages. The Message box - DropDown Style action can be selected.

 

 

Grid and UX Component - Dropdown Messages - A new Javascript method has been added to both the Grid and UX component to make it easy to display dropdown messages.

Three styles of dropdown message are available:

 

'Wait' Style Dropdown Message

 

'Confirm' Style Dropdown Message

 

'Message' Style Dropdown Message

 

 

 

 

Syntax

{dialog.object}.dropDownMessage(type,title,body,width,okButtonLabel,cancelButtonLabel,onOK,onCancel,location,animationStyle)

{grid.object}.dropDownMessage(type,title,body,width,okButtonLabel,cancelButtonLabel,onOK,onCancel,location,animationStyle)

 

Where

 

 

 

 

Example:

var dropDownType = 'confirm';

var title = 'Message Title';

var msgBody = 'Message body text';

var width = '400px';

var oKButtonLabel = 'OK';

var cancelButtonLabel = 'Cancel';

var onOK = function() { alert('pressed ok'); };

var onCancel = function() { };

{grid.object}.dropDownMessage(dropDownType,title,msgBody,width,oKButtonLabel,cancelButtonLabel,onOK,onCancel);
 

 

Property Grid Control - The Property Grid control is ubiquitous throughout the Alpha Anywhere IDE. It is used extensively in the UX and Grid builder, and in the List, ViewBox, FormView, ControlBar etc. builders in the UX builder. Previously, the Property Grid control was based on a 3rd party ActiveX control licensed from CodeJock. Unfortunately, this CodeJock control had a resource leak that resulted in the Alpha Anywhere IDE having to be shut down and restarted after extended periods of use. While a later version of the CodeJock control has addressed this issue, we were not able to switch to this newer version as it introduced other issues.

Therefore, Alpha has built its own Property Grid control. The benefits of the Alpha Property Grid control are:

If you come across any issues with the new Property Grid control, you can revert to the old CodeJock control by executing this Xbasic command from the Interactive window:

a5.System_Mode_set("new_propgrid","off")

 

UX Component - Expanding Menu - Dynamically Populating - Ajax - Two new helper functions have been added that make it easy to dynamically populate an Expanding Menu control with data computed in an Ajax callback.

 

Watch Video - Part 1
Watch Video - Part 2

 

Download files

 

 

Xbasic - A5_sqlToJSONExpandingMenu() Function - A new helper function has been added to generate the JSON needed to populate an Expanding Menu control in a UX component from data returned by a SQL query.

Syntax

c JSON = a5_sqlToJSONExpandingMenu(C connectionString ,C table ,C fieldList [,C endPointFieldName [,C filter [,C order [,P argsIn [,C endpointfunctionname ]]]]])

 

Where:

 

Watch Video - Part 1
Watch Video - Part 2

 

Download files

 

Example:

 

dim cs as c = "::name::AADemo-Northwind"

dim table as c = "customers"

dim fieldlist as c = "country,city,contactname"

dim endpointfield as c = "customerId"

dim filter as c = "country <> ''"

dim order as c = "country"

dim endpointfunctionname as c = "selectCustomer"

dim json as c

json = a5_sqlToJSONExpandingMenu(cs,table,fieldlist,endpointfield,filter,order,null_value(),endpointfunctionname)

'now use this JSON to generate the Javascript to populate an Expanding Menu control on a UX component

 

dim js as c

js = "var data = " + json + ";" + crlf()

js = js + <<%str%

var obj = {dialog.object}.getControl('expandingmenu_1');

obj.data.items = data.items

obj.data.actions = data.actions

obj.refresh()

%str%

 

 

Xbasic - a5wcb_convertFriendlyMenuToExpandingMenuJSONData() Function - A new helper function has been added to generate the JSON needed to populate an Expanding Menu control from a menu definition that uses a CRLF list of menu entries, with tab indentation to indicate menu hierarchy.

The menu definition allows you to assign a optional server-side show/hide expression and/or a set of security groups to any menu branch or leaf item. The JSON that is generated will honor the server-side show/hide expressions and security groups. For example, if a menu branch should only be available to someone who is a member of the Administrators group, the generated JSON will not include that branch if the currently logged in user is not in the Administrators group.

The example below shows a "friendly" menu definition

Alpha

    Alpha1

    Alpha2

        Alpha21

        Alpha22

Beta

    Beta1

Gamma

    Gamma1

Each item in the menu can be followed by an optional JSON definition. This JSON definition can have these properties (all of which are optional)

The above "friendly" menu definition shown using the optional JSON settings string for some of the menu items:

Alpha{serverSideShowHideExpn: 'session.var1 = "alpha"'}

    Alpha1

    Alpha2

        Alpha21{securityGroups: 'Administrator,Sales'}

        Alpha22

Beta

    Beta1

Gamma{icon: 'svgIcon=#alpha-icon-bandAidCrossed:icon,24'}

    Gamma1

 

 

 

Syntax

C json =  a5wcb_convertFriendlyMenuToExpandingMenuJSONData(C menu )
 

Where:

 

TabbedUI Component - Expanding Menus - TabbedUI Component - You can now use Expanding Menus to render Tree Controls in the TabbedUI Menu. This allows for a more modern look for your TabbedUI components.

NOTE Expanding Menus are a standard UX control type. To add an Expanding Menu to a UX component, go to the Data Controls section in the UX toolbox and select [More...].

In the two images below, a TabbedUI is rendered with a Tree Control in the first image and an Expanding Menu in the second image. Notice that when the Expanding Menu is used, various parts of the TabbedUI (e.g. the Menu header, the Tab bar, etc.) inherit the color used for the Expanding Menu.

 

 

 

 

To render a Tree container as an Expanding Menu, check the Display as Expanding Menu property in the Tree Control Begin Properties section.

 

 

 

 

When you render a Tree Control as an Expanding Menu you can set the Menu prefix icon for tree branches. This is an icon that will display to the left of the branch text.

 

 

In the image below a tree branch is shown with an icon prefix.

 

 

When you use Expanding Menus in a TabbedUI you will generally want to set the colors of various TabbedUI parts to match the menu color of the Expanding Menu. This is easily done by clicking on the smart field for the CSS to customize TabbedUI appearance property.

 

 

 

When this dialog opens, click the Set all TabbedUI part background colors to match the Expanding Menu color property. This will match the color in the first Expanding Menu control in the TabbedUI. (A TabbedUI might have multiple Expanding Menu controls, each of which may have a different menu color.)

NOTE: If you do not check the box to set the color of various TabbedUI parts to match the Expanding menu color (or if your TabbedUI does not have any Expanding Menu controls), this dialog also allows you to tweak the appearance of different parts of the TabbedUI by defining a set of custom CSS classes that are applied to different TabbedUI parts.

 

 

TabbedUI Component - Customizing Appearance - By modifying the style sheet used for a TabbedUI you can customize the appearance of the TabbedUI component. However, as an alternative to editing the style sheet, you can define custom CSS classes that get applied to various parts of the TabbedUI.

The parts of the TabbedUI interface that you can modify with your own custom CSS classes are:

To define the CSS classes to modify the appearance of these TabbedUI parts, click the smart field for the CSS to customize TabbedUI appearance property in the CSS/SVG section in the property sheet.

 

 

This will open a dialog where you can specify the CSS classes you want to define to customize the various TabbedUI parts.

NOTE The custom CSS classes you define are applied in addition to the built-in CSS classes for the various TabbedUI parts. For example, if you are using the MobBlue style sheet, the CSS class applied to the Menu Panel Header is MobBlueGridHeader. If you define a custom CSS class (called (say) MenuPanelHeader) the CSS classes applied to the Menu Panel Header will be MobBlueGridHeader  and MenuPanelHeader.

 

TabbedUI - Tab Pane Buttons - You can now customize the appearance of individual tab pane buttons (these are the buttons that appear in the tab band after you open a component by clicking on a button in the TabbedUI menu area).

NOTE Previously, you could only customize the appearance of all of the tab pane buttons, but not individual tab pane buttons. To customize the appearance of all tab pane buttons, set the Tab button off and Tab button on properties in the Class names section of the TabbedUI property sheet.

To customize the appearance of a particular tab pane button, select the TabbedUI button in the property sheet and then set the Tab class name and Tab selected class name properties in the Tab CSS section.

 

 

 

 

UX Component - Methods - .setCSS() method - The {dialog.object}.setCSS() method allows you to dynamically add CSS classes at run-time.

 

Syntax:

id = {dialog.Object}.setCSS(css [,id])

 

Where:

If you do not pass in an id a new DOM 'style' node is created. The method returns the id of the node that was created. You can use this id to update the CSS.

 

Example:

var css = '.css1 {color:red;} .css2 {color:blue;}';

var id = {dialog.object}.setCSS(css)l

//now update the definition<br>
css = '.css1 {color:blue;}';

{dialog.object}.setCSS(css,id);


 

Xbasic - showvarhtml() Function - Display Formatted HTML - The showvarhtml() function can be used to display a string of HTML text. The HTML is formatted for readability before it is displayed.

TIP: Contrast with the a5_show_htmlchrome() function which shows the rendered HTML (as opposed to the HTML source).

 

UX Component - List Control - Columnar Layout - Columns - Sort - Initial Sort Direction - When you define the sort action for a column in a List control you can now set the initial sort direction. If the column is unsorted when the user clicks on the column heading the Initial sort direction is defined by the Initial sort direction property.

NOTE: The Grid component as a similar capability to set the initial sort direction.

To set the initial sort direction, set the Initial sort direction property in the List Builder for the selected column.

 

UX Component - Sample Template - Ad-hoc SQL Query Builder - A new sample template is now available when you build a new UX component. The purpose of the component is to allow a user to perform arbitrary queries against any table in a database and then export the data to Excel.

Watch Video

 

The image below shows the component when it is running. As the image shows the user can

 

Once the user execute the query focus is automatically given to the Results pane (second image) which shows the query results.

The use can choose to

 

In order to save and load queries you must configure a Repository table. This is done by going to the Project Properties dialog when the Web Control Panel has focus and setting properties for Repository Settings.

The list of connection strings that the user can select from is controlled by the choices you define for the ConnectionString dropdown box control on the UX.

 

 

 

 

 

UX Component - Containers - Height - Screen.Height - When setting the height of a container control on a UX you cannot use percentages. For example, you cannot set the height of a container to 100%. (You CAN set the width to 100%). Now you can use a special variable screen.height when setting a container's height property.

NOTE: You cannot use screen.height when defining the in-line style for the container. You can only use screen.height in the Height property.

 

Watch Video

 

You can define arithmetic expressions using screen.height.

For example, to set a container's height to half of the screen height set the Height property to

screen.height/2

 

To set a container's height to 50px less than the screen height:

screen.height - 50

 

NOTE: Numeric constants in an expression are always pixels.

 

NOTE: If you use an Alignment container and you set the Container vertical alignment property to Middle and you do NOT set the container height property, Alpha Anywhere will automatically set the container height property to screen.height.

 

UX Component - List Control - Detail View - Synchronization Log Table - When you edit a List control in the List Control Builder, when you save your edits, if your List is configured with an updateable Detail View and you do not have the 'server-side synchronization log table' feature turned on, a warning dialog is now displayed recommending that you turn this feature on.

If you have not configured the synchronization log table (normally done by opening the Project Properties dialog), the warning dialog will automatically configure the synchronization log table if you turn on the synchronization log feature.

 

UX Component - List Control - Detail View - .saveListEdits() Method - The .saveListEdits() method is used to synchronize edits made to the List. The method can now take additional optional properties to specify:

These additional properties are passed in the optional settings object  that the .saveListEdits() method takes.

 

Syntax:

{dialog.object}.saveListEdits('listName',

{

    rows: 'all' or 'current',

    ajax: {

        timeOut: 15000,

        onAjaxFail: function() { } ,

        onDeviceOffline: function() { }

        }

}

);

 

UX Component - PhoneGap Applications - Downloading Files to a Device - A new action has been added to Action Javascript that makes it easy to download multiple files (including SQLite database files) to a device so that these files can be accessed while the application is offline.

 

To select the action choose PhoneGap - Manifest from the list of available actions.

 

 

 

 

 

 

HTML Reporting - Window Toolbar - Close Button - When you use Action Javascript to define an action that prints a report as HTML you can define buttons that appear in the toolbar of the window in which the report is shown. In some cases, developers will choose to turn off the display of the window title bar in order to create a nicer looking window. However, if you turn off the title bar, there is no way to close the window. There a new option is available to add a close button to the window toolbar.

 

To select this option uncheck the option to show the window title and then set the Has window close button property

 

 

Here is how the window toolbar will appear:

 

Bugs

Application Server for IIS - Under certain conditions the Application Server for IIS would crash.

UX and Grid Component - Date Picker - Two Digit Years - Regardless of the date template that has been defined, when the user enters a date with a two digit year, the year is now correctly interpreted.

UX Component - List Control - Soft Delete - If a List with Detail View was configured to do "soft deletes" and the List was based on a SQL query that joined two or more tables, the soft delete field was not being qualified with a table alias in the SQL statment that retrieved the data for the List.

API Creator - Authorization - Passing Parameters in Request Header - Fixed an issue where argument could not be passed to the authorization method in the request header.

Xbasic - AlphaDAO - toJSON() Method - Fixed a bug that caused an unhandled exception when calling SQL::Query::Resultset.toJSON() if a query included a row with an invalid Geometry Well Known Text value.

UX Component - Hyperlink - Click Event - Disable - If you used client-side enable expressions to disable a hyperlink, the Click event would still fire even though the hyperlink should have been disabled.

UX Component - Textbox Control - Client-side Formatting - If a textbox control had client-side formatting defined, when you tabbed into the control, all of the text in the control was not selected.

UX Component - List Control - Reports - Fixed an issue with the currentListFilter() function.

Geocode_address() Function - Was not passing in the API Key value correctly

UX Component - Web Sockets - Fixed an issue where the WebSockets code was not getting published when a web project that used WebSockets was published. As a result, the components that used Web Sockets would not work. 

SQLite Database - Indexes - When you create a SQLite database, Alpha Anywhere allows you to define indexes for the SQLite database. If a table was based on a custom SQL statement, the Index Builder genie did not show you the fields in the SQL query.

Application Server - Security Framework - Active Directory - IIS - A regression was introduced in the last release build in Application Server for IIS where groups are not found for a user. This leads to users not being authorized to access pages after the user has successfully logged in.

This problem occurs when the users and groups are in separate branches of the Active Directory hierarchy. Given this example Active Directory structure:

Company (OU)
    Employees (OU)
        Location1 (OU)
        Location2 (OU)
            Users (OU)
                User1 (User)
                User2 (User)
                User3 (User)
    Security Groups (OU)
        Applications (OU)
            Manufacturing (OU)
               Administrators (Group)
               Assemblers (Group)
               Foreman (Group)
		

the problem would occur when using the Users OU to authenticate users and the Manufacturing OU for groups. This is now fixed.

 

Action Javascript - Email a Report - Fixed an issue when the Internal option was selected to email the report. (The Mandrill and Sparkpost options did not have any issues).

Web Applications - Security Framework - Active Directory - Fixed an issue where you would occasionally get an error message stating:

 

Cannot access a disposed object.

 

UX Ccomponent - Semi-circular Number Display - Dynamic Color - The dynamic color option was broken as a result of an upgrade to a new version of the RGraph open source Javascript library bundled with Alpha Anywhere

 

Alpha Anywhere V4.5.4.5 - Build 5221-5152 23-JUL-2018

 

 

Features

Web Control Panel - F2 Key - The F2 key now acts as a shortcut for the Rename command, available on the right-click menu.

 

UX Component - Action Javascript - Try/Catch Blocks - You can now wrap individual actions and the entire action in a Javascript try/catch block. To wrap an action in a try/catch block, right-click on the action and select the Wrap action in try/catch block  command. This will open an editor where you can define the code to run in the catch block. If an action is configured to use a try/catch block, the menu item will be checked.

 

 

An action can comprise several individual actions. You can also wrap the entire action in a try/catch block by checking the appropriate checkbox at the bottom of the dialog.

 

Custom APIs - Swagger Test Page - When you create a custom API using Alpha Anywhere's API creation facility, you might want to create an .a5w page where users can explore your API and test it out. In order to create an API testing page, click the New button on the Web Control Panel while the Web Components category has focus.

Then select the Swagger API Test Page option.

When your users visit this page in your published application they will be able to explore the methods exposed by your API.

 

 

 

 

UX Component - Javascript Charts - X-Axis Label Angle - You can now specify the angle for the x-axis labels. In the example below, the xaxisTextAngle property has been set to 45.

TIP When you set the xaxisTextAngle property, you may also need to set the gutterBottom property to ensure that the labels are not clipped.

 

 

 

 

UX Component - Expanding Menu - Above Menu and Below Menu HTML - You can now specify arbitrary HTML to display above and below an Expanding menu control.

 

 

 

UX Component - Summary of all defined event handlers - A new item on the Menu dropdown in the UX builder allows you to get a summary of all of the events that have been defined in the UX. This can be very helpful in a large UX with many controls because it allows you to quickly get a comprehensive view of all of the event handlers that have been defined.

To display the summary, click the Menu button and then select the Show summary of all Javascript code for event handlers menu item.

 

 

 

This will display a windows showing all of the controls on which event handlers have been defined.

 

 

 

UX Component - Action Javascript - Run a Report that is Embedded in a UX Component using a Custom Filter Action - This action now allows you to define a custom sort order in addition to the custom filter.

 

 

 

 

UX Component - PhoneGap - Offline Applications - Loading Files onto a Device - When you design an App for offline use, you may want to install files (including images, videos and SQLite databases) on the device so that these files can be accessed by your App even when there is no connection.

There are already ways in which you can load SQLite databases onto a device (using Action Javascript) and also use the client-side data cache to store data on the device, but now a new method ( {dialog.object}.phoneGapDownloadManifestFiles() ) allows you to define an arbitrary list of files that you want to install on a device.

The  {dialog.object}.phoneGapDownloadManifestFiles() method take a manifest that defines the files you want to install on the device. The manifest can either be a JSON string that specifies an array of objects (described below), or the URL of remote JSON file that specifies the manifest.

Syntax

{dialog.object}.phoneGapDownloadManifestFiles(manifest,folder,cbAllDone,optionsIn,fileSystemPart)

 

Where

Syntax for the optional optionsIn argument
 

{
    showProgress: true,
    progress: {
        color: 'green',
        width: '600px',
        progressElement: '{dialog.componentname}.V.R1.PLACEHOLDER_1'
}

 

Example

 


var cb = function(arr) { alert('File have been installed - ' + arr.length);};
 

 

//the manifest is an array of objects

//each object must have a 'url' - the url of the file

//each object must have a 'type'. types are: 'sqlite', 'folder' or 'file'.

//for 'folder' the entire folder must be zipped into a single zip file. The 'targetFolder' specifies the sub-folder

//within the target folder where the folder (containing all of the unzipped files) will be located

//for 'file', the file must not be zipped.

//for 'sqlite', the file can be zipped, or unzipped. (zipped is recommended)


array  = [
        {
            url: 'http://alphamediacapture.s3.amazonaws.com/transform/SQLiteNorthwind.zip',
            type: 'sqlite',

            version: 1
        },
        {
            url: 'http://alphamediacapture.s3.amazonaws.com/transform/sqlite3.db',
            type: 'sqlite',

            version: 1
        },
        {
            url: 'http://alphamediacapture.s3.amazonaws.com/transform/allimages.zip',
            type: 'folder',
            targetFolder: 'images',

            version: 1


        },

        {
            url: 'http://alphamediacapture.s3.amazonaws.com/transform/customer.zip',
            type: 'file',
            targetFolder: 'files',

            version: 1


        }


    ]
 

var url = 'http://alphamediacapture.s3.amazonaws.com/transform/transformManifest.json';

 

//can either specify a url that points to a manifest or the JSON manifest itself

url = array;
{dialog.object}.phoneGapDownloadManifestFiles(url,'account1',cb,opsIn)

 

 

UX Component - PhoneGap - Unzip Files - A new helper function has been added to the Alpha Anywhere Javascript library that makes it easier to work with the PhoneGap plugin that allows you to unzip files.

The function allows you to specify the file system part and folder where the source zip file located, the file system part where you want the unzipped files to be placed and optionally can call the onSuccess callback function with an array showing the files that were unzipped.

Syntax:

 

{dialog.object}.phoneGapUnzipFiles(explicitFilenameURI,filesystemSource,folderSource,zipFileName,fileSystemTarget, dirStructureTarget,onSuccess,onError,flagListUnzippedFiles)

 

Where

 

 

Web Components - Modal Windows - Tab and Sift Tab Key - You can no longer tab out of a modal window using the Tab or Shift+Tab keys.

 

UX Component - Container - Constrain Tabbing - You can now set a constraint on a container to prevent the user from tabbing out of the container using either the Tab or Shift+Tab keys. You can set the Constrain tab key property to:

 

 

TIP: Using this feature you can constrain controls in a Panel Card by wrapping all of the controls in a container.

 

PhoneGap Builder - 3rd Party Plugins - Cordova Custom URL Scheme Plugin - Added support for the Cordova Custom URL Scheme plugin. This plugin allows you to register a custom URL scheme that can be used as a link to launch your app.

When you select the Cordova Custom URL Scheme Plugin a dialog will appear to allow you to enter your custom URL scheme when you save the PhoneGap project.





The link can be added to an email, a web page or another app. As long as the app is installed on the device and the link is triggered from an email, web page or app that is being viewed or used on the device, then your app will load. You can also pass in parameters that can be used for deep linking, redirecting the app to a specific page within your app. You can also pass Base64 encoded JSON as a parameter for further processing within your app.

The plugin supports an optional handleOpenURL(url) method, that receives the URL and any parameters that were used to launch your app. This allows you to define a custom handler that can act on the path and parameters as required.

See the plugin documentation for further details and examples. cordova-plugin-customurlscheme

 

PhoneGap - Instant Update - Channels - By default, when you publish an Instant Update to your PhoneGap application, all of the users of your app will get the update as soon as they launch the app on their devices (assuming the app was designed with auto update turned on).

However, you may want to push an update to just of few users, perhaps because you are still testing a new feature. This can easily be done by specifying a channel when you publish an Instant Update.

You will need to add a user interface to your app so that a user can select what channel they are on. By default, all users are on the Production channel. But a user may change their channel to (say) the Test channel. The Javascript command that you can use to allow a user to set their channel is:
{dialog.object}.setChannel(channelName)

When you publish an Instant Update, you specify for which channel the update is intended. For example, if you publish an Instant Update to the Test channel then a user who is on the default Production channel will not get an update when they re-launch the app on their device. However, a user who has changed their channel to the Test channel will get updated when they re-launch the app. If that user later changes their channel back to the Production channel, then when that user re-launches the app, they will be automatically switched to the latest Production version.

 

 

 

Template Tester - A completely redesigned version of the Template Tester is now available. The main advantage of this new version is that all of the various editing panels (i.e. JSON data, template, css, javascript) are resizeable and can also be collapsed. Previously, each of these editing panels was on a separate tab. The new tester is more convenient to use. If you prefer the old version of the template tester you can revert to it by going to the View, Settings menu and navigating to the Preferences, TemplateTester section.

 

Bugs

Web Applications - Session Variables - Fixed a regression that was introduced in Version 4.5.4.1 enumerating session variables.

UX Components - Panel Cards - Fixed a regression that was introduced in the previous release.

 

 

 

 

Alpha Anywhere V4.5.4.4 - Build 5159-5132 22-JUN-2018

 

Bugs

 

UX Components - Panel Cards - Fixed a regression that was introduced in the previous release.

Starting Alpha Anywhere with Command Line Arguments - Fixed a regression that was introduced in the previous release.
 

 

Alpha Anywhere V4.5.4.2 - Build 5155-5130 20-JUN-2018

Bugs

Launching Alpha Anwhere from a Shortcut - A regression was introduced i the last release that broke the ability to launch Allpha Anywhere and open a named work space using a shortcut.

Application Server for IIS - Grid Component - Fixed a regression that was introduced in the last update. Grid would fail on any Ajax callback.

PhoneGap - Fixes a problem when generating an app with custom icon and splash screen.

 

Alpha Anywhere V4.5.4.1 - Build 5151-5127 18-JUN-2018

 

Videos

UX Component Cascading DropdownBoxes Using the Client-side Data Cache Cascading dropdown boxes allow you to dynamically change the choices in a child dropdown box based on the selection in the parent dropdownbox. The UX component makes it very easy to define cascading dropdownboxes. However, in applications that are designed to work offline, you cannot use the standard way of creating cascading dropdownboxes because if you are offline you cannot make the Ajax callback to populate the child dropdownboxes when the parent dropdownbox value is changed. However, you can still implement cascading dropdown boxes in offline applications by populating the dropdownboxes from data in the client-side data cache.

In this video we show how data in the client-side data cache is used to create cascading dropdownboxes.

Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

Download files

Date added: 2018-04-30
UX Component - Map Control Computing Distance and Travel Time Between Points A common requirement in mapping applications is to compute a route (showing driving directions, distance and travel time) between points.

In this video we show how a route, defined by addresses in a List control is used to compute driving directions, distance and travel times between points on the route. The code is all generated automatically by Action Javascript.


Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

Download files

Date added: 2018-04-30
SOAP Services Using the Sample WCF Service You can easily consume SOAP services from your Xbasic code. But it can be difficult to find publicly available SOAP services to test your code with. Using the sample WCF SOAP service that ships with Alpha Anywhere, you can easily create test code that shows how to consume methods in a SOAP service.

In this video we show how the sample WCF service can be used.

Watch Video

Date added: 2018-05-06
UX Component - List Control Running Totals This video shows how you can compute a column of running totals.

Watch Video

Download files

Date added: 2018-05-31
UX Component - ExpandingMenu Control Collapsing Menu When Selecting an Action When you select the action on a leaf node in an Expanding Menu control, you might want to collapse the menu so that some or all of the expanded nodes are collapsed.

In this video we show how an expanded node in an Expanding Menu control can be collapsed.

Watch Video

Download files

Date added: 2018-06-02

 

 


 




 

 

Features

Alpha Launch - New Version -  A new version (version 2.1.1) of Alpha Launch is now available in both the iOS and Android stores. With version 2.1.1, installing apps onto the device is now significantly quicker if the apps are published to Alpha Launch using the singleWithHeader option in the Download type property. With this option, all of the files that need to be installed on the device are combined into a single file which is then downloaded to the device and then unpacked on the device. It is considerably quicker to download a single large file than hundreds of smaller files.

 

Web Applications - Reload Security Information - Reload the security data for the current application - When you change the security information for an application (for example, change whether a page requires login, and if so, what groups are authorized) and you republish the application to a remote server, the new security information is not loaded immediately. It is only loaded when the security information cache is cleared (the duration of this cache is set in the Security Settings for the project). For more information on the security cache click here.

 

The a5ws_ReloadWebSecurity() function will force an immediate reload of the web security settings for the current application on a standard web server, regardless of the security cache timeout setting. The function must be run on a web page or component running on the web server. It does not reload security on an IIS server. This can be used on a maintenance page to force a reload of security after publish

The function will return .T. if successful, and .F. if running on IIS, running in Live Preview, or running in Working Preview

Syntax:

L flag = a5ws_ReloadWebSecurity( )
 

Xbasic - Using the Stripe API From Xbasic - A new genie, accessed from the right-click menu when you are editing Xbasic code, opens a genie that shows sample code for making calls to the Stripe API

 

The image below shows how the Stripe genie is accessed from the Genies... menu on the right click menu.

 

 

When you select the Stripe genie.. command the dialog shown below is shown.  The genie shows sample Xbasic code for the vast majority of the features exposed by the Stripe API.

 

 

 

Web Applications - Publishing Fonts - In some cases the server on which your application is running may not have installed a font used in one of your reports.

You can now click on the More... button on the Web Projects Control Panel and select the Create 'Fonts' folder menu command to create a folder called fonts in your Web Project. Any fonts you place in this folder will be automatically installed on the server when you print a report. This feature is especially useful on Alpha Cloud where you do not have the ability to specify what fonts each server has installed.

 

 

UX Components - Color Palettes - If a UX component uses a version 4 type style (the Alpha style is the only style currently that is a version 4 style), a new property is available in the UX builder to select a color palette.

 

 

 

Selecting a color palette is very similar to using the Customize style colors and fonts property, except that the color palette applies only to the current UX component, whereas if you use the Customize style colors and fonts property, the settings apply to every UX component in the current Web Project that uses the selected style.

 

 

When you click the smart field for the Color palette prompt the dialog that is displayed allows you to select an existing color palette, or create a new, user-defined, color palette.

 

 

When you preview a color palette or create a new color palette you will see a dialog like the one shown in the image below. This dialog allows you to set a color for each of the available color types.

 

 

 

Audit Table Feature - User Defined Field - You can now add a user defined field to the audit table to capture any additional information that you want at the time the audit table is updated. If you set the value in a special session variable called session.__audit_userfield1, the value in this variable will be written to the user defined field when the audit table is updated. If you want to store a significant amount of information in this field, consider creating a string of JSON data. The JSON data can have a large number of properties.

 

Xbasic - ShowDiff() function - The ShowDiff() function shows you a windows with the differences between data in two variables or files.

You can either choose a light theme or a dark theme (second image).

You can use the Previous and Next buttons to move from one difference to the next.

Use the black square icon on the right to change the theme.

Syntax

V =  showdiff(c varOrFile1, c varOrFile2)

 

Where

NOTE: ShowDiff() Function cannot be used in Web Application

 

 

 

Xbasic - geocode_address() Function - Now allows you to pass in an API key. If you are using Google to Geo-code addresses, Google is introducing rate limiting to the geo-coding API. You can now pass in your API key when you call this function. You can also define a project wide API key in Project Properties

 

Xbasic - SQL_Query() Function - Returns JSON data from a SQL Select statement - This function is a convenience function. It is just a wrapper around the low level Xbasic AlphaDAO commands.

 

Syntax

 

p Result = sql_query(a cnIn, c sql [, sql::arguments argsIn [, L flagPortableSQL[, L formatJSON]]]);

 

Where

 

Xbasic - A5_ink_to_png() Function - Background Color - The A5_ink_to_png() function is used to convert the Alpha Anywhere ink format (produced by the UX Ink control) to a .png image. By default, the image created has a transparent background. Now, you can specify an explicit background color.

Syntax:

function a5_ink_to_png as v (c ink ,n heightInPoints,n widthInPoints,c filename [, L flagUseViewBox [,c backgroundcolor ]])
 

 

Where

 

.Net 4.7.2 - Alpha Anywhere now installs Microsoft .Net 4.7.2. The first time you run an installer or path installer for this version there will be a significant delay while .Net 4.7.2 is installed (if it is not already installed on your machine).

 

UX Component - Expanding Menu - Set Background Color Below Menu - You can now easily set the background color of the space below the bottom an expanding menu control. This gives the expanding menu a more pleasing appearance.

 

 

 

 

In the expanding menu builder there is a new property Below menu background color.  By default, this property is set to <Same as Menu Color> which will use the Menu color defined in the previous property.

 

Alpha Launch - Publishing apps to Alpha Launch can be tricky. A new option on the Alpha Launch dialog allows you to check if your publish worked correctly. To test your publish, click the Check if files were published correctly button.

 

IMPORTANT: The publishing profile you define for Alpha Launch publishing should not use used to publish your application using the standard Publish dialog. The Alpha Launch publishing profile is for the exclusive use of Alpha Launch publishing.

 

 

 

Xbasic - Get size of JSON Array - The extension::json::ArraySize() method allows you to get the size of a JSON array, without having to first call the json_parse() function. For large JSON strings, this can result in a significant performance improvement

Syntax

n size = extension::json::ArraySize(c JsonString)

Example:

? extension::json::ArraySize("[10,20,30,40,50,60,70,80,90]")

= 9

 

Xbasic - Chunk JSON Array - The extension::json::ArrayChunked() method takes a large JSON array and breaks it into smaller chuncks

Syntax:

c JSONChuncks = extensioni::json::ArrayChunked(c json, n maximumRows, n maximumBytes, c separator)

Example:

? extension::json::ArrayChunked("[10,20,30,40,50,60,70,80,90]",3,0,crlf()+"--sep--"+crlf())
= [ 10,20,30 ]
--sep--
[ 40,50,60 ]
--sep--
[ 70,80,90 ]

 

Alpha Launch - Faster App Install - When you publish files to Alpha Launch you can now bundle the package of files that get loaded into AlphaLaunch into a single file. This makes installing apps on a device much quicker because a single file is loaded from the Alpha Launch server, rather than a large number of small files. To use this new feature, select the singleWithHeader option in the Alpha Launch Settings dialog.

NOTE: This option will only work if you have installed Alpha Launch V2.1.1 on your device.

 

 

 

JSON Path - JSON Path allows you to extract portions of a JSON string and perform certain types of simple calculations on JSON strings.

When working with XML data, there is a well known standard, called XPath, for extracting parts of the XML data. JSON Path allows for similar functionality when working with JSON data.

Xbasic now includes a new function called json_path() that allows you to perform JSON Path queries on JSON data.

You can also use JSON Path on the client side (in your Javascript code). The Javascript function is also called json_path().

IMPORTANT: The json_path() function is only available in the UX component. In addition, you must explicitly load the jsonpath system library by selecting it at the Optional system libraries property in the UX Builder if you want to use the json_path() function in your code

 

Syntax - Xbasic json_path() Function

c string = json_path(c json, c path)

Syntax - Javascript - json_path() Function

    string = json_path(jsonOrObject, path)

Where

 

 

The following sample JSON string is used in the examples below:


{
  "store": {
    "book": [
      {
        "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      {
        "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      {
        "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      {
        "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}

 

JSON PathSyntax

(NOTE: Examples are from the https://www.npmjs.com/package/JSONPath documentation)

 

$.store.book[*].author The authors of all books in the store
$..author All authors
$.store.* All things in store, which are its books (a book array) and a red bicycle (a bicycle object).
$.store..price The price of everything in the store.
$..book[2] The third book (book object)
$..book[(@.length-1)]
$..book[-1:]
The last book in order.
$..book[0,1]
$..book[:2]
The first two books
$..book[0][category,author] The categories and authors of all books
$..book[?(@.isbn)] Filter all books with an ISBN number
$..book[?(@.price<10)] Filter all books cheaper than 10
$..*[?(@property === 'price' && @ !== 8.95)] Obtain all property values of objects whose property is price and which does not equal 8.95
$ The root of the JSON object (i.e., the whole object itself)
$..* All Elements (and text) beneath root in an XML document. All members of a JSON structure beneath the root.
$.. All Elements in an XML document. All parent components of a JSON structure including root.
$..[?(@.price>19)]^ Parent of those specific items with a price greater than 19 (i.e., the store value as the parent of the bicycle and the book array as parent of an individual book)
$.store.*~ The property names of the store sub-object ("book" and "bicycle"). Useful with wildcard properties.
$.store.book[?(@path !== "$['store']['book'][0]")] All books besides that at the path pointing to the first
$..book[?(@parent.bicycle && @parent.bicycle.color === "red")].category Grabs all categories of books where the parent object of the book has a bicycle child whose color is red (i.e., all the books)
$..book.*[?(@property !== "category")] Grabs all children of "book" except for "category" ones
$..book[?(@property !== 0)] Grabs all books whose property (which, being that we are reaching inside an array, is the numeric index) is not 0
$.store.*[?(@parentProperty !== "book")] Grabs the grandchildren of store whose parent property is not book (i.e., bicycle's children, "color" and "price")
$..book.*[?(@parentProperty !== 0)] Get the property values of all book instances whereby the parent property of these values (i.e., the array index holding the book item parent object) is not 0
$..book..*@number() Get the numeric values within the book array

 

Example

 

Xbasic Example

dim path as c

'get the author for all books in the store

path = "$.store.book[*].author"

dim json as c

json = <<use the sample json string from above>>

dim result as c

result = json_path(json,path)

= [
    "Nigel Rees",
    "Evelyn Waugh",
    "Herman Melville",
    "J. R. R. Tolkien"
]

 

Javascript Example

    var path = '$.store.book[*]';

    var json = {

        //put sample json here

    }

    var result = json_path(json,path)

 

 

CURL Genie - Xbasic Template - extension::curl::RequestTemplate() Method - When you use the XBasic CURL genie (to convert a CURL command into Xbasic) a new, more concise Xbasic syntax can be generated.

The new syntax, shown in the image below in the Xbasic Template tab of the genie, takes a JSON input string to define the request.

The main advantages of the Xbasic Template over the low level Xbasic syntax (shown in the Xbasic tab of the genie) are:

In the example shown in the screenshot below, the JSON definition passed to the command defines:

 

 

 

The Xbasic Template can also be used to post multi-part form data.

 

In the screenshot shown below, the JSON defines a form property which can have form data (name "key1" and value "value1") and form data.

 

 

 

 

 

Special Placeholders

When defining the URI and the headers in the JSON passed to the extension::curl::RequestTemplate() method, there are two special placeholders that you can use:

The values for these placeholders are resolved by the specified Named Provider (see the namedResource variable in the example code below).

 

Sample Xbasic code showing how a REST API call is made to the Salesforce API.

(Assume that the authentication details for the Salesforce account have been saved in a Named Provider called salesforcetoken. )

Notice that the URI specified in the JSON string has an argument name in it (:id)

dim json as c = <<%json%
{
    "uri": "{namedresource.resourceurl}/services/data/v39.0/sobjects/Account/:id",
    "auth": {
        "bearer" : "{namedresource.access_token}"
    }
}
%json%
dim namedResource as c = "salesforcetoken"
 

'define the value of the arguments used in the URI
dim args as sql::arguments
args.add("id","0011N00001EBYRDQA5")
 

'instead of putting the account id in a sql::argument, we could have

'used a variable and referenced the variable in the URI as {accountNumber)

'instead of :id

'for example: /services/data/v39.0/sobjects/Account/{accountNumber}
 

dim vars as p
vars.accountNumber = "0011N00001EBYRDQA5"
 

dim response as extension::CurlResponse
response = extension::curl::RequestTemplate(json,namedResource,vars,args)

if response.content <> "" then

    dim json as c

    json = response.content
else

    'no response
end

 

 

 

UX Component - ViewBox Control - Data Source - REST API - The ViewBox control now has new data source type - REST API. Use this option to make a REST API call to retrieve the JSON data to be rendered in the ViewBox.

 

When you use the REST API option you can specify if the REST call is made from the server or from the client.

When you make the call from the server, the Alpha Anywhere server will make the REST API call and then return the JSON data to the browser. If you later refresh the ViewBox, an Ajax callback is made to the server, the server executes the REST API call and then returns the JSON data to the client.

When you make the call from the client, the REST call is made directly from the client using the Javascript XHR object. The Alpha Anywhere server is not involved at all.

When you make the call from the server, you can specify a URL for the REST API end point that includes placeholders that will get resolved before the call is made. You can use controls on the UX and also arguments as placeholders. For example, say you have a textbox on your UX called customerId. You might specify the URL for the REST API as:

http://www.myapi.com/customers/{customerId}

 

When the API call is made, the placeholders in the URL are resolved. So, for example, if at the time the ViewBox is refreshed, the customerId control has a value of CUST_01, the URL for API call will be:

http://www.myapi.com/customers/CUST_01

 

Argument values are represented in the URL using :argument_name. For example, assume you have an Argument called CUSTOMER_ID. You could specify this URL for the API endpoint:

http://www.myapi.com/customers/:CUSTOMER_ID

 

In some cases, the API endpoint you call will be authenticated. For example, many API endpoints require an oAuth authentication or a "service account" login. You can specify the name of a Named Provider (defined by going to the Tools menu when the Web Control Panel has focus, and selecting Tools, Named Providers, or by opening the Project Properties dialog).

In the case where the call is made from the server,  you can optionally specify an Xbasic function to post-process the JSON data that is returned by the REST API call before the data is returned to the client. In the case where the call is made from the client, you can optionally specify Javascript code to post-process the data before the ViewBox is populated.

In the case where the API call is made from the client, the URL is defined by Javascript code that must return the URL. This allows you to easily construct URLs that are dynamically computed, based on data in the component.

 

 

UX Component - ViewBox Control - Data Source - Custom - The ViewBox control now has a new data source type - Custom. When you select the Custom option you can specify the name of an Xbasic function. This function should return the JSON data that the ViewBox will render.

An example of where the Custom option could be used is if the data that you want to show in your ViewBox is returned from a SOAP service request, or you need to aggregate data from multiple data sources.

 

UX Component - List Control - <listObject>.removeRows() Method - Animation - You can now turn on animation when you remove rows from a List control using the .removeRows() method.

Syntax

<listObject>.removeRows([rowsToDelete [,flagAnimate]])

Where

 

 

UX Component - httpFetch() Method - A new method has been added to the UX component to fetch data from a remote URL.

Syntax:

{dialog.object}.httpFetch(url,onSuccess,onError[,headers])

 

Where headers is an optional array that allows you to set custom headers for the request. The headers array is an array of objects. Each object has a name and value property.

For example:

var headers = [];
headers.push( {

    name: 'Authorization',

    value: 'Bearer my_access_token_value_goes_here'

});

 

The onSuccess callback function get called when the data are available.

Example:

var url = 'http://some_remote_url'
var cb = function(data) { console.log(data)}
var fail = function() { alert('request failed');}
{dialog.object}.httpFetch(url,cb,fail)

 

Template Tester - MDI Window - The Template Tester (accessed from the Tools menu when the Web Control Panel has focus) is now a MDI window rather than a modeless window. This makes it easier to keep the Template Tester window open while you are working on other tasks.

Template Tester - Default Template - The Template Tester now has a new link on the Template pane to generate a default template from the JSON data. In cases where the JSON data is very complex, this can give you a quick start on building a new template. The default template can be generated in one of two ways: compact, or fully expanded.  The 'compact' option will use containers (e.g. {orders}....{/orders}) for arrays, but not objects. The 'fully expanded' option will use containers for both arrays and objects and it results in a larger template.

 

Alpha Anywhere Server for IIS - Performance Improvements - Session State Storage -

All session state providers have a new option to specify storage. A button is available in the new publish profile genie
 




and a new option is available in a publish profile's property sheet "Session State Storage Type" :



Session State Storage Type defines where session files are stored.

There are 2 options:


When "Storage Connection String" is selected there will be an additional prompt for the storage connection string.



When the storage connection string is of type "Disk" there will also be a "Storage Lifetime" and "Storage Scope" prompt.

 

Alpha Anywhere Server for IIS -  Redis Installed as a Service - The Application Server for IIS installer will now install Redis as a Windows service. This service will be installed for Manual start. If an application uses Redis for session state provider, this service can be set to Automatic start up and started up to provide a Redis instance. The redis.config for the service is located in C:\ProgramData\Alpha Software\Redis. See (https://www.alphasoftware.com/documentation/pages/Guides/IIS/ConfigureProviders/ProviderConfiguration.html#section2_configureRedis) for understanding the options in the redis.config file.
 

SQLite Database - A new menu option on the Tools menu (when the Web Control Panel has focus) allows you to create an SQL database and populate the database with data. After the SQLite database has been created, it can optionally be uploaded to Amazon S3. This makes it easy for mobile applications to download the database and store it on a device.

To select the option select Tools, More.., Create SQLite Database

 

Xbasic - High Precision Numeric Calculation - When doing numeric calculations with Xbasic there can sometimes be a loss of precision because internally Xbasic uses floating point numbers. A new class is available in Xbasic for high precision calculations. When using this new class, all input numbers and output results are variables of type character (not number).

For example:


 


? MathUtil::Decimal::Add("1.20","2.30")
= "3.50"
? MathUtil::Decimal::Subtract("1.20","2.30")
= "-1.10"
? MathUtil::Decimal::Multiply("1.20","2.30")
= "2.7600"

? MathUtil::Decimal::Divide("1.20","2.30")
= "0.5217391304347826086956521739"

? MathUtil::Decimal::Compare("1.20","2.30")
= -1


 

Web Applications - Publish - Done Message - After a web project is published, a dialog can now be shown to confirm that publishing was completed. You can toggle whether this dialog should appear or not by opening the Project Properties dialog from the Web Control Panel and selecting the Design-time tab.

NOTE: By default, this dialog is turned off. You must go to Project Properties, Design-time Settings to turn it on.

 

NOTE: Alpha Anywhere also displays a dialog after publishing files as shown below. This dialog can be turned on/off by going to the View, Settings menu and navigating to the Preferences, Web Publishing section. The setting to show or hide this dialog is system wide, while the settings for the new Publish Complete dialog are just for the current Web Project.


 

 

 

UX Component - PhoneGap - Instant Update - First-time Run Message - The first time you load a PhoneGap app (built using the Instant Update feature) on a device the app files must be unzipped and stored in a folder on the device. On most newer devices, this process happens quite quickly. However, on some older Android devices, it can take some time to unzip the files. It can appear to the user that the app is not responding. Therefore, you can now display a message to the user when the app is unzipping files for first time use. The message should tell users that this is a one-time delay and that they must wait until the files have been prepared.

 

 

Xbasic - A5InstanceCount Function - Returns the number of instances of Alpha Anywhere that are running.

 

Syntax:

n count = A5InstanceCount()

 

 

Runtime Applications - Control Panel - In most Runtime Applications, the Control Panel is hidden from the user. However, in some Runtime Applications, the user is allowed (by the designer of the Runtime Application) to get access to the Control Panel. You can now control which panes in the Control Panel should be visible in a Runtime Application

To set the visible panels, select the File, Workspace Properties menu option.

 

 

Documentation - Notable new Articles  - Several new notable articles have been added to the documentation. These articles are highlighted here:

 

 

Consuming SOAP Services - Sample Service - Alpha Anywhere now has a sample WCF service that you can host locally. This makes it very easy to test how to consume a SOAP service from Xbasic.

 

Watch Video
 

You can automatically install and run the sample, locally hosted, service when you create a new Web Reference client at the Web Control Panel, as documented in the steps below:

 

 

1. Click on the New button when the Web Services category is selected.

 

 

2. Click the Create a new definition to consume a SOAP web service button.

 

 

3. Select the Sample WCF Service item from the dropdown when you click on the Insert Sample hyperlink.

 

 

 

 

UX And Grid Components - Friendly Dates - String Customization  - You can now customize the strings used to display 'friendly dates' (e.g. a friendly date might display 'today' by default, but you might want to customize this so that it displays in the user's language of choice).

You can now customize all of the strings used in friendly dates by setting the Friendly dates customization property. You can use language and text dictionary tags in the customized strings.

 

 

 

UX Component - List Control - Fields - Security Groups and Server-side Show/Hide Expressions - When you define a List control, the List Builder allows you to specify security groups and server-side show/hide expressions for any of the fields in your List's data source.

A clarification has been added in the builder explaining that these settings only apply to fields used in a Column List layout. They do not apply in a Freeform layout. Furthermore, these settings only control whether a particular column in the List layout should be shown or not -- they do not affect the data that are sent from the server to the browser. (So, for example, if you have set a security setting on (say) the 'salary' column, the 'salary' column will be hidden in the List, but the List data that is sent from the server to the browser will still include the salary data).

If the List is based on a SQL query, then if you have defined security groups or show/hide expressions for any field in the List data source, when you close the List Builder a new dialog (shown in the image below) will appear asking if you want to copy your security and show/hide settings to the Data Source tab. The advantage of doing this is that the security and show/hide will be applied at the query level (meaning that in the above example, the salary data will not be included in the List data that is sent from the server to the browser).

 

 

 

 

UX Component - PhoneGap - iPhoneX - Sample Template - Styling a PhoneGap application so that it looks good on an iPhoneX can be tricky. A new sample template for UX components is available to help you get you styling right.

When you create a new UX select the PhoneGap - iPhone X Styling template.

 

 

 

PhoneGap  iPhone X - Important information about styling an iPhone X application so that it appears full screen has been added to the documentation. The article can be accessed from this link. If you are building PhoneGap apps for iPhone X, this article is essential reading.

 

PhoneGap Builder - Hot Topics Link - The PhoneGap builder now has a new hyperlink that opens the 'Hot Topics' documentation in the Help System. The PhoneGap ecosystem is in constant flux. As Adobe updates the PhoneGap build service from time time time, things that used to work may not work the same way or plugins that used to work may no longer be working. The Hot Topics document in the Help System helps you stay on top of the changes to PhoneGap and alerts you to things you might need to do in your PhoneGap projects.

 

 

 

 

UX Component - Bind Controls Dialog - The Bind Controls to Fields dialog is now easier to work with (especially for UX components that bind a large number of fields) because the dialog now allows you to filter and sort the data shown in the table.

 

 

 

UX Component - Map Control - Action Javascript - Compute Distance and Travel Time Between Points - A new action type has been added to the Google Maps Methods action. The action is called Get distance and travel time between points. It takes an array of addresses (either strings or longitude/latitude values) and computes the distance and travel time between each set of points in the array.

Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

 

 

The builder for the action is shown below. You can either pass in a start and end address or multiple addresses.  In the case where you select MultipleAddresses you must specify the name of a Javascript function that will return an array of addresses. For example, if your function returns an array with these addresses:

 

['address1','address2','address3']

 

the action will compute the distance and travel time between:

The action is asynchronous, so when all values have been computed, a callback function is called. You can specify the Javascript run run in the callback function in the onReady Javascript property.

In your Javascript you can reference an array called data that has an item for each address pair. Each item in the array has these properties:

 

In addition you can reference these variables:

 

 

Control Panel - Contains optimizations to improve the way in which the Control Panel is rendered

 

UX Component - PhoneGap - Instant Update - Quick Build - If your PhoneGap project has turned on the Instant Update feature, a new button appears on the Web Projects Control Panel toolbar that allows you to quickly build an Instant Update without having to bring up the PhoneGap Genie. All modal dialogs normally displayed when an Instant Update is built are suppressed.

 

UX Component - Action Javascript - Map Control - Plot Route - A new action in Action Javascript - Google Map Method makes it easy to plot a route on a map and get directions (either driving, walking or bicycling).

 

 

 

The builder for the new Plot route action is shown below:

 

 

 

The Type property can either be StartAndEndAddress or MultipleAddress. If you select StartAndEndAddress you can either enter address for the start and end (e.g. '36 Bigelow St. Cambridge MA') or latitude/longitude values (comma delimited (e.g. 42.3685632,-71.1045822). You can also specify the name of a Javascript function to return the start and end address. To use a Javascript function, specify the address as:

javascript:name_of_your_function

 

If you select MultipleAddress option, then you must specify the name of a Javascript function. This function must return an array of addresses. Each address in the array can either be an address or a lat/lng value (comma delimited).

 

 

 

Bugs

Reports - PDF - Watermark - Fixed an issue where settings for PDF watermarks were not being honored under certain conditions.

fedex_delivery_status() Function - Fixed this function.

 

Grid Component - Search Part - Checkbox - Fixed a regression where a search using a checkbox control combined selected options using AND rather than OR.

SQL Server Reporting Services Reports - Multi-select Parameters - Numeric Stored Value - If a SSRS report had a multi-select parameter that had a numeric stored value (i.e. the parameter displayed a list of string values, but each string value had a numeric stored value), the report could not be displayed by Alpha Anywhere.

SQL Auditing - The SQL Audit feature was not correctly inserting the name of the Grid that was used to edit a table when the component was run in live mode. In Working Preview, it worked correctly. Also, the audit feature was not inserting the connection string into the Audit Table. You will need to recreate the Audit Table to get the fix for the connection string.

 

 

 

Alpha Anywhere V4.5.4 - Build 5028-5088 19-APR-2018

 

Videos

Auditing Auditing Table Edits In many applications it is desirable to keep track of every edit made to a SQL table so you can know what fields were changed, who made the edit and when the edit was made. This is often achieved by added update, insert and delete triggers to the SQL database. But in cases where it is not possible to modify the database, you can use the built-in auditing feature in Alpha Anywhere.

In this video we show how the auditing feature is set up and used.

Watch Video

In cases where updates to SQL tables are made in your own Xbasic code (as opposed to from UX and Grid components), it is necessary to manually update the audit log. In this video we show how this is done.

Watch Video - Part 1
Watch Video - Part 2


Date added: 2018-15-06

 

 

Features

 

Auditing  - You can now enable an auditing feature to keep track of all edits made to SQL tables in an application. Information about each Insert, Update and Delete is kept in the Audit table. This table keeps track of the type of edit, the user id of the person making the edit, the name of table that was edited, and the old and new value of each field that was edited.

Watch Video

 

To turn on the Auditing feature, go to the Project Properties dialog in your Web Project (click the Project Properties button when the Web Control Panel has focus) and then check the Keep track of edits to tables made through Grid and UX components property.

 

 

Once you do this, you will be able to specify the connection string to the database where the Audit table is stored. You can either map an existing table, or create a new table.

 

 

By default, the User Id of the user who made the edit to a table is obtained from the Alpha Anywhere security framework (by evaluating the context.security.currentUser expression). However, if you are not using the Alpha Anywhere security framework, you can define a custom expression to get the user id of the person who made the edit.

 

In the case where you are making updates to SQL tables in your own Xbasic code, you will need to manually update the audit log table. There are two helper function in Xbasic to make this easy:

 

For example, the following code updates a table and also updates the audit log

dim cn as sql::Connection

cn.open("::Name::Northwind")

dim args as sql::arguments

args.add("primaryKey","ALFKI")

args.add("title","Manager")


dim sql as c
sql = "update Customers set title = :title where CustomerID = :primaryKey"

'capture the BEFORE update values
dim dataJson as c
dataJson = a5Helper_getAuditInfoFromSQLStatement(cn,sql,args.xml)

flag = cn.Execute(sql,args)

'write to the auditing table
a5Helper_writeToAuditingLog(cn,"Update",dataJson,"CustomerID","ALFKI")
 

TIP: The Audit table can grow to be very large in a large application used by many people. You might want to implement a strategy to purge old records from the audit table from time to time.

Alpha Anywhere Server for IIS - Redis is now an option for the Session State Provider in a publish profile.
 




The configuration settings are as follows:
 


JIT session locking can also be set.

The option will only appear on the profile property sheet.

 





It is also only available for the Redis provider.

The SecurityConfiguration object has a new property JitSessionLock that when set to true and the new AddSessionStateProviderRedis() is called, will configure to use the JIT session state wrapper with the Redis session state provider.

 

UX Component - Action Javascript - PhoneGap - TouchID/FaceID Action - A new action in Action Javascript allows you to easily use features in the PhoneGap TouchID plugin.

 

Bugs

UX Component - Reports - CurrentListFilter() - Fixed an issue when using the special CurrentListFilter() function an a report filter if the List was a parent of another List with pre-fetched data.

UX Component - Detail View - PhoneGap - Image Capture for List Detai View - onImageCapture Event - Was not firing if the capture method was set to PhoneGap.

Reports - Report Server - Images - PDF Reports - If you have a report with images in the data, then when printing the report to PDF from a web application, the images did not appear in the PDF. This problem does not happen if you turn off the Report Server (from the Project Properties dialog). The problem also does not affect the IIS server, or Alpha Cloud as neither of these use the Report Server. This issue is now fixed.

Web Applications -- IIS Server - Workspace reports, labels and letters are now all allowed if component security if turned off.

TabbedUI - Running a TabbedUI in build 5007 that had been created in an older build caused a Javascript error in certain cases.

 

 

Alpha Anywhere V4.5.3 - Build 5009-5081 10-APR-2018

Web Applications -- IIS Server - Workspace reports, labels and letters are now all allowed if component security if turned off.

TabbedUI - Running a TabbedUI in build 5007 that had been created in an older build caused a Javascript error in certain cases.

Alpha Anywhere V4.5.3 - Build 5007-5081 09-APR-2018

 

Videos

UX Component - PhoneGap Using the Instant Update Feature in a PhoneGap Application After you have created a PhoneGap application from a UX component, if you subsequently want to update the application you need to go through the entire release cycle again (i.e. submit to PhoneGap Build, then submit to the appropriate App Store). However, if you enable the Instant Update feature when you build your application in the first place, you can make certain types of updates to your application without having to go through the release cycle again.

Instant Update can be used as long as you are not changing the PhoneGap plugins used by your application, or the splash screens, etc. You can perform an Instant Update on an application as long as the changes to the application are limited to changes in the application's UX component.

In this video we show how the Instant Update feature operates.

Watch Video - Part 1
Watch Video - Part 2

Date added: 2017-12-24
Grid Component - Alphabet Button Search Adding Bubble Help with Record Counts to Buttons in Alphabet Button Search Bar The Alphabet Button search bar in a grid is a convenient way for searching for all records where a field starts with a particular letter. It can be useful for the user to know how many records are in each group before they actually press the button to execute the query.

In this video we show how bubble help is added to each button in the Alphabet button search bar. When the user hovers the mouse over the button, the bubble help shows how many records are in the group.

Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

Download component

Date added: 2017-12-31
Reports Alternating Background Colors for Records in the Detail Section It is common in reports to print alternating rows in the report's Detail section with different background colors.

This video shows how this is done.

Watch Video

Date added: 2018-02-01
UX and Grid Components Display Date and DateTime Values using Formatted Text Date and datetime values are easier to comprehend when they are formatted in a 'friendly' manner (e.g. today, in 1 hour, tomorrow).

In this video we show how you can display date and datetime values using 'friendly text' in a Grid and UX component.

Watch Video

Date added: 2018-02-04
UX Component ViewBox - Client Side Reporting Using the ViewBox control, it is possible to create highly stylized client-side reports. In this video we build on a previous view in which a sample Invoice report is created. The video shows how you can configure the report to allow the invoice line-items to be collapsed (i.e. hidden) or expanded. The video also shows how you can add a button to the report to generate a PDF file for the report.

Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

Date added: 2018-02-10
UX Component Mobile Date Picker In a mobile app, the standard date picker control that the UX uses may be too big for the screen. In this case, it might be desirable to use a date picker that is more tuned to a mobile application, such as a control that uses Spin Lists to select the month, day and year.

In this video we show how to use Spin List controls to edit the value in a date field.

Watch Video

Download component

Date added: 2018-02-23
UX Component - List Control Displaying Friendly Dates in a List Control The data picker control allows you to display dates in a friendly format (i.e. today if the date is today's date).

In this video we show how date values displayed in a List control can be displayed in a friendly format.

Watch Video

Download component

Date added: 2018-02-23
UX Component - ViewBox Control
Using a ViewBox to Create Nice Looking Email Messages The ViewBox component can create beautifully styled HTML by merging data into a template to create a customized, styled HTML document. You might want to email the contents of the ViewBox to someone as an HTML message.

In this video we show how a ViewBox can be used to create some nice looking HTML output (by merging JSON data for a customer's order into an HTML template) and then sending the resulting output as an HTML email.

Watch Video - Part 1
Watch Video - Part 1

Download component

Date added: 2018-03-02
UX Component - ControlBar Control Scrolling disclosure menus A common practice when building ControlBars is to have a button on a ControlBar that displays a menu that slides in from the left or right. The menu can be implemented using a List (which is inherently scrollable), but can also be implemented using a disclosure (which is a much simpler solution).

In this video we show how the disclose menu can be made to scroll.

Watch Video

Date added: 2018-03-27
Salesforce Creating a Salesforce Connected Application Before you can work with Salesforce data in an Alpha Anywhere application, you must first define a new Connected Application in your Salesforce account and a Named Resource in your Alpha Anywhere Web Project.

This video walks through the process of creating a Salesforce Connected Application

Watch Video

Date added: 2018-04-06
Salesforce Creating a Named Resource Provider Before you can work with Salesforce data in an Alpha Anywhere application, you must first define a new Connected Application in your Salesforce account and a Named Resource in your Alpha Anywhere Web Project.

This video walks through the process of creating a new Named Resource Provider in your Alpha Anywhere web project.

Watch Video - Part 1
Watch Video - Part 2


Date added: 2018-04-06
Salesforce Making REST API Calls Then SalesforceAPIRequest() function makes it easy to make REST API requests to the Salesforce API. You can either make a request directly against an endpoint documented in the Salesforce API documentation, or you can use the Salesforce SQL like query language, SOQL, to execute queries.

In this video we show both uses of the SaleforceAPIRequest() function.

Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

Date added: 2018-04-06
Salesforce Creating a Connection String You can create a Salesforce connection string (just as you create connection strings to point to SQL databases) that then allows you to treat Salesforce as a data source for a component, or a control.

In this video we show how a Salesforce connection string can be defined and then used to create a Grid component.
Watch Video - Part 1
Watch Video - Part 2

Date added: 2018-04-06
Salesforce Building a UX Component That Uses the Salesforce API In this video we show how a UX component can be built to display Salesforce data. The UX component does a query to retrieve the a list of accounts from Salesforce and it displays the result in a List control. When the user clicks on a row in the List, details for the selected account are shown by making another API request to Salesforce.


Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

Download component

Date added: 2018-04-06
Creating a REST API Creating a simple REST API You can create REST APIs in Alpha Anywhere to expose functionality defined in an Xbasic class or a Node API.

In this video we show how a simple API is defined.

Watch Video - Part 1
Watch Video - Part 2

Date added: 2018-04-06
Creating a REST API Passing parameters to a method In the previous video we showed how to expose a very simple method in a REST API. The method did not take any arguments. Typically most of the methods you expose in your API will take arguments. These arguments can be supplied to the method being called in various ways (as part of the request URL, in query parameters, in the request header, or in a POST body).

In this video we show how a method that takes a single parameter can be exposed in a REST API.

Watch Video

Date added: 2018-04-06
Creating a REST API Authenticating a method in a REST API When you create a REST API that exposes one or more methods, you might want to require that some (or all) of the methods exposed by the API should require some type of authentication before the call can be made.

In this video we show how to require authentication for certain methods in your API.

Watch Video - Part 1
Watch Video - Part 2

Date added: 2018-04-06
Creating a REST API Auditing an API You can use the audit feature when you create a REST API to keep track information such as how often a particular endpoint is called, how long each method takes to execute. You might want this information so you can implement some type of rate limiting for you API to ensure that it is not being abused.

In this video we show how you can define methods to audit the use of your API.

Watch Video

Date added: 2018-04-06
Creating a REST API Defining the Encoding for the Body Data A common use case for an API is to create a new record in a database or to update an existing record in a database. In these cases, the request will typically be a POST and the data for the new or updated record will be in the request body. The data in the body can either be FORM or JSON encoded.

Watch Video

In this video we will show the difference between FORM and JSON encoding the body data.

Date added: 2018-04-06
Creating a REST API Returning Complex JSON Data In this video we show how to create a REST API that returns complex JSON data for a customer. The API will return data about a particular customer, including all of the orders placed by that customer, and for each order, all of the line items in that order. The data will come from querying the sample Northwind database. The video shows an example of the type of complex data that a REST API is often designed to return.

Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

Download files

Date added: 2018-04-06
Creating a REST API Importing a Swagger Definition When you create a REST API you can either start by defining an Xbasic Class that defines the methods you want to expose in your API, or you can start by importing a Swagger definition for the API. Swagger is an open source standard for describing REST APIs. When you import a Swagger API definition, Alpha Anywhere will create a stub Xbasic class that you can then edit.

In this video we show how you can import a Swagger definition.

Watch Video

Date added: 2018-04-06

 

 

Breaking Changes

Web Applications - Active Directory  - As a result of changes in the way Active Directory authentication is now implemented, certain applications may need to be reconfigured. If an application uses Forms Based Active Directory for authentication and authorization (i.e. for users and groups) the Active Directory Configuration in the publish profile may need to be updated if the users are defined in one organizational unit and roles are defined in a different organizational units.

The Active Directory Configuration dialog now has an additional prompt for the organizational unit that specifies the groups used by the application. The input value is the distinguished name of the organizational unit. This prompt can be set to "All Organization Units" if groups are in the same hierarchy as specified in the LDAP connection string.



Given this Active Directory structure:


 

Company Domain (Domain)
    Users (Users)
        User1
        User2
        User3
    Car Division (OU)
        CarUser1 (User)
        CarUser2 (User)
        CarUser3 (User)
    House Division (OU)
    Application Division (OU)
        Group1 (Group)

            User1

            CarUser1
        Group2 (Group)

            CarUser2
        Group3 (Group)

            User1


 

And this LDAP connection string:

LDAP://ad.company.com/CN=Users,DC=ad,DC=company,DC=com

 

And a setting in the Organizational Unit for groups prompt of:

OU=Application Division,DC=ad,DC=company,DC=com

 

Then, anyone in Active Directory can login, but only users in an "Application Division" group (i.e. Group1, Group2, Group3) will have access to protected pages.


Next, assume the following LDAP connection string:


LDAP://ad.company.com/OU=Car Division,DC=ad,DC=company,DC=com

 

And assume that the setting for the Organizational Unit for groups  prompt is:


OU=Application Division,DC=ad,DC=company,DC=com
 

In this case, only users in the Car Division OU will be able to login. Only the users that are assigned to an "Application Division" group will have access to protected pages.

This change affects both the Standard Application Server and the Application Server for IIS.

 

 

Application Server - Cookieless Sessions - Support for cookieless session tracking has been removed from the Classic Application Server. This eliminates the small possibility that previously existed of "session hijacking".  Your application users must now support cookies in order to use sessions with the Classic Application Server.

 

 

Features

REST API - Creating - You can now create and publish REST APIs. Alpha Anywhere has always had the ability to consume REST APIs, but now you can also publish your own REST APIs.

For details on how to create and publish a REST API, click here.

Salesforce - Extensive support for working with Salesforce data has been added to the Alpha Anywhere. For complete details on how you can work with Salesforce data in an Alpha Anywhere application, click here.

 

PhoneGap Build - Instant Update - The Instant Update feature allows you to update a PhoneGap App that has already been installed on a user's device without needing to submit the App to the PhoneGap Build service after you have made changes to the App and without having to re-submit the App to the App stores.

As soon as the user launches the App on their mobile device, the App will be instantly updated to the latest version of the App.

 

Watch Video - Part 1
Watch Video - Part 2
 

The first time you create a PhoneGap App from a UX component, you are creating a Baseline for this application. The Baseline App must be submitted to the PhoneGap Build service, and must then be submitted to the appropriate App Stores.

After you make changes to the App, the PhoneGap genie will prompt if you want to do an Update build, a new BaseLine build, or Roll-back to a previous update.

NOTE: You can only use the Instant Update feature if you do not need to change any of the PhoneGap plugins used in your App. If you need to change PhoneGap plugins, you will need to create a new Baseline application.

If you select to do an Update build, the PhoneGap genie will determine which files in your project have changed (relative to the Baseline build) and will upload a changes file to a server (either an Alpha Software Amazon S3 bucket, or your own Amazon S3 bucket). When a user launches the App on their device, the App will automatically check if a new version is available, and it will instantly update itself to the new version.

If you release an Update to your App, and you find that this new version has introduced a bug, you can roll back to a prior version. When the user launches the App on their device, the App will instantly be downgraded to the specified previously released version.

To turn on the Instant Update feature, set the Enable Instant Update property to Yes.

 

Once you have enabled Instant Update the Instant update settings property is revealed

 

 

 

The options in this dialog are:

                    The current installed version number (shown when the App is launched)

                    App is running latest version message (if no update to the App is found)

                    App was updated message (if an update was found)

                    In Verbose mode, the user-defined After update message will also be shown.

                    Fatal errors are always shown.

 

 

How to Configure A Private S3 Bucket

The S3 bucket you specify must have a CORS policy set. Click the CORS Help hyperlink on the Instant Update Settings dialog for more information on CORS.

You will also need to set a bucket policy to set the objects in the bucket to allow public read. The policy can be set in the Amazon AWS management console and it will look something like this:

{
    "Id": "Policy1513279106848",
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1513279094040",
            "Action": [
                "s3:GetObject"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::your-bucket-name/*",
            "Principal": "*"
        }
    ]
}			
			
			
			

UX Component - PhoneGap Applications - {dialog.object}.instantUpdateCheckForUpdate() Method - This method allows you check if an update is available in a PhoneGap application that was build with the Instant Update feature enabled. Since this is an asynchronous operation, you need to provide the JavaScript success and the error callback functions.

If a result is returned within a 5 second time-frame, the successCallback is called and passed an object with a result property that will be either true or false. If true, an update is available. If a timeout or any other error occurs the error callback is passed an error object or a string, depending on the error.

This method can be useful if you have turned off auto updates and want to programmatically check if an update is available.

Syntax:

{dialog.object}.instantUpdateCheckForUpdate(_successCallbackFunction,_errorCallbackFunction);

 

Where

_successCallbackFunction - function to call if there is an update available

_errorCallbackFunction - function to call if there was an error checking for an update.

 

UX Component - PhoneGap - Instant Update - By default, if you build a PhoneGap App and you turn on the Instant Update feature, every time the App is launched in a device, the App will check if a new version is available. You can turn this default behavior off.

When you define your PhoneGap project, the Instant Update Settings dialog has a property called Automatically check for update when App is started. If you uncheck this property, then when the App is started, it will not automatically check for a new version.

 

 

 

 

Use the {dialog.object}.instantUpdateRefresh() method to force a check for a new version at runtime.

You can toggle this setting on or off at run-time using this method: {dialog.object}.instantUpdateUseAutoUpdate(true/false);
 

 

UX Component - PhoneGap Applications - Instant Update - URL For AJAX Callbacks - When creating an Instant Update to an existing baseline application, you can now change the URL for Ajax callbacks by checking the Change AJAX URL property in the image shown below.

When you press the OK button, the Genie will prompt for a new AJAX callback URL.

 

The AJAX callback URL is set in the PhoneGap builder when you create he baseline version of your application. When you create an update you might want to change this URL so that users who are still running an older version of your APP are still making callbacks to the original location, while users who are running the latest version of your App will make callbacks to a new location.

Another reason why you may want to change the URL for AJAX callbacks is that you simply want to move the location where your App is hosted. For example, you might be migrating from on premises deployment to deploying in the Alpha Cloud.

IMPORTANT: If you change the URL for AJAX callbacks be sure to also publish your App to that location!

 

 

UX Component - PhoneGap Applications - Instant Update - Version Numbers - When you create an Instant Update to a PhoneGap Application, each update is automatically give an internal version number. The internal version number is an integer that automatically increments each time a new Instant Update is created.

Now, you can also define your own version number for each Instant Update. The version number can use any numbering pattern that you want. (The Internal Version Number will also still be generated). In addition you can define a description for the Instant Update.

Your version number and description will make it easier if you need to roll back to a previous version to select the version to which you want to roll back.

 

 

UX Component - PhoneGap Applications - {dialog.object}.instantUpdateRefresh() Method - This method allows you to check for a new Instant Update version of an application without having to exit the App on the device and then re-launch it.

The method is only available in a PhoneGap application that was build with the Instant Update feature enabled.

Normally, after you publish an Instant Update to a PhoneGap application, users will not get the new version until they re-launch the application on their devices.

Using this method, you can get a new version of the application without have to exit and re-launch the application.

Syntax:

{dialog.object}.instantUpdateRefresh()

 

 

Xbasic - JSON_normalize() Function - Takes an array of JSON objects and "normalizes" the data to create an hierarchical JSON object.

For example, consider the following "un-normalized" JSON array:

 

[
{"name" : "john", "state" : "MA", "city" : "boston"},
{"name" : "fred", "state" : "MA", "city" : "boston"},
{"name" : "liz", "state" : "MA", "city" : "springfield"},
{"name" : "jill", "state" : "NY", "city" : "albany"},
{"name" : "sid", "state" : "NY", "city" : "manhatten"},
{"name" : "tammy", "state" : "NY", "city" : "manhatten"},
{"name" : "fran", "state" : "RI", "city" : "providence"},
{"name" : "tess", "state" : "RI", "city" : "providence"}
]

 

Notice that the "state" and "city" properties are duplicated in each array item.

You can use the JSON_normalize() function to produce the following "normalized" JSON:

 

			
[
    {
        "state": "MA",
        "_list_1": [
            {
                "city": "boston",
                "_list_2": [
                    {
                        "name": "john"
                    },
                    {
                        "name": "fred"
                    }
                ]
            },
            {
                "city": "springfield",
                "_list_2": [
                    {
                        "name": "liz"
                    }
                ]
            }
        ]
    },
    {
        "state": "NY",
        "_list_1": [
            {
                "city": "albany",
                "_list_2": [
                    {
                        "name": "jill"
                    }
                ]
            },
            {
                "city": "manhatten",
                "_list_2": [
                    {
                        "name": "sid"
                    },
                    {
                        "name": "tammy"
                    }
                ]
            }
        ]
    },
    {
        "state": "RI",
        "_list_1": [
            {
                "city": "providence",
                "_list_2": [
                    {
                        "name": "fran"
                    },
                    {
                        "name": "tess"
                    }
                ]
            }
        ]
    }
]
			
			

Syntax:

c jsonOut = json_normalize(c jsonIn, c groupingOptions)

 

Where:

In the above example, the command used to produce the normalized JSON is:

json_normalize(jsonin,"state,city")

 

This indicates that the first level of grouping is on the "state" property, and the second level of grouping is on the "city" property.

 

NOTE: The json_normalize() function is the reverse of the json_flatten() function.

 

UX Component - ControlBar - Disclosure Type - Template - A new type of ControlBar disclosure can now be created. The Template type allows you to create arbitrary HTML and inject placeholders for ControlBar items into the HTML.

Watch Video

For example, assume you have defined these ControlBar items: Button1, Button2 and Button3.

You can inject these controls into the HTML for the template using these placeholders: [Button1], [Button2] and [Button3].

The Template type is similar to the HTML disclosure type in that they both take an HTML template. There are however significant differences. The Template type is regenerated every time the disclosure is opened and you can inject ControlBar items into the template. The contents of the disclosure can be scrolled.

The HTML type is rendered once at the time the ControlBar is instantiated and you cannot inject ControlBar items into the HTML. The contents of the disclosure cannot be scrolled.

 

 

 

UX and Grid Components - Action Javascript - Open a Grid and Open a UX Actions - Ajax Failed Message - The actions to open a child UX or Grid have always allows you to specify a value for the Ajax failed message.  This message is displayed in the case of a failed Ajax callback (i.e. the server does not respond). Now you can execute arbitrary Javascript when the Ajax callback fails by specifying the Ajax failed message as

javascript:name_of_your_javascript_function

 

UX Component - Sample Template - MobileApp_HOST_UX_with_multiple_linked_child_UX_components - When you create  new UX Component, a new template is available.

This template shows a possible design solution for the use case where you have a parent table (e.g. customers) and you want to be able to display/edit an arbitrary number of tables related to a particular customer. For example, each customer can have multiple Order, Payments, Credits, Returns, Notes, etc.

The sample UX component shown in this template is analogous in concept to a Grid based on the Customer table with a row expander showing grids for each of the related child tables.

 

 

UX and Grid Component - Auto-suggest - Speed Improvement - By default the auto-suggest used the Upper() function in the SQL select statement to force the query to be case insensitive. However, on extremely large tables this resulted in a significant slow down and furthermore many databases already perform case insensitive queries by default so using the Upper() function was unnecessary.

Now, the Auto-suggest does not use the Upper() function in the generated SQL query, meaning that on those databases that perform case-insensitive queries the auto-suggest is case-insensitive and on those database that perform case sensitive queries, the auto-suggest is case sensitive. The resulting performance improvement on very large tables can be dramatic.

For those situations where you have a database that performs case sensitive queries, but you want the auto-suggest to be case insensitive, a new option in the Auto-suggest builder allows you to explicitly force a case-insensitive query.

 

UX Component - List Control - Detail View - Incremental Refresh - Timestamp Field - Normally, no schema changes are required to the database in order to perform an incremental refresh (i.e. there is no requirement that a timestamp field be added to the table).

An incremental refresh must compute which records on the server were changed since the last time the List was populated. In order to compute which records were changed the checksum (CRC) of the record contents of each record on the server is compared with the checksum of the corresponding record on the device. If the checksum is different, the record was changed and an updated version of the record is sent to the server.

However, a more efficient way of determining if a record was changed is to query for all records modified since the highest timestamp value the last time the List was populated.

Now, if you have a timestamp field in your table, you can direct Alpha Anywhere to use this field for Incremental Updates, rather than the CRC (checksum) method.

To direct the List to use a timestamp field for incremental updates, open the List builder and go to the Detail View pane.

Then check the Use a 'timestamp' field when performing an Incremental Refresh property and then specify the name of the timestamp field.

 

 

UX Component - List Control - Detail View - PhoneGap - Media Files - Ignore Folder - When a List is populated you can specify that all media files (images, videos, audios, etc.) that are referenced in the List should be downloaded to the device so that these media files will be available when the device is offline.

Now you can specify that any referenced media files that are in a folder in the PhoneGap bundle (i.e. in a subfolder inside the www folder of the PhoneGap project) should be ignored when the List computes which files must be downloaded from the server.

The following scenario will make the use case for this option clearer.

 

Assume that your UX contains a List control with this data in two of the rows at the time the PhoneGap project is built:

ID Name Image
1 Alpha myImages/image1.jpg
2 Beta myImages/image2.jpg

 

The myImages folder is part of your Web Project (i.e. it is stored in your Web Project folder) and it contains the files image1.jpg and image2.jpg.

 

When the PhoneGap app is built, the 'myImages' folder is included in the PhoneGap project (the PhoneGap Genie has a property where you can specify Additional Files to be included in the PhoneGap project). You would specify

myImages/*.*

for the additional files.

 

When the PhoneGap app is built, the myImages folder and all of the images in that folder become part of the PhoneGap application (i.e. the myImages folder will be a sub-directory in the www folder on the device) and the images in the List will still display because the Image field is pointing to a local file on the Device.

Now further assume that when you designed the List control you specified that Media files should be downloaded to the device. When you specify this property you specify the folder where the media files should be downloaded. You cannot specify that they should be downloaded to the www/myImages folder on the device as that is a read-only folder.

By default Alpha Anywhere suggests a folder for media file downloads called _AAFiles in a part of the filesystem that you designate.

When you refresh the List, Alpha Anywhere decides if the image must be downloaded by checking for its existence in the target folder (i.e. _AAFiles by default). So when it checks the first record, it will not find an image called myImages/image1.jpg in the target folder, and therefore it will attempt to download this file (even though this file is already in another folder on the device) from the server so it can be stored in the target folder.

Once the download is complete the filename in the Image field will be changed to point to the file in the target folder (i.e. the _AAFile folder).

However, by specifying which folders in the PhoneGap bundle to ignore, you can prevent Alpha Anywhere from downloading any images that are already on the device in the www/myImages folder.

To specify folders in the root www folder to ignore, open the List builder and go to the Detail View pane. Then open the Media files (photos, videos, audio recordings, other) settings dialog.

 

 

In this window, check the Ignore media files in www sub-folder property and then specify the folder name.

 

 

UX Component - List Control - Detail View - .addTableRowsBulk() Method  - Allows you to programmatically add multiple rows of data to a List with a Detail View.

The <listObject>.addTableRowsBulk() method allows you to add an array of new rows to the List.

NOTE: Using the .addTableRowsBulk() method is faster than calling the .addTableRow() method in a loop.

 

Example:

 

var listObj = {dialog.object}.getControl('LIST1');

var dataArray = [

    { FIRSTNAME: 'Cecelia', LASTNAME: 'DeLuca'},

    { FIRSTNAME: 'Cathy', LASTNAME: 'Marsh'}

]

listObj.addTableRowsBulk(dataArray);


 

TransForm - TransForm is a stand-alone service for building mobile, data collection forms (i.e. apps). To use TransForm you do not need an Alpha Anywhere license, but if you also have Alpha Anywhere, there are several features in Alpha Anywhere that make working with TransForm easier. To learn more about TransForm, click here.

To learn more about the TransForm features that are built into Alpha Anywhere, click here.

 

AlphaDAO - Update and Delete Operations - When you execute a SQL UPDATE or DELETE operation, if the WHERE clause does not find any records to operate on the SQL::Connection.execute() method currently returns .F.

However, some developers have requested that the SQL::Connection.execute() method should return .T. and treat the "no records found" condition as a warning and not an error. The SQL::Connection.callResult.rowsAffected property can be checked to see if any work was actually done.

In order to change the default behavior so that the "no records found" condition is a warning you can either manually update the connection string to add this property to the connection string:

A5ReportNotFoundAsWarning=Y

NOTE: This property is not exposed in the connection string builder.

Or alternatively, set a property on the connection object. For example


DIM cn as SQL::Connection
cn.ReportNotFoundAsWarning = .t.

 

 

Web Projects Control Panel - Component Dependencies - You can now right click on a component in the Web Projects Control Panel and select the Show dependencies for this component... menu item to see a list of component that this component calls and a list of components that call this component.

 

 

For example, this dialog shows that the Auto_Customers Grid component is called by the FlyingStartTabbedUI component and that it calls the Auto_Orders component.

UX Component - Builder - Live Preview - The Live Preview pane in the UX builder now lets you select if you want to use Internet Explorer or Chrome for Live Preview. Previously Internet Explorer was used and there was no option to use Chrome instead.

This is now similar to Working Preview which also allows you to select between Internet Explorer and Chrome.

 

UX Component - Arguments - Setting Values on the Client-Side - The value of arguments in a component are typically set on the server-side. Now, a new method - .setArgumentValue() -  allows you to set the argument value on the client-side. After an argument value has been set on the client-side, when the next Ajax callback occurs, the argument will have a new value when the server-side code is executed.

Syntax

{dialog.Object}.setArgumentValue(argName,argValue)

 

Where argName is the name of the argument you want to update. The argName must be uppercase and the argument name in the component definition must also be uppercase.

argValue is the new argument value. It is always a string value. If the argument was defined as being some other type, when the argument value is set on the server-side the value will be converted to the correct type.

UX and Grid Component - serverIsAvailable() Method - Performance - The performance of this method has been substantially improved. If the server is available, the response will be received significantly more quickly. This means that you can use a shorter timeout value in the method.

UX Component - Client-side Templating - Format Directives - New formatting options available for the client-side templates.

In all places where you can edit a client-side template, the Insert format directive hyperlink now shows two new options: 'Friendly' date format and Text format.

 

 

The available text formats are

 

If you select the 'Friendly' date format option a builder is displayed.

You can use click the Edit Date Format button to compose either a relative (e.g. 3 days ago) or calendar (e.g. this month) format.

 

 

The new 'Friendly' date formats are represented in the template as follows:

{date:dateRelative(precision,scope)}

{string:dateStringRelative(formatIn,precision,scope)}

{date:dateCalendar(type,showTime)}

{string:dateStringCalendar(formatIn,type,showTime)}

 

 

Xbasic Genie for SQL Actions - A new genie is available to help developers write Xbasic code that performs CRUD operations against SQL databases.

To access the genie, right click on white space while editing any Xbasic code.

 

 

 

The Xbasic SQL Genie screen is shown where you can select the type of SQL action you want to perform.

 

 

The screen below shows the genie for an UPDATE action.  The bottom half of the window shows the generated code based on the settings made in the top part of the screen.

 

 

Update to Security for HTTP Client Functions - The http_fetch(), http_get(), http_getpost(), and http_post() functions in Alpha Anywhere allow an optional SSL/TLS cipher list to be specified. This allows fine-grained control over TLS connection options when working with remote servers.

Some servers have recently begun rejecting connections from these HTTP functions because of their support for older, less-secure encryption ciphers. To address this, we have updated the default ciphers used when they are not otherwise specified.

These functions now use the cipher list from the httpd_defaultcipherlist() function. This is the cipher list used by the Application Server, and it is also suitable for clients.

 

UX Component - List - Detail View - Customization of Message Box - There are several message boxes that the List with Detail View displays.

The message text, title and icon for these messages can be customized in the Customization section of the Detail View pane in the List builder.

Now you can take complete control over these messages and call your own Javascript functions to display the messages.

 

 

In order to use a custom Javascript function for a message, set the message text to:

javascript:name_of_your_function

 

 

Note: If you write you own Javascript handler for any of these message boxes, you will be responsible for specifyin the Javascript to execute if the user selects the OK button (i.e. confirms, for example, that they want to revert the Detail View).

Web Control Panel - Keyboard Shortcuts - Ctrll+P can now be used to Publish a project and Ctrl+Q can now be used to invoke the Quick Publish command.

Web Applications - Active Directory - Performance of authentication against an Active Directory has been significantly improved.

Alpha Application Server - Self-signed Certificates - The way in which self-signed certificates has been changed. This will allow you to use the Development server with SSL turned on in Google Chrome.

 

Xbasic - handlebars_template_merge() Merge Function - Merges JSON data into a template using Handlebars syntax.

Handlebars is a popular, open source templating library.

This function takes JSON data and a template (that uses Handlebars syntax) and merges the data into the template.

NOTE: This is just a helper function for the low level nodeservices::handlebars.runTemplate() static method.

Example:

 

 

jsondata = <<%str%
{

    firstname:'Fred',

    lastname : 'Smith'

}
%str%

template = <<%str%
Hello {{firstname}} {{lastname}}
%str%

?handlebars_template_merge(template,jsondata)

 

= "Hello Fred Smith"

 

 

Xbasic a5_Create_PDF_From_Template() Function - A helper function for use in a Web Application. The function is used in an Ajax callback. It takes some JSON data, and a template, generates a PDF file from the result of merging the data into the template, and then returns the Javascript code necessary to download the PDF file to the client. The merge syntax can either be Handlebars, or the Alpha Anywhere client-side templating syntax.

Syntax

c JavascriptResult = a5_Create_PDF_From_Template(P e,c template ,c jsondata [,c  syntax = "AlphaAnywhere" [, c javascriptfunctions)


Where

IMPORTANT This function uses the Node PhantomJS module. This module is not installed by default (it is installed on Alpha Cloud so no action is necessary for Alpha Cloud) . You must install it by selecting to the Tools, Packages command then selecting phantomjs from the dialog. This will make PhabtomJS available while you are in development mode. You must also ensure that PhontomJS is available in your published application by going to the Web Project Properties dialog and then clicking on the smart field for Referenced Packages.

 

 

Example

Assume you have a button on a Grid or UX component that makes an Ajax callback. The purpose of the button is to generate a PDF confirmation that the client can download. Assume that the name of the Xbasic function that handles the callback is XBCallback. Here is how this function could be defined:

 

Function XBCallback as c (e as p)

 

dim jsonData as c = <<%txt%

{ Firstname: "John", Lastname: "Harris", amount: 23.45 }

%txt%

 

dim template as c = <<%txt%

<p>Dear {Firstname} {Lastname}</p>

<p>Thank you for your order in the amount of {amount:number('$#,##0.00') }

%txt%

 

dim js as c

js = a5_create_pdf_from_template(e, template, jsondata)

 

XBCallback = js

 

 

end function

 

 

UX Component - ViewBox Control - Partial Templates - A partial template is a template snippet that can be included in another template.  Partial templates are useful if your ViewBox defines multiple Layouts and each of these layouts contain parts that are the same across all of the layouts. The parts that are the same across all layouts would be defined as a partial template and then each layout can include the partial template with this template code

{*partial name_of_partial_template}

 

To define partial templates, select the Partial templates property on the ViewBox Properties tab.

 

 

 

 

Application Server for IIS - License Activation - A change was made in how the IIS Server license activation is performed. This change will improve performance for certain requests under the IIS server.

 

UX Component - HTML Editor - Image and File Upload - Amazon S3 - When you upload an image or a file from the HTML editor, you can now specify a storage connection string as the Upload Folder. If your connection string points to Amazon S3, the file will be uploaded to S3 and a URL pointing to the file on S3 will be injected into the HTML document you are editing.

This new option is especially important when running under the IIS server or on Alpha Cloud, because the option of uploading files to a folder in the webroot is not possible in these environments.

 

PhoneGap App Builder - PhoneGap Version - Added support for PhoneGap 8.0.0 which was recently added to PhoneGap Build. This version updates only the Android platform, although it is a major version update for Cordova Android from 6.3.0 to 7.0.0. The minimum Android API level required for PhoneGap 8.0.0 is 19 (KitKat) and only Gradle builds are supported. These properties will be set automatically within the PhoneGap Builder when you save or save and upload your project to PhoneGap Build when using PhoneGap 8.0.0.

If you have any trouble with plugins, you may need to use an older version of PhoneGap.

 

UX and Grid Component - Date and DateTime Fields - Date Picker - Friendly Value Display - For date and dateTime fields, you can now specify that the value should be displayed using 'friendly' text.

 

Watch Video

 

The 'friendly' text can either display the calendar value in text form (e.g. next Friday at 12:00​am, today, Thursday the 21st of February 2019) or in relative form (in 3 days, in 3 days 2 hours, in 45 seconds).

When you select a relative form the display value will automatically update at an appropriate frequency to make the passage of time. For example, if the initial display for a dateTime value is in 45 seconds, then the display will automatically update to in 44 seconds, in 43 seconds, and so on.

To turn on friendly value display for a date or dateTime field, check the Display value using friendly text? property.

 

 

Once you check this property the Friendly date display settings property will become visible. Click the smart field to open the builder as shown in the image below.

 

 

The builder allows you to make several selections to control how the value will be displayed and at the bottom of the builder you can check to see how various values will be formatted using the settings you have chosen.

 

For the Calendar option, you can specify 3 different formats that control how much detail is used in the display value (Abbreviated, Standard, Extended).

 

For the Relative option you can specify the date parts used in the display (i.e. the Scope) (Years, Months, Weeks, Days, Hours, Minutes, Seconds) and how many of these parts should be used in the display (i.e. the Precision)

 

For example, if you specify the full scope (Years to Seconds) and the full precision (-1) the relative a relative would be be displayed as:

"1 day 8 hours 50 minutes 6 seconds ago"
 

However, if you changed the precision to 2 the same value would be displayed as

"1 day 8 hours ago"

 

Javascript Library - Date Object - Several new methods have been added to the Javascript date object prototype allowing for powerful date formatting and calculations.

 

For full documentation see here.

 

Example:

Consider the following console session for a page that load the Alpha Anywhere Javascript libraries:

var d = new Date();
d.adjust('day',2);
d.toString();
"Sat Feb 03 2018 13:59:42 GMT-0500 (Eastern Standard Time)"
d.toRelative();
"in 1 day"
d.toRelative(2);
"in 1 day 23 hours"

 

Support for 4K Monitors - Improved support for 4K monitors has been added. Previously, some of the lists in various screen in the IDE would appear to be compressed. Now, these lists display normally. However, as a result of these changes, certain screens might not look as "sharp" they did before the 4K support was added.

You can use a new command line argument (-hidpi ) to turn off support for 4K monitors.

For example

alpha5.exe -hidpi

 

 

UX and Grid Component - Lookup Grid - Dynamic Filter - When you define a dynamic filter for a Lookup Grid you can now get the filter value from the result of a Javascript function. Previously you had to get the filter value from a control in the current row of the Grid (if the lookup was for a Grid field), or some control on the UX (if the lookup was for a UX field).

 

 

UX Component - Page Title - You can now set the page title property to a session variable.

 

UX Component - PhoneGap Applications - Changing URL for AJAX Callback at Run-time - When you build a PhoneGap application, the URL for AJAX callbacks is set at the time that you build the application.

You can now change this URL at runtime using the {dialog.object}._updateAjaxURL() method.

 

Syntax:

{dialog.object}._updateAjaxURL(newCallbackURL);
 

Example:

var newCallbackURL = 'https://www.myserver.com/v2';

{dialog.object}._updateAjaxURL(newCallbackURL);
 

   

printQRCode() Function - This function now has a new option to generate the QR code internally, rather than calling the Google API. Generating the QR code internally is substantially faster than using the Google API. The speed difference will be most noticeable in reports that call the prinQRCode() function many times.

Syntax:

 

Syntax

P result =  printQRCode(c value, sizeInPixels = 200, flagURLEncodeValue = .t., flagUseGoogle = .f.)

 

The sizeInPixels and flagURLEncodeValue parameter are ignored if the flagUseGoogle parameter is .f.

 

UX Component - Sample Template - A new sample template UX component is available. This template allows you to create a UX component that allows a site administrator to create new users and set user roles.

When you create a new UX, select this component from the available list of templates:

 

Here is what the component looks like at run-time:

Alpha Anywhere Server - A WARNING message will be written to the Xbasic error log when a query parameter name, etc, has a normalized name that is different from the original name. For example, a variable called 'First-Name' in a Post body gets converted to First_Name because First-Name is not a valid Xbasic variable name.
 

Xbasic - AlphaDAO - MySQL/MariaDB - Geography Queries - Portable SQL now generates the ST_Intersect() function instead of the Intersetct() function for queries that use the portable GeogLocationIsWithinPolygon() or GeogLocationIntersectsLine() functions.

PhoneGap App Builder - PhoneGap Version  - Added support for PhoneGap version cli-7.1.0. PhoneGap Build recently announced support for PhoneGap version cli-7.1.0. This release includes support for iOS 11.2 and includes Cordova iOS 4.5.4, Android 6.3.0 and Windows 5.0.0. This will resolve the plugin dependency issues with the latest plugins that require Android version 6.3.0 or greater. With the release of cli-7.1.0, PhoneGap Build should now support the latest Android plugins.

PhoneGap App Builder - Core Plugin Versions - All of the core PhoneGap plugins now include a version specification that is defined in an external file named phonegap_core_plugins.txt that is included in the PhoneGap folder of the directory that contains the Alpha Anywhere executable file. The versions specified are known to work reliably with PhoneGap cli-7.0.1 and greater. If you would like to load a different version of any core plugin, this file can be edited with any text editor. We suggest you make a backup copy of this file prior to editing.

Application Server - IIS - Crash Dump Files - In the event of a crash of Alpha Anywhere Application Server for IIS, a crash minidump file is written to the log folder. Each minidump file can have a unique name. Due to IIS' ability to recover from a crash, it may not be apparent that a crash has happened which may lead to the crash happening again causing another minidump file to be created. Since minidump files can be quite large, lots of disk space may be consumed. An IIS publish profile now has the ability to limit the amount of spaced used by minidump files and these settings are enabled by default.

 

 

These settings are also available for a published application in IIS Manager under the Logging feature in the Alpha Anywhere Application Server section:

 

 

 

 

Xbasic_execute_Javascript() Function - Execute Javascript code on the server side using the Javascript engine in Node.js

Syntax

p result = Xbasic_execute_Javascript(c jscode)



Where

If you want the Javascript code to return a value, the Javascript code must emit the value by specifying the name of the variable to emit as the last line in the Javascript code. See example below


dim js as c
js = <<%str%
var arr = [];
for(var i = 0; i < 1000; i++) {
    arr.push('String: ' + i );
}
var txt = arr.join('\n');

//we want to return the value of the 'txt' variable, so we emit it by specifying

//the variable name as the list line in the Javascript code
txt;
%str%


pr = xbasic_execute_javascript(js)
 

if pr.error = .f. then

    showvar(pr.result)

else

    showvar(pr.errorText)

end if
 

Alpha Anywhere Development Version - Built-in Version of Chrome - The AlphaAnywhere Development environment has been upgraded to build-in the latest version of Chrome. Previously an older version of Chrome was built-into Alpha Anywhere. As a result of this change certain Chrome features that were not supported in the old version of Chrome will now be available when using Chrome for Working Preview. In addition, Chrome Working Preview will be more responsive and the memory footprint used by the Development Version is reduced.

 

MFC Dependency - Starting with this build, Alpha Anywhere no longer has any dependency on the Microsoft MFC library. While the benefit of this to users may not be apparent, the benefit to Alpha Anywhere is significant and will result in new features that would not previously have been possible.

NOTE: This change should NOT have any effect on the Application Server (both the Classic and IIS servers).

 

UX and Grid Component - Javascript Actions - Duplicate Action - You can now duplicate Javascript actions.

 

 

 

Bugs

UX Component - List Control - Action Javascript - Filter List - When using Action Javascript to filter a List, the builder did not show the correct List of fields on which a search could be defined. The builder showed the fields in the underlying table(s) that the List was based on, rather than the fields in the query that the List was based on.

Grid Component - Alpha Theme - Buttons - Some buttons did not show the hover and pressed state.

Grid and UX components - Dynamic Images - Fixed a regression in dynamic images

Grid Component - Updateable Grid - Display Format and UnFormat Expressions - If an updateable grid had a Display Format expression defined for a column, then when the Grid was updated, the "old" value for that column was not first being "unformatted". As a result, the user would get a write conflict error when trying to update the field.

Grid Component - Export to Excel - Hidden Columns - Column Headings - If you have checked the option to use Grid Column Heading for columns in the Excel file, and you have also checked the option to export hidden columns, the hidden columns will now correctly use the defined Grid Column Headings.

Page Layout Component - Frames - Modern - Modern Frames were not rendering correctly.

IIS Server -- Lockout user until reset by administrator - This option did not work correctly

 

.DBF Tables - Export - SQL Server - Fixed a bug exporting .dbf tables to SQL Server.

UX and Grid Component - Javascript Syntax Checker - No longer reports an error if your Javascript code deletes a variable.

UX Component - Slider - Multi-Valued Sliders - Fixed issue when both min and max buttons were at the max value. User could not drag button to a new value.

Grid and UX Component - SVG Icons - Fixed issue with events and styling on SVG icons.

PhoneGap - InstantUpdate Feature - Fixed an issue where if you installed an app on a device that used the Instant Update feature, and you then created a new baseline app and installed it on the device without first uninstalling the original version of the app, the original version of the app (not the new version), would continue to run.

Grid, TabbedUI and UX Components - SVG Icons - onClick Event - Fixes a bug with the onClick event on an image that uses a SVG icon.

TabbedUI and PageLayout Components - Modern Frame - Show/Hide Button - Fixes a bug that was introduced in the last official update. You will need to edit the component and recalculate the controls.

UX Component - ViewBox refresh - Fixes a bug with the refresh ViewBox data option. This bug was introduced in the previous release.

Alpha Launch - UX Components - Auto-suggest Controls - Fixed an issue where Auto-suggest controls did not work in applications that were running in Alpha Launch.

UX Component - ExpandingMenu Control - Menu Data Genie - Fixed several problems when using the Menu Data Genie to define the choices shown in the ExpandingMenu control.

Tips

UX Component - Drag Scrolling vs. Vertical Scrollbar - Web Applications - In some cases you might have a UX with a Panel Card that contains more content than can be displayed in the Panel Card. Vertical scrolling is required to see the content that is not initially visible. On a mobile device, the user will scroll using drag scrolling.

In a web application, you want the user to see a vertical scroll bar.

However, if you are running the web app on a machine that is touch enabled, then drag scrolling will be enabled, and the vertical scroll bar will not be visible.

Here is how you can force the app to show a vertical scrollbar:

In the client-side onInitializeBegin event: add this code:

if( [condition you want to not drag scroll] ){
    A5.u.drag.useDragScrolling = 'never';
}

 

 

UX Component - List Control - Capture and Restore the List's Scroll Position - In some applications it might be necessary to restore the List's scroll position without actually selecting a row in the List. For example, a List may have been scrolled to a certain position, but no record in the List has been selected. A refresh operation on the List is performed, and now you want to scroll the List back to its previous position.

 

Here is how you can do this (assume that the List ID is 'LIST1'):

 


//capture the scroll position
var eleID = {dialog.object}.getControl('LIST1').contId + '.CONTENTWRAPPER';
var obj = A5.u.element.getScroll(eleID)
{dialog.object}._scroll = obj;


//restore the scroll position
var obj = {dialog.object}._scroll
var eleID = {dialog.object}.getControl('LIST1').contId + '.CONTENTWRAPPER';
A5.u.element.setScroll(eleID,obj.left,obj.top);

 

 

 

 

Xbasic - Working with .Net Arrays


Zero-based versus One-Based Indexing
By default, XBasic arrays are indexed using one-based indexing. This means that the items in the array are referenced using indexes beginning with one (1) for the first entry and continuing on with 2, 3, 4 and so on.

Other environments, including .Net arrays and collections, use zero-based indexing. This means that the first item in the array is referenced with an index value of zero (0) and continues on with 1,2,3 and so on.

When accessing an array or collection in .Net from XBasic, Alpha Anywhere automatically maps one-based indexes in XBasic array references (square brackets – “[]”) to zero-based indexes. This removes the need to remember whether an array reference is for an XBasic array or a .Net array or collection.
 

XBasic Square Bracket References


XBasic Function Calls

 


Example Usage

The interactive wndow session below now shows accessing the System::Data::DataSet Tables collection using the Item property with a numeric or string index:

 

dim ds as system::data::dataset
t1 = ds.Tables.Add("Fred1")
?t1.TableName
= "Fred1"
t2 = ds.Tables.Add("Fred2")
?t2.TableName
= "Fred2"
Tables = ds.Tables.Count
for i = 1 to Tables ; ? ds.Tables.Item[i].TableName + crlf(); next
Fred1
Fred2
?ds.Tables.Item["Fred1"].TableName
= "Fred1"
?ds.Tables.Item["Fred2"].TableName
= "Fred2"

 

 

 

Alpha Anywhere V4.5.2 - Build 4770-5018 14-DEC-2017

NOTE: This build has introduced a bug in the Javascript Action to refresh the data in a UX Component ViewBox control. After you install this update you can install a hotfix for the bug by downloading this file. Click here for instructions on how to install a htofix.

 



 

Videos

UX Component - Tree Control Populating a Tree Control using a SQL Query and Defining a Javascript Event for Each Tree Leaf Node The Tree control can be automatically populated with data derived from a SQL query. When doing this it is common to want to execute some Javascript code when the user selects a leaf node in the tree.

In this video we show how this is done.


Watch Video

Download component

Date added: 2017-11-02
UX Component Selecting Multiple Values in an Auto-suggest or Edit Combo Control The Auto-suggest and Edit Combo controls have always allowed you to set a mode where multiple selections can be made. However, each time you make a selection the pick list is closed and you must reopen the pick list before you can make your next selection.

Now, a new property in these controls allows you to specify that the pick list should stay open after each selection, allowing you to make multiple selections more easily.


Watch Video


Date added: 2017-11-15
UX Component - ControlBars Using the Built-in ControlBar Templates The ControlBar is highly configurable. This allows you to create solutions for many different use cases. There are several common patterns that developers use and for many of these patterns you can get a quick start by selecting one of the pre-defined ControlBar templates. For example, common patterns addressed by the pre-defined templates are:ControlBar with a menu button that animates in a menu from the left or right side of the Panel, ControlBar with buttons that reveal animated drop-down menus, ControlBar with buttons that allow you to create a tabbed user interface.

In this video we show how you can create a new ControlBar from a template and then continue to modify the resulting ControlBar.

Watch Video

Date added: 2017-11-28
UX Component Sample UX Component - Amazon Mobile Shopping Look Alike Example The Amazon mobile shopping App is one of the most recognizable mobile Apps. In this video we show how the look and feel of this App can be recreated using the UX component.

Open the App in a Browser

Watch Video - Overview

How the Products List is Populated
Watch Video
How the Back Button in the ControlBar is Implemented
Watch Video
How the Badge on the Shopping Cart Icon is Implemented
Watch Video
How the Search Box is Implemented
Watch Video
How the Product List Layout is Implemented
Watch Video 1
Watch Video 2
How the Detail View is Implemented using a ViewBox Control
Watch Video 1
Watch Video 2
Watch Video 3

Date added: 2017-12-13
     

 

 

 

Features

Application Server for IIS - Unlicensed Mode - The Alpha Anywhere Application Server for IIS is will now run in unlicensed mode. Five users can be active on an unlicensed server allowing development and testing to be done without needing a license. If more users are needed or the server is running in production a license is required.

This change brings the Application Server for IIS in line with the Standard Application Server for use in development and testing.

You can download the installer for the Application Server for IIS here.

 

Application Server For IIS - Installer - Pending Reboots - When you run the installer for the Application Server for IIS the installer will now warn you if your machine has any pending reboots mandated by previously installed Windows, or other, updates.

UX Component - {dialog.object}.refreshExpandingMenuData() Method - This method makes an Ajax callback to refresh the data in an Expanding Menu. This method is useful if the Expanding Menu control has assigned security or server-side show/hide expressions to any of the branches or nodes in the data for the expanding menu.

For example, after a user has logged into an application, you might want to use this method to refresh the choices shown in the expanding menu so that only choices for the user's role are shown.

Syntax:

{dialog.object}.refreshExpandingMenuData(expandingMenuIds);

 

Where:

 

UX Component - {dialog.object}.{dialog.object}.populateExpandingMenuControl() Method - This method will repopulate the data shown in an Expanding Menu control.

Syntax:

{dialog.object}.populateExpandingMenuControl(id,data)


Where:

 

Example:

				

var obj = {dialog.object}.getControl('EXPANDINGMENU1');
var data = {
	items:[
		{
			html: 'Category 1', 
			value: 'category1',
			icon: 'svgIcon=#alpha-icon-addCircleBorder:icon,24',
			action: '',
			children: [
				{
					html: 'Action 1', 
					value: 'action1',
					action: 'action:1',
					icon: 'svgIcon=#alpha-icon-bandAidCrossed:icon,24'
				},
				{
					html: 'Action 2', 
					value: 'action2',
					action: 'action:2',
					icon: 'svgIcon=#alpha-icon-bellRing:icon,24'
				}
			]
		},
		{
			html: 'Category 2',
			value: 'category2',
			action: '',
			icon: 'svgIcon=#alpha-icon-heartSolid:icon,24',
			children: [
				{
					html: 'Action 4', 
					value: 'action4',
					action: '',
					icon: 'svgIcon=#alpha-icon-map:icon,24',
					children: [
						{
							html: 'Action 4a', 
							value: 'action4a',
							action: 'action:4a',
							icon: 'svgIcon=#alpha-icon-trendingDown:icon,24'
						},
						{
							html: 'Action 4b', 
							value: 'action4b',
							action: 'action:4b',
							icon: 'svgIcon=#alpha-icon-trendingDown:icon,24'
						}
					]
				},
				{
					html: 'Action 5', 
					value: 'action5',
					action: 'action:5',
					icon: 'svgIcon=#alpha-icon-trendingDown:icon,24'
				}
			]
		},
		{
			html: 'Category 3', 
			value: 'category3',
			action: '',
			icon: 'svgIcon=#alpha-icon-shield:icon,24',
			children: [
				{
					html: 'Action 7', 
					value: 'action7',
					action: 'action:7',
					icon: 'svgIcon=#alpha-icon-shuffle:icon,24'
				}
			]
		}	],
	actions: {
		action: function(arg){
			alert('Action' + arg);
		}
	}
}
{dialog.object}.populateExpandingMenuControl('EXPANDINGMENU1',data);
					
		

sql_upsert() Function - The sql_upsert() function is a high level Xbasic function that complements the sql_update() and sql_insert() functions. The sql_upsert() function will update a record if the record exists in the database. Otherwise it will insert a new record into the database.

Syntax

    p result = sql_upsert(A connection,c tablename,c fieldValuePairs [,c primaryKey [, a primaryKeyValue [, L execute [, P e ]]]])

 

Where

 

Example:

 


dim cn as sql::Connection

cn.open("::Name::myconnstring")
tablename = "mytable"
fieldsValuePairs = <<%str%
name=fred smith

date of birth=1952/12/18

salary=78000
%str%
 

'You can also specify field values using JSON
fieldsValuePairs = <<%str%

    "name" : "fred smith",
    "date of birth" : "1954/11/25",

    "salary" : "78000"
}
%str%

primaryKey = "id"
primarykeyValue = "1"

p = sql_upsert(cn,tablename,fieldsValuePairs,primaryKey,primaryKeyvalue)

 

Amazon Look Alike Sample Mobile Application - A new sample template is available. The Amazon look-alike sample mobile application is a sample Alpha Anywhere application designed to show how a familiar mobile app could be built using a UX component.

You can load the sample app in your web browser, or on your mobile device from this url:

http://alphamediacapture.s3.amazonaws.com/sampleamazonlookalikeapp/index.html

 

You can watch a video showing a quick overview of the application by clicking here.

 

NOTE: When you create a new UX Component, you can select this sample application from the list of template applications.

 

The images below show screenshots from various parts of the application:

 

 

 

Main App screen. This screen shows a List control listing the various products that can be purchased. Each row in the List is rendered using a freeform layout template that uses Alpha Anywhere's client-side templating feature to create a highly customized layout.

 

 

Navigation menu. The navigation menu is shown when the user taps on the menu icon in page header. The menu it rendered using the Expanding Menu control.

 

 

This is the Detail View for a particular product. This Panel is shown when the user taps on a row in the List. The ViewBox control is used to render the Detail View and the template that is used in the ViewBox control to render the Detail View makes extensive use of client-side templating features.

 

 

This is the scrolled view of the Detail View for a particular product.

 

 

This is the shopping cart showing a list of products that have been added to the cart. This Panel also uses a List control with a freeform Layout to display each row in the shopping cart.

Notice that the shopping cart icon in the header has a badge indicating how many products are in the cart.

 

 

This screen shows the page that is displayed when the user taps on the Quantity button on the product detail page.

 

After the user selects a quantity, the Quantity button on the product detail page is updated to show the selected quantity.

 

Understanding How the App Was Built

The entire App was built using a single UX component as shown in the image below.

 

 

The key building blocks of the app are:

 

The app structure is shown below:

 

 

Each 'page' in the App is contained in a Panel Card and the Panel Cards are contained in a Panel Navigator. The Panel Navigator has been configured as "Programmatic" - meaning that the user cannot swipe left-to-right, or right-to-left on a Panel to navigate to the next Panel. Instead Javascript code is used to control which Panel is shown in the Panel Navigator.

The Panels in the App are:

 

NOTE: This demo app is not a complete application.  It is only meant as a teaching tool to show how a compelling mobile user interface can be created using the UX components. For example, the navigation menu displays, but when you make a selection from the menu, the product list is not updated.

 

Videos Explaining How Various Features Are Implemented

 

How the Products List is Populated

    Watch Video

How the Back Button in the ControlBar is Implemented

    Watch Video

How the Badge on the Shopping Cart Icon is Implemented

    Watch Video

How the Search Box is Implemented

    Watch Video

How the Product List Layout is Implemented

   Watch Video 1

   Watch Video 2

How the Detail View is Implemented using a ViewBox Control

   Watch Video 1

   Watch Video 2

   Watch Video 3

 

JSON_shred() Function - This function has been enhanced. The input schema that describes how the JSON should be shredded is now optional. Also, the function can automatically inject linking values into the JSON if the JSON does not already have appropriate linking values. If the input schema is not specified then linking values are automatically injected.

The purpose of the JSON_shred() function is to take a complex JSON document (with one or more nested arrays) and decompose the JSON into multiple flat arrays, none of which have nested arrays.

The new syntax for the function is:

 C result =  JSON_shred(C json [,C schema [,C topArrayName [,L flagAddSurrogatePrimaryKey [,C surrogateKeyName ]]]])

 

Where:

 

Example:

dim json as c 
json  = <<%str%
[
    {"Firstname": "John", "Lastname" : "Smith", "City" : "Boston", "State" : "MA", "Children": [
        {"Name" : "Callie", "Age" : 5},
        {"Name" : "Griffin", "Age" :3},
        {"Name" : "Luke", "Age" : 1}
        ]
    }, 
    {"Firstname": "Henry", "Lastname" : "Rhodes", "City" : "New York", "State" : "NY", "Children": [
        {"Name" : "Howard", "Age" : 15},
        {"Name" : "Robert", "Age" : 11}
        ]
    }
]
?json_shred(json)

{
    "__top": [
        {
            "__surrogatePrimaryKey": "475750b196554658b2518fde4bfaec6e",
            "Firstname": "John",
            "Lastname": "Smith",
            "City": "Boston",
            "State": "MA"
        },
        {
            "__surrogatePrimaryKey": "c970381d48aa4abfa92d0f46d02ead27",
            "Firstname": "Henry",
            "Lastname": "Rhodes",
            "City": "New York",
            "State": "NY"
        }
    ],
    "Children": [
        {
            "ParentLinkingValue": "475750b196554658b2518fde4bfaec6e",
            "LinkFieldName": "__surrogatePrimaryKey",
            "__surrogatePrimaryKey": "16963be3261c4d82a50152dfb18f9ff0",
            "Name": "Callie",
            "Age": 5
        },
        {
            "ParentLinkingValue": "475750b196554658b2518fde4bfaec6e",
            "LinkFieldName": "__surrogatePrimaryKey",
            "__surrogatePrimaryKey": "556ed6b0264544bd93ebe1382578347a",
            "Name": "Griffin",
            "Age": 3
        },
        {
            "ParentLinkingValue": "475750b196554658b2518fde4bfaec6e",
            "LinkFieldName": "__surrogatePrimaryKey",
            "__surrogatePrimaryKey": "32558171e17c41f88dffc6594b4f73c3",
            "Name": "Luke",
            "Age": 1
        },
        {
            "ParentLinkingValue": "c970381d48aa4abfa92d0f46d02ead27",
            "LinkFieldName": "__surrogatePrimaryKey",
            "__surrogatePrimaryKey": "7ea305b5205844c5abde8728b68f08ae",
            "Name": "Howard",
            "Age": 15
        },
        {
            "ParentLinkingValue": "c970381d48aa4abfa92d0f46d02ead27",
            "LinkFieldName": "__surrogatePrimaryKey",
            "__surrogatePrimaryKey": "98ff8b3ccc1b4fa1a79bdee2620daee2",
            "Name": "Robert",
            "Age": 11
        }
    ]
}

%str%

 

Dynamic Storage Connection Strings - Storage - SQL Server Reporting Services (SSRS) - Alpha Anywhere has had the concept of dynamic connection strings for AlphaDAO connection strings for some time now. But dynamic connection strings for storage and SSRS did not exist. A dynamic connection string is particularly useful in multi-tenant SaaS applications. Now, you can define dynamic storage connection strings for both storage and SSRS.

A dynamic connection string will resolve differently based on a the value of a session variable.

To define a dynamic storage connection string, your named connection string must start with DynamicConnection_. For example: DynamicConnection_myS3Storage.

You must also have a session variable named

__protected__<name>

where <name> is the text to the right of DynamicConnection_ in the named connection string.

 

So for example, if your named connection string is:

DynamicConnection_myS3Storage

You would need a session variable called:

__protected__myS3Storage

 

When the named connection string is resolved, it will resolve to the value of the __protected__myS3Storage session variable.

 

Xbasic csv_to_json() Function - Escaping Doublequotes - This function now supports two different methods for escaping double quotes.

 

The default is use use two double quote characters. .e.g

"fred","smith","the ""computer"" store","boston"

 

But you can also use Javascript style escapement. e.g.

"fred","smith","the \"computer\" store","boston"

 

Syntax:

c json = csv_to_json(c csvtxt, c escapeMethodForQuotes)

 

Where:

 

 

UX Component - Frame Container - Modern Frames - If a modern frame container is configured to have a show/hide button, you can specify that if the current frame is opened and another frame is subsequently opened, the current frame will be closed.

 

 

UX Component - Mobile Applications - Panel Card - Drag Scrolling - Previously if you dragged on an input control in a Panel Card, the Panel did not scroll. Now, as long as you have not actually given focus to the input control (i.e. the keyboard has not come up) then the panel will still scroll.

 

 

UX Component - ControlBar Builder - User-Defined Templates - You can now save a ControlBar that you have designed as a template. Your user-defined templates will be listed when you click the Load Sample ControlBar hyperlink on the Home pane of the ControlBar builder.

 

 

To save the toolbar that you are currently editing in the ControlBar builder as a template, click the Save ControlBar as a Template hyperlink on Home pane of the ControlBar builder.

 

The dialog shown below will be displayed where you can give the template a name and a description. The description can use HTML markup.

 

 

After you have saved the template, you can save an image of how the ControlBar looks. The image filename that you must use is shown in the next dialog.

When you use the Load Sample ControlBar command the image you have saved will be shown in the list of available templates, making it easier to choose the template you wish to use.

 

 

 

Application Server - Publishing - The publish genie now has an option on the 'Clear Publishing History' button to clear the publish history for just the currently selected publish profile. The ability to clear all history is still available as an option.
 

UX Component - New Starter Template for Mobile App - A new starter UX template is available. The template, called MobileAppFramework_FlyInMenu_to_select_Active_Panel ) is a Panel Navigator, with multiple Panel Cards, and a Control Bar with a menu button that displays an expanding menu that flies in from the left.

 

 

 

Xbasic - Arrays - Change_type() Method - Changes the data type of an Xbasic array.

When you create an Xbasic array by parsing some JSON text, the array's type is set to 'A'. This is because a JSON array can contain items that are of different type.

For example, consider the following code

 

dim json as c

json = <<%txt%

[

    {name: "fred"},

    3

]

%txt%

 

dim p as p

p = json_parse(json)

 

If you were to check the type of p[1], (using typeof(p[1]) ), it would return 'P'.

However, if you were to check the type of p[2], it would return 'N'.

So the array elements in the array can be of any type. You can also dim an array where the items can be of any type like as follows:

dim array1[10] as A

 

Now consider a JSON string that defines an array in which all items are of the same type:

 

dim json as c

json = <<%txt%

[

    {name: "fred"},

    {name: "john}

]

%txt%

 

dim p as p

p = json_parse(json)

 

In this case all of the elements in the array are of type 'P'.

However, if you insert or append elements to the array, the new elements will be of type 'N' and not 'P' as you might have expected. This is because the internal type of the array is 'A' (as is always the case when an array is created by parsing a JSON string).

In some cases you will want to change the type of the array to a specific type so that items inserted into the array, or appended to the array are also of the same type as the other items in the array.

For example:

 

dim json as c

json = <<%txt%

[

    {name: "fred"},

    {name: "john}

]

%txt%

 

dim p as p

p = json_parse(json)

dim result as c

result = p.change_type("P")

if result <> "" then

    ui_msg_box("Error","Could not change array type: " + result)

end if

p.insert(1,1)

?typeof(p[1])

= "P"   '<<----- would have been 'N' had the .change_type() method not been called!

 

UX Component - ControlBar - ControlBar Builder - Pre-defined Templates - New pre-defined templates are available when you create a new ControlBar from a template and the template picker has been enhanced to show a preview of each template.

Watch Video

 

When you create a  new ControlBar, you can set all of the properties in the ControlBar by selecting a template (i.e. sample ControlBar). To select a template, click the Load Sample ControlBar hyperlink on the ControlBar builder Home pane.

 

 

When you click the hyperlink a window showing the templates is shown:

 

 

 

 

UX Component - ControlBar - DisclosureButtons - Disclosure Position - Three new disclosure positions are now available: flyout, flyout-element and flyout-element-cover. Using these positioning directives, it is possible to create controlbars with dropdown menus. See example below.

 

 

 

 

In the image below, the button on the toolbar opens another disclosure positioned using the flyout-element position.

 

 

 

NOTE Sample ControlBars that use the new flyout-element position directive can be seen by selecting the Load Sample ControlBar hyperlink on the ControlBar builder Home tab.

 

sql_import() function - Upsert - The SQL_Import() function is a helper function that imports new records into a SQL table. It is called a 'helper' function because it is an alternative to writing the low level Xbasic AlphaDAO commands to import data. This function now supports both 'insert' and 'upsert'. An 'upsert' performs an update on existing records and an insert if there is no existing record.

The syntax for the function is now:

p result = sql_import(connectionString as c, tableName as c , tableOwner as c, csv_or_json_data as c , replicateIdentity = .f., inputfield_to_sql_table_column_map = "", action="insert", primaryKey = "")

 

Where:

 

 

Example

p = sql_import("::name::myconnstring","table1","","c:\data\datatoimport.xlsx",.f.,"","upsert","id")


 

UX Component - List Control - Freeform Layout - List Item Footer - Freeform layouts now support the List-item Footer property. The state of the list item footer can be toggled on each row from open to closed, or vice versa using the <listObject>.toggleRowExpander() method.

 

UX Component - Multi-select Token Control - Keep List Open - A new option has been added to the Multi-select Token Control to keep the pick list of choices open after the user makes a selection.

 

UX and Grid Components - Arguments - Upper Case Names - When you add a new argument or rename an existing argument, the argument name is now converted to uppercase. By using the convention that argument names are always uppercase, a class of bugs that can result when the same argument name is used in multiple linked components is used and in each of these components, the argument name is defined using a different case.

UX Component - List Control - Detail View - onStateChanged Event - A new event has been added to the List control. The onStateChanged event fires when the Detail View goes from clean to dirty, or vice versa.

UX Component - Auto-Suggest and Edit-Combo Control - Multiple Selections - Keep List Open - The Auto-suggest and Edit Combo controls have always allowed you to set a mode where multiple selections can be made. However, each time you make a selection the pick list is closed and you must reopen the pick list before you can make your next selection.
 
 Now, a new property in these controls allows you to specify that the pick list should stay open after each selection, allowing you to make multiple selections more easily.

 

 

If you have turned on multiple selections, you can delete previously made selections by either backspacing to delete one character at a time, or use Shift+Cntrl+Backspace to delete complete selections.

If you have turned on multiple selections, you can prevent the user from selecting the same value more than once by setting the Allow duplicate selections property.

 

PhoneGap App Builder - Core Plugins And Some Key 3rd Party Plugins - Added a version specification to all core and some essential 3rd Party Plugins plugins to resolve problems with updated plugins and Android on PhoneGap Build.

Many of the core plugins were updated recently and specified a requirement for a minimum PhoneGap version of Android 6.3.0. PhoneGap Build cli-7.0.1 (the latest release supported by PhoneGap Build) includes Android PhoneGap Version 6.2.3 so the changes to the plugins configuration files causes the build to fail on the current release on PhoneGap Build. This change ensures that PhoneGap Build will work with the specified plugins.

PhoneGap App Builder - 3rd Party Plugins - Added support for the PDF417-Phonegap plugin. This plugin is a small but powerful scanner that handles bar code and PDF417 scanning.

 

Alpha Style Sheet - SVG Icons - Several new SVG icons have been added to the Alpha stylesheet. These are:

 

 

 

UX Component - List Control - List Virtualization - onNavigate Event - The onNavigate event's behavior is different depending on whether the list is virtualized or not. If the List is not virtualized, the onNavigate event fires when the List is scrolled. If it is, then the onNavigate event fires when the user navigates to a new page of records.

In order to allow the behavior of this event to be consistent regardless of the virtualization option, a new property has been added to the list. The onNavigate event behavior property can be set to Navigate, Scroll or Both. When set to Scroll, the behavior is the same as a non-virtualized list.

 

 

Application Server - OpenSSL - Updated to build 1.0.2m of OpenSSL.

Web Security - Utility for SQL tables in Standard Server - A revised utility has been added to the 'Utilities' option in the Web Security menu when using SQL based tables on the standard server. The new utility will still verify if the defined security tables can be found, but has additional options.

If the security system connects to the SQL tables with Active Link tables, the utility has an option to 'Validate Field Maps'. The action will verify if the field map saved in the Active Link tables map to the correct field names in the SQL table.

The option will only check a single table if one is selected. If a table is selected, the option 'Clear Selected' will remove the selection and allow checking all tables.

The option 'Show Connection String' will show the actual connection string used by a table if the table is selected. The normal configuration would have the same connection for all tables.

Errors cannot be corrected if using Active Link tables, but the utility will show a message on close if any errors were found

Changes can be made and saved if the security system is using a 'DataLink' file in place of Active Link tables. The option to 'Show Connection String' is still shown, but the option to 'Validate Field Maps' will open a genie to remap the fields if any errors were found in the existing map. The genie will only allow selecting fields that are of the correct data type and length.

A new option is shown to 'Change Connection String'. This shows a list of available connections and can change the connection for all tables. The utility will check if the current tables exist in the new connection and will run the validation option is tables with the same names are found.


Another new option is 'Select New Table'. This will show a list of tabled found in the SQL database that uses the connection. When a table is selected, the field map validation will run to allow remapping the field as needed. This option can also create a new table in the target database, but will not populate the new table with any data.

Changes can be saved by the 'Save Changes' button which is activated if any changes were made.

 

PhoneGap App Builder - iOS Launch Images - Added static (legacy) image generation support for iPhone X and the 10.5 inch iPad Pro launch images. If you are planning to support the new iPhone X and/or the 10.5 inch iPad Pro, you previously had to use storyboard images for your app launch image. This is no longer the case. If you choose to use static (legacy) launch images, then the appropriate size is automaticaly generated for the iPhone X and the 10.5 inch iPad Pro. Remember to center weight your image (look at Twitter's launch image) and verify that each generated image looks correct. The iOS launch images can be found in the PhoneGapProjects\ProjectName\www\res\screen\ios folder.

PhoneGap App Builder - PhoneGap Project Template The PhoneGap new project template was modified to support better code formatting for legacy (static), iOS Storyboard and Android 9-Patch launch images. These sections are dynamically replaced within the PhoneGap config.xml file when the launch and storyboard images are generated by the PhoneGap App Builder genie.

UX Component - List Control - No Records in List HTML - Specify Message Using Javascript - The List Builder allows you to specify a message to show in the List if there are no records in the List.

Previously, you could only define some static HTML to display. Now you can specify some Javascript code to return the message to be shown. To specify that the message is returned by some Javascript code, prefix the message with javascript:

For example, assume that you had defined a local function called norecordsmessage in the List Builder  (Turn on the optional Javascript tab in the List Builder and define a function at the This object level).

You would set the No Records HTML to:

javascript:this.norecordsmessage()

 

You can also include a5-item attributes in the message text. For example, assume you wanted to display a message if the user tapped on the no records message. Assume also that the message was to be returned by a local function called norecordsmessage(). Here is how this could be done:

First, define an item in the List Builder's Items tab (by turning on the optional Template Items tab - check the box at the bottom of the List Builder window. For example, you could define an item called 'norecords' that displayed a message when clicked.

Then define the norecordsmessage function as follows:

 

return '<span a5-item="norecords">List has no records</span>'

 

 

Xbasic Functions - convert_ts_to_js() - Converts TypeScript files (with .ts extension) to Javascript files (with same name, but .js extension)

 

Syntax

result = convert_ts_to_js(files)

 

Where

 

UX Component - Client-side Event - OnBeforeCreate - Fires before any code to render the UX is executed. Allows you to change settings in the Alpha Anywhere Javascript library that affect how the UX is rendered. For example you could override the definition of the A5.listBox.prototype.populate() method in this code.

NOTE: The {dialog.object} object cannot be referenced in the code for this event handler as it has not yet been instantiated.

Xbasic - a5_XbasicTreeToJSONTree() Function - This function, which takes a CRLF delimited string, and converts it into a complex JSON structure that can be used to populate a Tree or Menu control, has been enhanced and now allows you to define the Javascript code to execute when the user clicks on a tree leaf.

 

Consider the following example, which produces a tree showing Countries, Cities, then ContactName. ContactName is the tree leaf. When the user clicks on a leaf, you want to call a Javascript function. The data for the tree should come from a SQL query.

Here is how this is achieved:

 

dim cn as sql::Connection
cn.open("::Name::northwind")
cn.PortableSQLEnabled = .t.
dim sql as c
dim flag as l

'define the sql query that will return the data in the correct format
sql = <<%str%
select country, city, concatenate(contactname,'```onclick:findCustomer(','''',customerId,''')') from customers where not (country = '') order by country, city, contactname
%str%

flag = cn.Execute(sql)
dim txt as c
txt = cn.ResultSet.tostring(-1,-1,.t.,"|")
'this will generate a crlf delimited string like this
'France|Nantes|Carine Schmitt```onclick:findCustomer('FRANR')
'France|Nantes|Janine Labrune```onclick:findCustomer('DUMON')
'France|Paris|Dominique Perrier```onclick:findCustomer('SPECD')
'France|Paris|Marie Bertrand```onclick:findCustomer('PARIS')
'France|Reims|Paul Henriot```onclick:findCustomer('VINET')'

'notice that the tree branches are separated by a | character.
'the leaf nodes specify an onclick event.
'the syntax for the onclick event is ```onclick:javascript to execute

'notice that we pass the primary key to the leaf as the argument to the function

txt = a5_XbasicTreeToJSONTree(txt,"|","html")

 

 

The resulting JSON string is:

 

[
  {
    "html": "Argentina",
    "children": [
	          {
		    "html": "Buenos Aires",
		    "children": [
			          {
				    "html": "Patricio Simpson",
				    "onClick": function() { findCustomer('CACTU')}
				   },
				   {
				     "html": "Sergio Gutiérrez",
				     "onClick": function() { findCustomer('RANCH')}
				   },
				   {
				     "html": "Yvonne Moncada",
				     "onClick": function() { findCustomer('OCEAN')}
				   }				
		]
           }
   }......
]
			

UX Component - Spreadsheet Input Control - Get and Set Column State - Two new methods have been added to the control

 

Example

 

var obj = {dialog.object}.getControl('myspreadsheetcontrol_1');

var json = obj.getColumnState()

//store the column state in local storage

localStorage.setItem('columnstate',json);

 

 

 

//restore the column state

var obj = {dialog.object}.getControl('myspreadsheetcontrol_1');

var json = localStorage.getItem('columnstate');

obj.setColumnState(json);

UX Component - List Control - Media Files - Events - In a disconnected application you can configure the media files in the List to download to the mobile device and be stored in the filesystem on the device. The UX component will fire the beforeMediaFiles download and afterMediaFilesDownload events. Previously, even if there were no media files to download, these events would fire. Now, if there are no media files to download a new event, onNoMediaFilestoFetch will be fired.

 

UX and Grid Components - Reports - Send via Email - A new option in the Action Javascript command to display a report, now allows you to email the report rather than displaying it.

 

 

When you check the Email report property the Email settings property is shown when you can configure the email that will be sent with the report as an attachment.

The Email Settings dialog is shown below.

 

 

UX Component - Frame Control - Modern Frame - Set Open/Close State Programmatically - A new method allows you to set a modern frame to be open. closed, or to toggle its state.

The method, {dialog.object}.frameOpenStateChange(frameId, state) takes two arguments:

Bugs

Alpha Style - IE 11 - Browser Hang - Under some circumstances it was possible to hang IE 11 when using a Grid or UX component that used the Alpha style. The Alpha style uses SVG icons for all icons shown in the components. If a button had an SVG icon and you clicked directly on the icon, and as a result of the click, the icon was replaced (perhaps with a disabled version of the icon), IE11 would occasionally hang.

 

UX Component - SpreadsheetInput Control - Column Width - The column width property was not being honored when the control was rendered.

Alpha Anywhere Server for IIS - Install Error - An install error introduced in approximately build 4710 has been corrected.

bus_days_between() Function - Fixed a bug in this function when using a .dbf table for the list of holidays. The bug did not exist when using a SQL table for the holiday list.

AlphaCloud - All Components - Local CSS - SASS - If any local CSS defined in a component used SASS syntax, the definition was not properly converted to CSS. This bug was a recent regression.

SASS Processing - This build now includes a new version of the SASS processor that converts SASS to CSS. This new SASS processor can report errors in the input SASS file.

UX and Grid Components - Client-side Watch Expressions - Stack depth exceeded Error - Certain types of client-side watch expression (for example myFunction('{grid.componentName}'), would cause a 'stack depth exceeded' error message when the component was saved.

Page Layout Component - Fixed an issue when a Page Layout component contained a Grid component.

Tips

UX Component - Edit-Combo Control - Automatically Displaying the List of Choices - In some situations you might want the pick list for an edit-combo box to be displayed automatically as soon as the user gives focus to the control.

This is easily done by getting a pointer to the button that opens the pick list and then calling the object's .click() method.

For example, assume that the variable name for your edit-combo control was MYEDITCOMBO. You could add this code to the control's onFocus event:

 

ele = $('DLG1.V.R1.MYEDITCOMBO.BUTTON');
ele.click()

 

However, on a mobile device this will not work because the events are all abstracted on a mobile device. To get the above code to work on a both a standard desktop browser and a mobile device change the code to use the $e.execute() method, which allows you to execute abstract events.

 

ele = $('DLG1.V.R1.MYEDITCOMBO.BUTTON');
$e.execute(ele,A5.d.evnts.click);

 

 

 

 

Alpha Anywhere V4.5.1 - Build 4642_4981 12-Oct-2017

Videos

UX Component - List Control Reorder List Rows by Dragging Row to a new Group when Client-side Grouping is Enabled When client-side grouping is enabled in a List, the order of the rows in the List is determined by the sort expression that is applied to the data so that the List data can be grouped correctly. That means that if you drag a row to a new position, and then drop, the row will immediately snap back to its original position (because the client-side sort will be re-applied to the List data).

However, you might want to use drag reorder to move a row from one group to another. This is done by changing data in the row that is moved so that in the onMoveEnd event, the data in the row is updated and then, when the client-side sort is applied to the List data, the row will continue to appear in the target group.

In this video we show how a list of customers, grouped by Country, can be re-arranged by dragging a customer from one country to another.

Watch Video

Download component

Date added: 2017-09-14
UX Component - Spreadsheet Input Control Using the Spreadsheet Input Control In certain applications where a user needs to input data quickly, a spreadsheet style data entry control can be very efficient.

In this video we show how you can add a Spreadsheet Input control to a UX component.

Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

Download component

Date added: 2017-10-02
     

Features

{dialog.Object}.frameOpenStateChange(frameId,state)"
a2[..].description = <<%html%
Sets the open/closed state of a Frame control. Frame control must be configured as a 'Modern' frame and must have
the 'Has show/hide buttons' property checked. Where: <br>
 

 

 

 

 

PhoneGap App Builder - Added PhoneGap CLI Support for Cordova Version 7.0.1  - Added support within the PhoneGap CLI builder for Cordova Version 7.0.1, Android Studio 2.3.3 and XCode Version 9.0.

Handling of Launch Images, Splashscreens and Icons was modified and tested with the latest releases of PhoneGap, Android Studio and Xcode.

Note: The script for Android Studio 2.3.3 was modified to kill all aapt.exe (Android Asset Packaging Tool) instances that remain open after a successful Android Cordova Build. This appears to be a bug in the Windows Android SDK or Cordova 7.0.1.

 

Xbasic - JSON - extension::json::ForEachString() Method - This method is similar to the Xbasic *for_each() function, except that it is designed to operate on property values in a JSON string.

 

For example:


dim json as c = <<%str%
{
    "name" : "name Smith " ,
    "alias" : [ "jj " , "name " ] ,
    "id"     : {
        "name" : "name_01 "
    }
}
%str%
 

Notice that the string 'name' appears in the above JSON as both a property name and also in a property value.

We want to change 'name' to 'John', without changing the names of any of the property values. Also, note that each property value has trailing spaces.
 

'change 'name' to 'John'

json = extension::json::ForEachString(json,"strtran(value,'name','John')")
 

'trim trailing spaces from each property value
json = extension::json::ForEachString(json,"trim(value)")
 

Result:


{
    "name" : "John Smith" ,
    "alias" : [ "jj" , "John" ] ,
    "id" : {
        "name" : "John_01"
    }
}
 

Notice that none of the property names were changed.

 

UX Component - SpreadsheetInput Control - A new control type is now available in the UX component. The SpreadsheetInput Control allows you to display a spreadsheet style grid of cells in which the user can enter/edit data. The spreadsheet columns can be resized and also reordered.

For example, in the image below, a SpreadsheetInput Control has been defined with 3 columns and 5 rows. The user can use keyboard navigation (tab, shift-tab, up and down ) to move between the cells in the control.

Watch Video - Part 1
Watch Video - Part 2
Watch Video - Part 3

Download component

When the UX is submitted, the data in the control is submitted as a JSON string.

 

For example, if the control had been filled in as shown below:

 

then, when the UX was submitted, the data submitted for the SpreadsheetInput control would be as string with this value:

 

"[{"field1":"alpha","field2":"beta","field3":""},{"field1":"","field2":"","field3":"gamma"}]"

 

 

To, add a SpreadsheetInput control to a UX, select the [More..] control from the Data Controls section of the UX toolbox.

 

 

 

Then select the SpreadsheetInput control from the list.

 

 

To configure the control, click the smart field for the Control properties.

 

 

 

This will open the genie where you can configure the control.

 

 

The most important property to configure is the Column definitions property. This property allows you to define the columns shown in the SpreadsheetInput control.

Click the smart field to open the editor, as shown in the image below.

 

 

You can add columns one at a time by clicking the Add Column button. You can click the Quick Select using Genie hyperlink to add columns to match the fields in a SQL table.

 

The onNavigate property allows you to specify Javascript code to execute when a cell in the control gets focus.

 

Defining Row Prefixes and Suffixes

You can define row prefixes (i.e. row labels) and row suffixes so that the control looks even more like a spreadsheet. The prefix displays at the left side of each row and the suffix displays at the right edge of each row. For example, in the image below a prefix has been defined to show the row number.

 

Here is how the control is configured to show the prefix:

The Has row prefix (label) property is checked.

The Row prefix HTML is a defined using Javascript code that can reference row - the zero based row number and data - the array of data with which the control is populated. To show the row number as the row prefix, the Javascript for the Row prefix HTML is set to:

return (row + 1);

 

The Width property is set to 50px to set the width of the prefix column.

The Style property is set to font-size: 75%; text-align: right; to make the font slightly smaller than the text in the input control and also to right align the text in the row labels.

 

 

 

Methods

 

Since the SpreadsheetInput control is a standard UX Data Control, you can use the {dialog.object}.setValue() method to populate the cells in the control with data and the {dialog.object}.getValue() method to get the data in the control. When you use these methods, the value is a JSON string.

For example, if the SpreadsheetInput  control has 3 columns (field1, field2 and field3), you could use the following Javascript to populate the control:

var _data = [

    {field1: 'alpha', field2: 'beta'},

    {field2: 'gamma', field3: 'delta'},

    {field3: 'epsilon'}

];

var _string = JSON.stringify(_data);

{dialog.object}.setValue('mySpreadsheetControl',_string);

 

.setColumnAndPopulate() Method

You can also dynamically change the columns shown in the control to match the columns in some data with which you want to populate the control. For example, say that the SpreadsheetInput control was initially configured to show a single column (say 'Field1') and you wanted to populate it with the the following data:

 

[

    {firstname: 'John', lastname: 'Smith', city: 'London'},

    {firstname: 'Harry', lastname: 'Jones', city: 'Boston'},

    {firstname: 'Winston', lastname: 'Flowers', city: 'Harare'}

]

 

You can call the control's .setColumnsAndPopulate() method.

For example:

var obj = {dialog.object}.getControl('mySpreadsheetControl');

var _data = [

    {firstname: 'John', lastname: 'Smith', city: 'London'},

    {firstname: 'Harry', lastname: 'Jones', city: 'Boston'},

    {firstname: 'Winston', lastname: 'Flowers', city: 'Harare'}

]

obj.setColumnsAndPopulate(_data);

 

 

The columns shown in the control will now be 'firstname', 'lastname' and 'city'.

 

.getColumnState() and .setColumnState() Methods

Since the columns in the Spreadsheet input control are resizeable and reorderable, you might want to capture the state of the Spreadsheet input control's column layout so that you can restore it the next time the user runs the component.

 

For example

var obj = {dialog.object}.getControl('myspreadsheetcontrol_1');

'get the spreadhseet control state as a JSON string

var json = obj.getColumnState();

 

'store in local storage

localStorage.setItem('spreasheet_01_State',json);

 

Then, to restore the state

var json = localStorage.getItem('spreasheet_01_State');

var obj = {dialog.object}.getControl('myspreadsheetcontrol_1');

obj.setColumnState(json)

 

 

 

UX Component - Client-side Events - onWatchEvent - A new client-side event has been added. The onWatchEvent fires when any of the client-side watch events (show/hide, enable, readOnly) fires. For example, when a client-side show/hide expression on a control is executed the event is fired. The type of event, the name of the control on which the expression is being evaluated and the result of the expression are passed into the event handler.

Possible values for the type parameter passed to the event handler are

 

 

UX Component - Set Tab Order - By default, the tab order in a UX component is the same as the order in which the controls were defined. However, you can now define a custom tab order without having to reorder the controls in the builder.

 

To open Tab Order dialog, select the Set tab order... menu item in the dropdown Menu

 

 

 

 

In the dialog, select the tab order that you want.

 

 

 

UX Component - List Control - Event - onBeforeListClear - Fires before the list data is cleared.

 

UX Component - Client-side Events - canAjaxCallback and onAjaxCallbackComplete - callbackId Parameter - A new parameter is available in the e object passed to these events. The e.callbackId property is a GUID that identifies the callback and allows you to match the onAjaxCallbackComplete event with a particular AjaxCallback.

UX Component - List Control - .setDisplay() Method - This method has been enhanced and can now be used to operate on List columns.

For example, the following method will hide columns 0, 1 and 2 in a columnar List layout:

 

var lObj = {dialog.object}.getControl('list1');

lObj.setDisplay('column',{column: [0,1,2], display: [false,false,false]})

 

 

Documentation - List Control - The documentation system now contains in-depth description of the List object. Note that in the documentation the List is referenced as ListBox, its official internal name.

NOTE: The documentation referenced here does not include the List control methods that are only available when the List has a Detail View. These methods are currently documented here.

 

PhoneGap Builder : Added support for PhoneGap Build Version cli-7.0.1

PhoneGap Build recently added support for PhoneGap 7.0.1 which aside from security and performance enhancements includes some important changes behind the scenes in the build infrastructure. There are now two distinct builders that can be used by PhoneGap Build, the original and the new and this option is exposed in the Alpha PhoneGap App Builder as the PhoneGap Builder Version property, values 1 and 2. By default this value is set to 1 which will use the original builder which will most likely be deprecated at some point in the future. If you set this option to 2, then the new builder will be used by the PhoneGap Build Service.




If you plan to support the new iPhone X, you will need to use storyboard launch images (now supported, see below) and you must use cli-7.0.1 and PhoneGap Builder Version 2.

Please see the PhoneGap Build Blog PhoneGap 7.0.1 Release Notes for all of the details on the cli-7.0.1 release.

PhoneGap Builder: Added support for iOS Storyboards and Android 9 Patch images

With the release of PhoneGap Build cli-7.0.1, support for iOS Launch Storyboards is now inherently supported within the new builder. If you plan to support the new iPhone X or the iPad Pro 12.9’s native resolution or split screen/slide-over multitasking, you’ll need to use iOS storyboard launch images.

Launch storyboard images are sized based on scale, idiom, and size classes. They supports all devices, and can be used with split-screen/slide-over multitasking.




Apple is moving away from legacy launch images. There is no official support for providing a native-resolution launch image for the iPad Pro 12.9 or for providing launch images that work with split-screen multitasking or slide-over. If your app doesn't need to support these contexts, then you can continue to use legacy launch images for as long as you like.

The preferred method of providing launch images is to use a launch storyboard.

These are similar to the legacy launch images, but there are crucial differences:



Designing launch storyboard images (Applies to Android 9-patch images as well)

The key to designing a launch storyboard image is understanding that the edges of the image will almost certainly be cropped. Therefore, one should not place any important information near the edges of any images provided to the launch storyboard. Only the center is a safe area, and this all but guarantees that following Apple's advice of presenting an unpopulated user interface will not work well.

Instead, the following tips should enable you to create a launch image that works across a multitude of form factors, viewports, and orientations:



Of the images supplied to the launch storyboard, iOS will choose the image that best matches the device and viewport and render that image.

The Alpha PhoneGap Builder will generate all of the rerquired storyboard images from a single user supplied square 2732px x 2732px (min) png file. The iOS storyboard file is generated from the image specified for the Portrait splash screen.

Changes to the PhoneGap Build config.xml file

The Alpha Anywhere PhoneGap App Builder will automatically remove and replace certain sections of the config xml file that reference legacy splashscreens, storyboards or Android 9-patch images, based on the properties set within the builder. All of the sections are marked with XML comments and those comments need to remain in place. If legacy splashscreens are specified then the sections for the storyboard and Android 9-patch images are removed, but the comment tags are left intact. If storyboards and Android 9-patch images are specified, then the legacy sections are removed.

If you are modifying an older PhoneGap project with a legacy config.xml file (the comment tags we added around April of 2017), these sections will be added to the older config.xml file and a message will be displayed, indicating that an older config.xml file was modified. In this case, you should edit the config.xml file to remove the older legacy splashscreen section, prior to submission to PhoneGap Build.

 

Grid Component - Arguments - Session Variables - Arguments that are bound to session variables are now updated on every Ajax callback. Previously, the argument values were only set when the Grid was initially run.

Xbasic - email_send_sparkpost() Function - SparkPost Options - SparkPost allows you to specify options, such as open_tracking and click_tracking (see SparkPost API documentation).

You can now pass in these options to the email_send_sparkpost() function as shown below:

 

dim ms as p

'xbasic commands to set required properties of mp not shown

ms.options.open_tracking = .f.
ms.options.click_tracking = .f.
dim key as c = "your sparkpostkey"

dim pp as p
pp = email_send_sparkpost(key,ms)

 

UX Component - DropdownBox Controls - Client-side Data Cache - DropdownBox Box controls can now be populated with data that is stored in the Client-side Data Cache.

This is particularly useful in the case of mobile applications that are deployed as PhoneGap applications, or in static HTML applications that use the Application Cache, because in these applications the DropdownBox controls are populated with data at the time the application in built. When the applications are run, the DropdownBox controls will still continue to show the data that they were populated with at build-time.

In many cases it will be desirable to update the choices shown in a DropdownBox with up-to-date data and to continue to use the most up-to-date data available when the App is launched, even if there is no connection available at that time.
To solve this problem, you can populate DropdownBox controls with data from the Client-side Data Cache.

In order to indicate that data from the Client-side Data Cache should be used, set the first line of the static choices to this:


client-side-data-cache:cacheItemName(displayDataColumn,storedValueColumn)


When the App is launched, if a connection is available, the Client-side Data Cache will be refreshed and the DropdownBox will be populated with fresh data. If no connection is available the first time the App is launched the choices you specify in the second and subsequent lines of the defined Static choices will be used.

For example, assume you had a Client-side Data Cache item called Products and that this item had two columns, Description and Code. In order to populate the DropdownBox to use the Description field as the display value and the Code field as the stored value, you would use this directive in the first line of the Static Choices:


client-side-data-cache:Products(Description,Code)


If you want the display value and stored value to be the same, then just specify the name of the display value column for the stored value.

 

client-side-data-cache:itemName(displayColumn,storedValueColumn)

 

The image below shows how the choices in a DropdownBox control would be defined to read the data from a Client-side Data Cache item called weekdays.

The choices shown starting on line two are the fallback choices that will be used if there is no connection available the first time the App is launched (which means that the Client-side Data cache cannot be populated).

 

 

 

Xdialog - Dynamic Titles - It is now easier to dynamically change the title on an Xdialog. The {title} directive can now display the value of a variable. When the value in the variable changes, the Xdialog title is also changed.

To specify that the {title} directive should use a variable, use this syntax:

{title=@variable_name}

 

 

Example:

 

dim dyn_title as c = "The Title"
ui_dlg_box("dynamicTitleExample",<<%dlg%
{title=@dyn_title};
Title [.80dyn_title!change];
{line=1};
{justify=right}<&Ok>
%dlg%,<<%code%
if a_dlg_button = "change" then
    a_dlg_button = ""
end if
%code%)

 

Clone Workspace - You can now clone a Workspace. The Clone Workspace command is on the File menu when the Web Control Panel or the standard Control Panel have focus.

 

 

UX Component - Slider Controls - Client-side Data Cache - You can now set the data in a slider control based on data in a Client-side Data Cache item.

 

UX Component - Client-side Events - afterControlBasedOnClientSideDataCacheRefreshed Event - Several control types (e.g. SpinList, ButtonList, Slider) can be populated from data in a Client-side Data cache. This event fires after a control that is populated from a client-side data cache item has been populated.

 

UX Component - Expanding Menu Control - Define Menu Choices Using JSON - You can now define the menu choices in an expanding menu control by defining a JSON object.

 

 

Xbasic - Handlebars.js Templating Library - You can now use the popular Handlebars.JS templating library in Xbasic code.

 

NOTE: The Alpha Anywhere templating library is also available to Xbasic code through the a5_merge_JSON_into_template() Function.

 

Example:

dim hb as nodeservices::handlebars

dim source as c = <<%str%
<p>Hello, my name is {{name}}. I am from {{hometown}}. I have
{{kids.length}} kids:</p>
<ul>

{{#kids}}

    <li>{{name}} is {{age}}</li>

{{/kids}}

</ul>
%str%
 

dim json as c = <<%str%
{
    "name": "Alan",
    "hometown": "Somewhere, TX",
    "kids": [

        { "name": "Jimmy", "age": "12" },

        { "name": "Sally", "age": "4" }

    ]   
}
%str%

html = hb.RunTemplate(source,json)

 

Resulting text:

 

<p>Hello, my name is Alan. I am from Somewhere, TX. I have
2 kids:</p>
<ul>

    <li>Jimmy is 12</li>

    <li>Sally is 4</li>

</ul>
 

 

 

UX Component - SpinList and ButtonList Controls - Client-side Data Cache - You can now specify that the data source for a SpinList or ButtonList control is a Client-side Data Cache item. This is particularly useful in PhoneGap applications that are designed to work offline. Here is why:

Say you build a UX component that has a SpinList control and you specify that the control should be populated with data from a Data Series. At the time your PhoneGap application is built, the SpinList with be populated with the data in the Data Series.

Once the PhoneGap app is installed on a device, the SpinList will continue to have the data that was in the Data Series at the time the PhoneGap app was built. If you refresh the Data Series the SpinList will now have up to date data, but this data has not been persisted on the device. So, this means that if you exit the App and re-launch it you are back to having stale data in the SpinList. If you do not have a connection you would not be able to make a callback to the server to refresh the data in the SpinList.

However, if you specify that the SpinList is populated from data in a Client-side Data Cache, the Client-side Data cache will be refreshed automatically when the App is launched and then the SpinList will be populated with the up-to-date data. The data that was retrieved from the server will be persisted on the device (assuming the Client-side Data Cache item was configured to persist data on the device). This means that if you exit the App and then re-launch it (while no connection is available), the SpinList will be populated with the data that was fetched from the server the previous time the App was launched (presuming that at that time a connection to the server was available).

 

UX Component - List Control - Search Part - Server-side After Search Expression Computed Event - New server-side event when performing a search on a List using the List's Search Part.

 

The Grid component exposes a server side event, onSearchPartFilterCompute, that allows developers to override the filter that was computed from the submitted search data. This event fires before the actual search query is executed.

 

Analogous behavior can now be added to searches performed from the Search Part of a List control.

The Javascript method to invoke a search is as follows:

{dialog.object}.getControl('name_of_your_list').searchList( searchOptions)

 

where searchOptions is a JSON object with these properties:

 

For example:

{dialog.object}.getControl('LIST1').searchList({searchMode : 'auto', xbasicAfterFilterCompute : 'xbmodifysearch'});

 

 

 

The Xbasic function takes e as an input parameter.

The e object contains:

e.searchDefinition contains these properties

 searchValue|||field type|argument name

For example:

%UK%|||C|search_country_country1

 

For example:

(Country LIKE :SEARCH_Country_Country1)
 

 

Your Xbasic function can modify any of the properties in the e.searchDefinition object.

 

Bugs

UX Components - Alignment Containers - Client-side Show/Hide Expressions - Were not working on alignment containers.

UX Component - List Control - Star Rating and Switch Control - Client-side Sorting - When you set the control type for a column in a List to either a Star Rating or Switch control and the List had a client-side sort applied to the data, the controls did not behave correctly.

UX Component - Javascript Injection Attack - In some cases, the UX was incorrectly reporting that a Javascript Injection Attack had been detected.

 

Alpha Anywhere V4.5.0 - Build 4584_4961 13-Sep-2017

Bugs

UX Component - List Control - Deleting Records - Under some circumstances a Javascript error was thrown when deleting a List row.

Application Server - IIS - Built-in icons were not displaying a disabled when they should have been.

Alpha Anywhere V4.5.0 - Build 4582_4960 12-Sep-2017

 

 

Videos

UX Component Multi-Lingual PhoneGap Applications Normally, UX components can be localized by wrapping the strings you want to translate in either language tags (<a5:r>...</a5:r>) or text dictionary tags (<a5:t>...</a5:t>). The string translation takes place on the server when the component is rendered. But in a PhoneGap application, the component is loaded from the file system on the device and so you can't use language or text dictionary tags. Instead, you must use a client-side approach (using Javascript) to translate the strings into the selected language.

In this video we show how you can implement client-side language translation.

Watch Video - Part 1
Watch Video - Part 2

Download component

Date added: 2017-08-04
UX Component - FormView Control Client-side Show/Hide and Enable Expressions that Reference External Data Typically, the client-side show/hide and enable expressions in a FormView layout reference field values that are in the data being displayed in the Form. For example, the Form might have a field called Country and you might want to show a container only when the Country field has a certain value.

However, there are also use cases where you want to reference external data (i.e. the value in some other control on the UX) in a client-side expression. This video shows how this is done using FormView state variables.

Watch Video - Part 1
Watch Video - Part 2

Download component

Date added: 2017-08-14
UX Component - ViewBox Control Client-side Show/Hide Expressions that Reference External Data When you define the layout for a ViewBox control, the template can use the {*if} directive to conditionally show/hide content in the ViewBox. Typically the expression in the {*if} directive will reference data in the ViewBox data. But in some cases you might want to reference data that is external to the ViewBox (for example, your UX might have a control whose value you want to reference in the {*if} directive's conditional expression). In order to do this, you must create a ViewBox state variable that is set to the value of the external data.

In this video we show how external data is used in a ViewBox conditional expression.

Watch Video

Download component

Date added: 2017-08-15
UX Component - List Control Displaying Data in a List using a StarRating Control Many applications allow you to rate something by tapping on a star in a StarRating control. The UX component has a stand-alone StarRating control (accessed by selecting [More...] in the UX Builder Controls toolbox), but in some cases you might want to display data in a List control using a StarRating control.

In this video we show how this is easily done.

Watch Video

Download component

Date added: 2017-08-18
UX Component - List Control Row Drag Actions A common user interface pattern seen in mobile apps that use a List is to allow the user to drag on a row in the List to invoke some type of action. For example in the iOS Email app a user can drag on a row to archive the row, mark is as unread/read, or move the row to another folder.

In this video we show how you can implementing row drag behavior an a List control.

Watch Video - Part 1
Watch Video - Part 2

Download component

Date added: 2017-08-25
UX Component - List Control Reorder List Rows by Dragging Row to New Position In certain applications where a List control is used, it is necessary to allow the user to reorder the rows in the List. A common user interface pattern used to reorder List rows is to allow the user to drag a row to its new position in the List.

In this video we show how you can add 'drag to move row' behavior to a List control.

Watch Video - Part 1
Watch Video - Part 2

Download component

Date added: 2017-08-28
UX Component - List Control Displaying Summary Values in Column Footers In some applications you might want to compute summary values (e.g. count, total, average, etc.) for data in a List column and then display that data below the last row of data in that column.

In this video we show how this is done.

Watch Video

Download component

Date added: 2017-09-02
UX Component Adding Keyboard Shortcuts to a Component In this video we show how you can add support for keyboard shortcuts to a UX component. Keyboard shortcuts can speed up a user's interaction with a component. For example, you could configure the Ctrl-S key as a shortcut for saving the data in the a UX.

Watch Video

Download component

Date added: 2017-09-02
UX Component Using the Enter key as a Keyboard Shortcut to Navigate to Next Control