Maps

Labels
AJAX(112) Apple(1) Application Builder(242) Application Factory(207) ASP.NET(95) ASP.NET 3.5(45) ASP.NET Code Generator(72) ASP.NET Membership(28) Azure(18) Barcodes(3) BLOB(18) Business Rules(1) Business Rules/Logic(140) BYOD(13) Caching(2) Calendar(5) Charts(29) Cloud(14) Cloud On Time(2) Cloud On Time for Windows 7(2) Code Generator(54) Collaboration(11) command line(1) Conflict Detection(1) Content Management System(11) COT Tools for Excel(26) CRUD(1) Custom Actions(1) Data Aquarium Framework(122) Data Sheet(9) Data Sources(22) Database Lookups(50) Deployment(22) Designer(177) DotNetNuke(12) EASE(20) Email(6) Features(99) Firebird(1) Form Builder(14) Globalization and Localization(6) Hypermedia(2) Installation(4) JavaScript(20) Kiosk(1) Low Code(3) Mac(1) Many-To-Many(4) Maps(6) Master/Detail(36) Microservices(4) Mobile(63) Mode Builder(3) Model Builder(3) MySQL(10) Native Apps(5) News(15) OAuth(5) OAuth Scopes(1) OAuth2(7) Offline(15) Oracle(10) PKCE(1) PostgreSQL(2) PWA(2) QR codes(2) Rapid Application Development(5) Reading Pane(2) Release Notes(165) Reports(48) REST(27) RESTful(22) RESTful Workshop(13) RFID tags(1) SaaS(7) Security(75) SharePoint(12) SPA(5) SQL Anywhere(3) SQL Server(26) Stored Procedure(4) Teamwork(15) Tips and Tricks(82) Tools for Excel(2) Touch UI(93) Transactions(5) Tutorials(183) Universal Windows Platform(3) User Interface(332) Video Tutorial(37) Web 2.0(100) Web App Generator(101) Web Application Generator(607) Web Form Builder(39) Web.Config(9) Workflow(28)
Archive
Blog
Maps
Tuesday, March 5, 2019PrintSubscribe
Build Apps Faster With Maps and Postal Address Verification
Code On Time release 8.7.9.0 brings the upcoming live designer another step closer to reality and introduces various cool features in the application framework including Postal Address Verification, external JavaScript business rules, enhanced batch editing of many-to-many fields, maps in forms, and much more. We also hope that you will notice the significant increase in the code generation speed.

For the past few years we were developing a new innovative development environment to revolutionize Rapid Application Development of custom business applications that work offline, online, and on-premises. This particular release makes your apps ready for Code On Time v9. Today you are starting the Design environment by selecting the corresponding option in the project wizard. In the very near future your own app will be launched with the new design environment  overplayed on top! The upcoming live designer is implemented as addon.appbuilder.dll automatically included in the ~/app/bin folder of apps created with v9. The add-on integrates its own scripts in the application. The design environment is composed of Project Explorer and Object Inspector. Developer can click on user interface elements of their live app to inspect properties of the corresponding elements and have them changed when needed.  Changes to some properties (such as labels), will provide instant feedback in the user interface of the live app. Any significant changes will cause the app to be re-generated and restarted when the developer is ready to see the end result.

The mechanism of code generation has been changed significantly in release 8.7.9.0 to speed-up the code generation and improve the start time of the app. In many cases the app generator will replace only a few files in the source code and eliminate the need for hard restart of the app.

Published app will not include the add-on DLL in the output. App Builder add-on is not required for your apps to work. It is activated only if Code On Time generator is installed on the machine and if your app is accessed via localhost address. Both Touch UI and Classic UI apps will work with the new app builder, when released. You will be able maintain the source code of your apps in Visual Studio and work with the source control systems such as Git. Nothing will change from the development prospective.

Autofill and Postal Address Verification

Postal Address Verification is the new feature built on top of Autofill, the mechanism embedded in the universal input elements of apps created with Unlimited Edition.



An autofill group is created by tagging multiple fields with tags that start with "autofill-" prefix. For example, autofill-address-city. Component "address" in the tag defines the name of the group. Component "city" is the group-specific purpose of the field and does not need to match the physical field name. The trigger field in the group will cause "AutoFill" command to execute. More than one trigger can be declared by tagging multiple fields with autofill-[groupname]-trigger attribute. All trigger fields must have values for "AutoFill" command to execute.

The framework implements processing of autofill-address-, autofill-geocode-, and autofill-map- groups. Group address will verify postal addresses with Google Geocoding API. Addresses in the United States can be also optionally verified with USPS.  Group geocode will perform address lookup from latitude and longitude fields in the group. On-Demand field tagged as autofill-(address|geocode)-map will resolve the address into a static map presented to the user.

Event menuitem.app

New event menuitem.app is triggered on the document to allow a custom script to form. For example, the following script will display a login form if Test item is selected in the menu.

(function () {
    $(document).on('menuitem.app', function (e) {
        if (e.item.url === '/pages/test') {
            $app.touch.show({
                controller: 'MyProfile', 
                view: 'loginForm',
                startCommand: 'New',
                startArgument: 'loginForm'
            });
            return false;
        }
    });
})();

This is how the app will behave in response to the user actions:


External JavaScript Business Rules

It is now possible to create JavaScript business rules without explicit definition in the data controller. Save the file in ~/js folder of the app, put a breakpoint, and hit Ctrl+F5 when the app is loaded in the browser. Your custom business rules will execute in Before phase giving you complete control over various behaviors of the app. This type of business rules is also support in native mode.

This particular sample when force the user to enter USA in the Country field of Suppliers controller for the record to save. This is a perfect example of client-side validation.

Also the user will not be able to execute New command and therefore will not be able to bring up the form to create new records.

(function () {
    $app.rules = {
        'Suppliers': {
            'Update':
                function (dataView, args) {
                    var data = dataView.data();
                    if (data.Country !== 'USA') {
                        $app.input.focus({
                            fieldName: 'Country',
                            message: 'Only USA is allowed in this field.'
                        });
                        return false;
                    }
                },
            'New': function (dataView, args) {
                $app.touch.notify('You are not allowed to create new records.');
                return false;
            }

        }
    };
})();

This how it make look at runtime:


Also Included


The following features and bug fixes are included in this release:

  • (Batch Edit) Many-to-Many fields display "keep original selection" and "delete original selection" options to allow either expanding the set of selected options or to have it replaced with a new set.
  • (EASE) Tracking of created/modify by/on fields does not overwrite the values of Created By/On fields when blobs are uploaded.
  • (EASE) Modified/Created By/On fields are displayed on form views in edit/read mode.
  • (EASE)  Modifed/Created By/On fields are not displayed in form views in "new" mode.
  • (Classic UI) Projects with advanced options and "Classic UI" are correctly generating the theme folder.
  • (Framework) Data access objects based on models without a primary key will not result in compilation error when the app is generated.
  • (Touch UI) Floating category without wrapping will display 2 or 3 columns of fields with the minimal width of the form equal or greater than MD and LG accordingly.
  • (Touch UI) Floating category with wrapping will display 2, 3 or 4 columns of fields with the minimal width of the form equal or greater than SM, MD,  and LG accordingly.
  • (Touch UI) Import treats dates serialized in Excel files as UTC dates and performs de-serialization equivalent to the one performed when getting data from the server.
  • (Touch UI) Smart dates are instantly refreshed if a date value is changed by user via direct input without using the calendar popup.
  • (Touch UI) Map locations on iOS and Mac open via OS-specific URLs.
  • (Touch UI) URLs prefixed with "_blank:" will open in the default OS web browser when running in native mode (Cloud On Time or branded host app).
  • (Classic) Modal forms with conditionally visible content are resized after dragging.
  • (Classic) Initial state of "form" buttons with When Client Script expressions is calculated correctly.
  • (Touch UI) JavaScript expressions specified in When Client Script property of actions are evaluating the current row using the same mechanism as the Visible When and Read Only When expressions of fields and categories. This improves performance and addresses issue of incorrect values tested when form views are opened.
  • (Touch UI) RTF editor toolbar is fully visible whatever the position of the "Rich Text" field in the form view.
  • (Touch UI) RTF fully supports "Dark" theme.
  • (Touch UI) Calendar view does not display "New/grid1" option when user clicks the calendar to create an event.
  • (AppGen) Display name of the projects is used as application name when the app name is not defined in the project features.
  • (Touch UI) ListBox/RadioButtonList/CheckBoxList do not cut the bottom of item in FireFox browser.
  • (Classic)  Dedicated Login page correctly links bootstrap CSS file.
  • (AppGen) It is now again possible to create new projects based on ASPX page model with the framework in the class library.
  • (Framework) Message "unable to load..." with either the name of the resource script of path to the script is reported if there was an exception while enumerating client library scripts.
  • (App Gen) All translated files are created with UTF-8 encoding Byte Order Marker. If the translated resources are the same, then the files are not overwritten.
  • (AppGen)  All files are saved in UTF-8 format with explicit Byte Order Marker during the build process of the project.
  • (AppGen) VB projects with the core framework in the class library are generated correctly.
  • (Touch UI) Confirmation controller will display the value of "data field" of the context record in the header of the form.
  • (Touch UI) Action with confirmation controller will cause explicit validation of field value before execution. If action causes validation error, then the confirmation controller will not execute until all validation errors are fixed.
  • (Action State Machine) Calling BusinessRules.PreventDefault() method will cause action state machine to stop processing of actions unless Result.Continue() was explicitly requested or the command name was Insert|Update|Delete. 
  • (Action State Machine) If a value is assigned to Result.NavigateUrl in business rules, then the framework will stop processing of the actions unless Result.Continue() is called explicitly in business rules.
  • (Touch UI) Event createlayout.dataview.app is triggered on the document whenever a form layout is required. Event generatelayout.dataview.app is triggered once and the output is cached as needed.
  • (Project Wizard)  App generator version is embedded in DataAquairum.Project.xml to ensure regeneration of core framework files when f the project has been cloned/copied after a product update installation.
  • (Project Wizard) Data Model List or Business Entity List is automatically focused when Data Model & Business Logic page is activated.
  • (Project Wizard) Data Model List is fully redrawn after a new model is added.   Business Entity List is fully extended when there are no models.
  • (Client Framework) Method $app.execute accepts filter in the form of an object. For example, filter: {CategoryID:5}.
  • (Client Library) Method DataView.data() returns an object with properties representing current values of fields. New object property "_modified" will have its own properties representing old values of modified fields.
  • (Framework) XmlConverter automatically locates the first element in XML document and takes its name for the root JSON property if the root is not specified.
  • (AppGen) Removed redundant parenthesis for simple "Not" unary expressions in the code of c# projects.
  • (Framework) XmlConverter performs a robust enhanced conversion of XML to JSON to support v9 Project Designer and Inspector.
  • (Framework) User settings embedded in the page do not include "server" section from ~/touch-settings.json. This section is removed before inclusion in the page.
  • (Framework) Developers can implement method ApplicationServices.ValidateBlobAccess to alter the verification of user access to the row with the blob and the blob field itself. The overridden method can return false to disable blob access validation.
  • (Framework) Removed "download done" cookie creation when Blob.DirectAccessMode is true.
  • (Touch UI) Partially visible summary view is not scrolled into view when an option on its toolbar is selected.
  • (Touch UI) Fixed the bug in the implementation of auto focus on the last input when the window is activated.
  • (Framework) Added auto-registration of Code On Time App Builder v9.
  • (Touch UI) Reduced redundant functionality of jQuery Mobile for a more compact code.
  • (Touch UI) JavaScript business rules automatically skip updating values of fields with unchanged values.
  • (Touch UI) JavaScript event menuitem.app is triggered on document object before the menu option is selected. Event property "item" provides access to "url", "description", "title", and cssClass associated with the selected menu item. If an event handler returns false or prevents default then the menu option is not processed by the framework. Use this method to execute custom actions always available in the user interface.
  • (Client Framework) Added support for declarative JavaScript business rules that do not require explicit definition of the rule.
  • (Touch UI) Method $app.touch.show accepts object as "filter" property in the options for simplified syntax of filter definition.
  • (Framework) TLS12 is always enabled in the apps.
  • (Framework) Apps with ASPX page implementation do not serve files with *.json extension over HTTP.
  • (Framework) Denies HTTP access to acl.json, touch-settings.json, ~/permissions, and ~/reports folders in apps with SPA implementation of pages.
  • (Framework) Default settings from ~/touch-settings.json are stored in application cache for improved performance.
  • (Touch UI) Email icon is displayed in context menu as an independent action for "email" fields.
  • (Touch UI) Script error is displayed as notification when an exception is raised in the rendering phase of the view on the client
  • Friday, September 23, 2016PrintSubscribe
    Calculating Driving Distance Between Points

    In businesses that require a lot of driving and tracking packages, it is invaluable to estimate a driving distance between two different addresses or sets of latitude/longitude. Starting in release 8.5.11.0, C# and Visual Basic business rules now have access to the CalculateDistance() method. This method will query the Google Distance Matrix API to estimate driving distance.

    The results from the CalculateDistance() business rule method displayed in a messsage.

    It is required to obtain and add a Maps API Identifier to your project in order to use this feature.

    Please make sure to follow Google Maps APIs Terms Of Service. Of note is section 10.5.d, which restricts long-term storage of Content.

    Let’s add a custom action to the Employees page that, when pressed, will display how far the employee lives from the main office using a code business rule.

    First, we need to add an action that will be accessible to the user in order to trigger the code.

    Start the Project Designer. In the Project Explorer, switch to the Controllers tab. Right-click on “Employees / Actions / ag1 (Grid)” node, and press New Action.

    Adding an action to grid scope of Employees controller.

    Enter the following settings:

    Property Value
    Command Name Custom
    Command Argument DistanceFromHQ
    Header Text Distance From HQ
    When Key Selected Yes

    Press OK to save. Next, let’s create a business rule that will be triggered when the user presses the action. Right-click on “Employees / Business Rules”, and press New Business Rule.

    Adding a business rule to Employees controller.

    Enter the following properties:

    Property Value
    Type C# / Visual Basic
    Command Name Custom
    Command Argument DistanceFromHQ
    Phase Execute

    Press OK to save the business rule. On the toolbar, press Browse to generate the application and create the rule file.

    When generation is complete, press “Edit Rule” on the action bar to open the file in Visual Studio.

    Editing the rule in Visual Studio.

    Replace the contents with the following:

    C#:

    using System.Data;
    using MyCompany.Data;
    using MyCompany.Models;
    
    namespace MyCompany.Rules
    {
        public partial class EmployeesBusinessRules : MyCompany.Data.BusinessRules
        {
            
            /// <summary>
            /// This method will execute in any view for an action
            /// with a command name that matches "Custom" 
            /// and argument that matches "DistanceFromHQ".
            /// </summary>
            [Rule("r100")]
            public void r100Implementation(EmployeesModel instance)
            {
                // combine address pieces with ","
                string sourceAddress = string.Join(",", instance.Address, instance.City,
                    instance.Region, instance.PostalCode, instance.Country);
                string destinationAddress = "1 Microsoft Way,Redmond,Washington";
    
                // get distance and calculate miles
                decimal meters = CalculateDistance(sourceAddress, destinationAddress);
                decimal miles = meters * 0.00062137m;
    
                // show result
                if (meters == 0)
                    Result.ShowAlert("No path found.");
                else
                    Result.ShowAlert("Distance from HQ is " + meters 
                        + " meters, or " + miles + " miles");
            }
        }
    }
    

    Visual Basic:

    Imports MyCompany.Data
    Imports MyCompany.Models
    
    Namespace MyCompany.Rules
        
        Partial Public Class EmployeesBusinessRules
            Inherits MyCompany.Data.BusinessRules
    
            ''' <summary>
            ''' This method will execute in any view for an action
            ''' with a command name that matches "Custom" 
            ''' and argument that matches "DistanceFromHQ".
            ''' </summary>
            <Rule("r100")>
            Public Sub r100Implementation(ByVal instance As EmployeesModel)
                ' combine address pieces with ","
                Dim sourceAddress = String.Join(",", instance.Address, instance.City,
                        instance.Region, instance.PostalCode, instance.Country)
                Dim destinationAddress = "1 Microsoft Way,Redmond,Washington"
    
                ' get distance and calculate miles
                Dim meters = CalculateDistance(sourceAddress, destinationAddress)
                Dim miles = meters * 0.00062137D
    
                ' show result
                If (meters = 0) Then
                    Result.ShowAlert("No path found.")
                Else
                    Result.ShowAlert("Distance from HQ is " & meters &
                                     " meters, or " & miles & " miles")
                End If
            End Sub
        End Class
    End Namespace
    

    Switch back to the web browser, and press the three dot menu button next to any row to reveal the grid action menu.

    Activating the grid scope menu for a row in Touch UI.

    Press “Distance From HQ” action, and a message box will display the distance.

    The results from the CalculateDistance() business rule method displayed in a messsage.

    Note that it is also possible to pass a latitude and longitude by separating the values with a comma, such as in the following example:

    CalculateDistance(instance.Latitude + "," + instance.Longitude, destinationAddress)
    Thursday, September 22, 2016PrintSubscribe
    Geocoding

    Geocoding is the process of capturing an address and converting it to exact latitude and longitude coordinates. Starting with release 8.5.11.0, apps generated with Code On Time now support automatic geocoding of address fields with the proper tags, as well as a Geocode() method available in C# or Visual Basic business rules.

    Example of result from Geocode method.

    Please make sure to follow Google Maps APIs Terms Of Service. Of note is section 10.5.d, which restricts long-term storage of Content.

    Both methods below require addition of a Maps API Identifier. The following examples will use a modified version of the Employees table from the Northwind sample project. Use the following script to add the required columns before creating the project.

    ALTER TABLE Employees
    ADD Latitude decimal(9, 6) NULL,
        Longitude decimal(9, 6) NULL

    If using an existing project, make sure to refresh the application after executing the script. Then, open the model for Employees and check the checkbox next to the three new fields to include them in the Employees controller.

    Geocoding with Tags

    The easiest way to geocode a set of address fields is to tag the source and destination data fields in the view. If the correct fields are tagged, the values will be geocoded when the user saves a new record or updates an existing record. When updating an existing record, the geocode request will only be sent if at least one of the source fields has been modified, in order to avoid extraneous API requests.

    Let’s add the relevant tags to start geocoding employees.

    Start the Project Designer. In the Project Explorer, double-click on “Employees / container1 / view1 (Employees, grid1) / createForm1 / c1 – New Employees / Address” data field node.

    Selecting the Address data field of createForm1 view of Employees controller.

    Make the following change:

    Property Value
    Tags geocode-address

    Press OK to save the data field. Use the above procedure to make the changes below:

    Data Field Tag
    City geocode-city
    Region geocode-region
    PostalCode geocode-zip
    Country geocode-country
    Latitude geocode-latitude
    Longitude geocode-longitude

    On the toolbar, press Browse. When the application opens in the default browser, create a new employee.

    Entering a new employee.

    Upon pressing Save, the geocode request will be sent. If a result is returned, the new employee record will have updated Latitude and Longitude fields.

    The Latitude and Longitude fields have been updated.

    Geocoding in C#/Visual Basic Business Rules

    The tag method explained in the previous section is convenient for automatic update of Latitude and Longitude fields. However, if the latitude and longitude need to be used in a calculation, the Geocode() business rule method can be used. Let’s add a business rule that utilizes this method to geocode the employee’s address and show an alert with the resulting latitude and longitude.

    In the Project Explorer, switch to the Controllers tab. Right-click on “Employees / Actions / ag4 (ActionBar) – Edit/Delete” and press New Action.

    Adding a new action to Employees controller.

    Specify the following properties and press OK to save the new action.

    Property Value
    Command Name Custom
    Command Argument ShowLatLong
    Header Text Show Lat/Long
    When Key Selected Yes

    Next, right-click on “Employees / Business Rules” node, and press New Business Rule.

    Adding a new business rule to Employees controller.

    Configure the rule as following:

    Property Value
    Type C# / Visual Basic
    Command Name Custom
    Command Argument ShowLatLong
    Phase Execute

    Press OK to save the new business rule. Then, press Browse on the toolbar to generate the application, as well as create the relevant business rule file.

    When complete, press “Edit Rule” on the action bar to open the file in Visual Studio.

    Editing the rule in Visual Studio.

    Replace the contents of the file with the following:

    C#:

    using MyCompany.Data;
    using MyCompany.Models;
    
    namespace MyCompany.Rules
    {
        public partial class EmployeesBusinessRules : MyCompany.Data.BusinessRules
        {
            
            /// <summary>
            /// This method will execute in any view for an action
            /// with a command name that matches "Custom" and argument that matches "ShowLatLong".
            /// </summary>
            [Rule("r100")]
            public void r100Implementation(EmployeesModel instance)
            {
    
                decimal latitude;
                decimal longitude;
    
                // join address parts with "," separator
                string address = string.Join(",", instance.Address, instance.City, 
                    instance.Region, instance.PostalCode, instance.Country);
    
                if (Geocode(address, out latitude, out longitude))
                {
                    Result.ShowAlert("Latitude: " + latitude + ", Longitude: " + longitude);
                }
                else
                {
                    Result.ShowAlert("Geocode failed to resolve address.");
                }
            }
        }
    }
    

    Visual Basic:

    Imports MyCompany.Data
    Imports MyCompany.Models
    
    Namespace MyCompany.Rules
        
        Partial Public Class EmployeesBusinessRules
            Inherits MyCompany.Data.BusinessRules
            
            ''' <summary>
            ''' This method will execute in any view for an action
            ''' with a command name that matches "Custom" and argument that matches "ShowLatLong".
            ''' </summary>
            <Rule("r100")>  _
            Public Sub r100Implementation(ByVal instance As EmployeesModel)
                Dim latitude As Decimal
                Dim longitude As Decimal
    
                ' join address parts with "," separator
                Dim address = String.Join(",", instance.Address, instance.City,
                                instance.Region, instance.PostalCode, instance.Country)
    
                If (Geocode(address, latitude, longitude)) Then
                    Result.ShowAlert("Latitude: " & latitude & ", Longitude: " & longitude)
                Else
                    Result.ShowAlert("Geocode failed to resolve address.")
                End If
            End Sub
        End Class
    End Namespace
    

    Switch back to the application running in your default browser, and navigate to the Employees page. Ctrl+click on a row to highlight the row. On the toolbar, press  “Show Lat/Long”.

    Activating the "Show Lat/Long" custom action.

    A message box will be displayed with the employee’s latitude and longitude.

    The popup shows the returned latitude and longitude.