Quantcast
Channel: Code On Time
Viewing all 336 articles
Browse latest View live

Getting Started with Model Builder

$
0
0

Code On Time release 8.5.6.0 introduces Model Builder – a new way to build the app you want.

In the past, applications created with Code On Time created a baseline for every entity in the database, and tried to estimate the best configuration for every page, controller, and application component. A frequent complaint about the previous versions about the app generator is the lack of ability to control this automatic process. In response to these complaints, we have included a new feature, designed to give Code On Time users more control over the application development process.

The Model Builder allows developers to design a data model for each and every database entity used by the app generator. They can pick and choose fields to include in the model, define or create foreign key relationships, and even import fields from several levels away easily. Names and labels can be easily changed, formatting can be applied globally, and sorting and filtering can be applied to form a business entity.

The Model Builder is now the first step for the creation of any Code On Time premium database app.

See an example of the default data model for Order Details table of Northwind database.

example of the default data model for Order Details table of Northwind database

In addition to Model Builder, the following noteworthy bug fixes and improvements have been added to release 8.5.6.0:

  • Support for Visual Studio 2015
  • Support for Azure 2.7 and 2.8
  • Support for .NET 4.6
  • CodeMirror integration in Model Builder and Project Designer
  • Charts in Touch UI now support color tags. Specify a list of colors, like so: "pivot1-row1-colors:'red, green, blue'".
  • Added tag “calendar-mini-disabled” to disable the mini calendar on the sidebar
  • Controller XML files ending with “.baseline.xml” in the Controllers folder will be used as a baseline controller, ignoring the data model.
  • Fixed scaling problem on high DPI devices.
  • Touch UI inputs now show a single line below the input.
  • Neutral cultures are now included in the list supported by app generator
  • Boolean fields will show check glyphicon in Touch UI when in read-only mode
  • Many more minor bug fixes

Working with the Model Builder

After entering the database connection string, a list of database entities will be listed. Select an entity to start building a data model.

List of database objects listed that can be used to create data models.

The Model Builder will open.

The default data model for Products table.

Adding additional fields to the data model is simple. Check the box next to a column to include the field.

Including "Country" field in the data model.

Fields defined with a custom SQL formula are also simple to add. Click the “Add Formula Field” button on the toolbar to get started.

Adding a custom SQL formula field to the data model.

Enter a name for the field in the first textbox. Enter the formula in the text area.

Adding a custom SQL formula field to the data model.

Use “Ctrl+Space” to see a list of columns. Fields can also be dragged from the diagram to be added to the formula.

Auto complete option in the SQL formula field.

Reorder fields in the model by dragging the Field column to the correct position.

Reordering fields via drag and drop.     Reordering fields via drag and drop.

Field labels and options can be changed by clicking in the cell. The following shortcuts can be used to quickly and easily navigate between the different cells:

  • If mouse cursor shows text, click to change
  • F2 to Select All/End
  • Left/Right moves between cells in row
  • Tab/Shift+Tab to move between cells
  • Up/Down to move up down
  • Enter/Shift+Enter to move up down
  • Esc once will restore original if changed, Esc twice will exit edit mode
  • Ctrl+Enter will save, stay editing

Changing labels in the data model.

Sorting can be added to the data model by entering the Sort Type and Sort Order.

Changing sorting in the data model.

The Query tab shows the command for the data model.

The Query tab shows the command for the data model.

The Data tab shows the output of the command. By default, Raw Data mode is on. This will show all primary and foreign key fields, and show native value formatting from the database.

The Data tab shows sample output of the data model's command.

Disabling Raw Data will hide primary and foreign keys, and apply formatting.

Disabling Raw Data mode will hide keys, and apply formatting.

The Labels button will replace field names with labels.

Enabling "Labels" button will replace field names with labels.

Click Save to persist the new data model. Proceed to generate the application. A page has been added, showing a grid of products, as defined by the data model.

A list of products, as defined by the data model.

The user can also switch to list view.

A list of products, as defined by the data model.

Automatic charts have also been created.

Charts automatically created for Products.

You can edit existing products or create new ones. Notice, however, that the SupplierID and Category ID have not been configured as lookups.

Products edit form, with Suppliers and Categories not defined as data models.

Let’s add Categories and Suppliers data models. Go back to the generator and create a data model for Categories. Notice that these two tables that are referred to are already suggested.

Creating data models for suggested database entities.

Create the data model for Categories.

Creating data model for categories.

Create a data model for Suppliers. Be sure to sort by CompanyName and disable the HomePage field.

New data model for Suppliers, sorted by CompanyName and HomePage field disabled.

Regenerate the project. Be sure to refresh when prompted. Notice that Supplier and Category are now rendered as lookups.

Products edit form with Supplier and Category models defined.

Activating the Supplier lookup will open a list of suppliers.

Supplier lookup

Activating the Categories lookup will show a list of categories to select.

Categories lookup.

Let’s create a second data model for Products, that only shows products from North America. There are two ways of creating a copy of a data model – saving a copy of an existing model, or creating a new model, listed under “Defined” section.

Creating a data model for an entity with an existing data model.

Let’s create a copy. Open the Products data model, and change the name to “NorthAmericanProducts” by typing in the name in the top-right corner.

Changing the name of the model to "NorthAmericanProducts".

Let’s add a filter to the new model. Click the “Add Filter…” button on the toolbar.

Adding a filter to the model.

Enter the filter in the text area.

Entering a filter.

In addition, sort the ProductName in descending order.

Sorting the model by ProductName in descending order.

The Query tab will show the new command.

The new command of the data model.

The Data tab shows that the sorting and filtering was a success.

The Data tab showing the output of the command.

To save the data model as a copy, activate the dropdown next to “Save”, and press “Save a Copy”.

image

Proceed to generate the application. Notice that another page has been added to the sitemap. This page is a Single Page Application created to handle products from North America.

The new page shows products from North America.

Virtual Connections

One of the most powerful aspects of the Model Builder is the ability to define virtual primary and foreign keys. Let’s create a data model using the view Alphabetical List Of Products.

Creating a data model for "Alphabetical List of Products".

The application framework is unable to perform any CRUD operations on a business entity until a primary key is defined. Let’s create a virtual primary key by right-clicking ProductID and pressing Set Primary Key.

Setting the virtual primary key of the Alphabeticallistofproducts data model.

The spec “VPK” will be added to the first column of the diagram.

The ProductID field has been specified as the primary key of the model.

Notice that because Alphabetical List Of Products is a view, foreign keys are not known, and values from these foreign key relationships cannot be included until a virtual foreign key is defined.

On the toolbar, click the “Add Table” button.

Adding a table to the diagram.

The field list at the top of the Model tab will be replaced with a list of database objects.

Adding a table from the list of available tables.

Drag the “dbo.Suppliers” table onto the diagram. Rename the alias of Suppliers to “Supplier” by clicking on the header of the new table in the diagram.

Renaming the new table to "Supplier".

Then, drag the “SupplierID” field from Alphabeticallistofproducts onto SupplierID column of Suppliers table to form a virtual foreign key. You can now check fields from the Suppliers table to include in the data model.

Including fields of Suppliers table into Alphabeticallistofproducts data model.

Sort this data model by entering “Descending” in the Sort Type of ProductName.

Sorting by ProductName.

The final result will show the inclusion of Supplier fields in the grid.

The new SPA for Alphabeticallistofproducts.


Conditional Styling of Data in Touch UI

$
0
0

Have you ever wanted to give your grids and forms a personal touch? Release 8.5.7.0 makes it possible with the inclusion of conditional CSS rules. These rules allow defining JavaScript expressions that are executed for every row in the view. These expressions have access to the values of each record. When the expression passes, a CSS class will be added to the row. You can then add custom styling to these rows to tell a story.

The picture below shows several examples of custom styling in Touch UI.

image

Adding a View Style Rule

The first step is to define a set of rules that will add CSS classes to the correct rows. The following examples will use the sample Northwind project.

Open the Project Designer. In the Project Explorer, switch to the Controllers tab, and double-click on Suppliers / Views / grid1.

Selecting grid1 view of Suppliers controller.

The view will be opened on the left side of the window. Switch to the Styles tab at the top of the screen.

Adding a new style to the 'grid1' view of Suppliers controller.

On the toolbar, press New | New Style to open the create form. Enter the following settings.

Css Classmyapp-country-usa
Test
$row.Country == 'USA'

This rule will add the class “myapp-country-usa” to every row where the “Country” column is equal to “USA”. The Test field is an expression written in JavaScript. The “$row” object is declared by the client library, and each field value is attached to this object when the expression is executed. The “myapp” prefix to the CSS class is added to ensure that there are no clashes with standard rules included in the application.

Press OK to save. Add one more style with the following configuration:

Css Classmyapp-contact-title-sales
Test
$row.ContactTitle != null&& $row.ContactTitle.match(/sales/i)

This rule will add “myapp-contact-title-sales” rule to every row where the Contact Title is equal to “sales”. The “i” at the end of the regular expression will ignore case.

Press OK to save. On the toolbar, press the Browse button to regenerate the app and open it in your default browser.

Notice that nothing has changed! The grid looks the same as it did before. The rules to add the CSS class has been added, but there have been no presentation changes that the user can see. By using Developer Tools (F12), the correct row can be inspected, and you can confirm that the class is present.

Inspecting the HTML of the page will reveal that the correct class has been added.

Next step will be to add some presentation to these rules.

Customizing Presentation with CSS

Switch back to the Project Designer, and press the Develop button at the top of the screen to open the project in Visual Studio.

In the Solution Explorer, right-click on the “~/touch” folder, and press Add | Style Sheet button.

Adding a new style sheet to the project.

Paste in the following rule:

.myapp-country-usa> .ui-btn:not(:hover):not(.app-selected):not(.ui-btn-active),.myapp-country-usa> .ui-btn:not(:hover):not(.app-selected):not(.ui-btn-active) .app-frozen-spacer {/* change this property */background-color: #ffd800 !important;
}

This rule will change the background color of the row, which has the class of “ui-btn”, as well as the spacer used as a background on the frozen column when the grid is scrolled to the right. This rule will not be used when the row is hovered over, clicked, or selected.

The result of this rule can be seen below.

The new CSS rule will add a background color to the relevant rows.

Another way of adding a highlight to a row that does not clash with hover, highlight, or select presentation would be to add a bar on the left side of the row.

.myapp-country-usa .ui-btn::after,.myapp-country-usa .ui-btn .app-frozen-spacer::after {display: inline-block;content: '';position: absolute;left: 0;top: 0;bottom: 0;width: 7px;/* change this property */background-color:  #ffd800 !important;
}

See the result in the screenshot. Notice that the yellow bar is still visible in the hovered first row, and the selected second row.

The new CSS rule will add a yellow bar to the left side of the relevant rows.

These rules can be combined, like so:

.myapp-country-usa > .ui-btn:not(:hover):not(.app-selected):not(.ui-btn-active),.myapp-country-usa > .ui-btn:not(:hover):not(.app-selected):not(.ui-btn-active) .app-frozen-spacer {/* change this property */background-color: #ffd800 !important;
}.myapp-country-usa .ui-btn::after,.myapp-country-usa .ui-btn .app-frozen-spacer::after {display: inline-block;content: '';position: absolute;left: 0;top: 0;bottom: 0;width: 7px;/* change this property */background-color:  #ffd800 !important;
}

The first row shows the background color, and the second row shows the bar on the left side when the user hovers over with a mouse.

The previous two rules have been combined, showing a yellow background and yellow bar on the relevant rows.

A more subtle way of adding custom styling to a row is to add a colorful triangle to the corner of the record. In this rule, the triangle will only be displayed in “List” presentation style by prepending the class “.app-listview”.

.app-listview .myapp-country-usa .ui-btn::after,.app-listview .myapp-country-usa .ui-btn .app-frozen-spacer::after {display: inline-block;content: '';position: absolute;width: 24px;height: 24px;transform: rotate(45deg);/* change these properties */top: 0;margin-top: -12px;left: 0;margin-left: -12px;background-color: forestgreen;
}

Here is the result. Notice that the triangle is still visible on the selected record.

A green triangle has been added to the card.

The previous example places the triangle in the top left corner. It can be easily moved to any other corner by using a combination of “top”, “left”, “bottom”, and “right” attributes, and changing the corresponding margins. The color was also changed.

.app-listview .myapp-country-usa .ui-btn::after,.app-listview .myapp-country-usa .ui-btn .app-frozen-spacer::after {display: inline-block;content: '';position: absolute;width: 24px;height: 24px;transform: rotate(45deg);/* change these properties */bottom: 0;margin-bottom: -12px;right: 0;margin-right: -12px;background-color: red;
}

The picture shows the triangle positioned in the bottom right corner.

A red triangle has been added to the bottom right corner.

Using Glyphicons

Many different glyphicons are included in the application. These glyphicons can be used in conjunction with CSS rules to customize your application even further.

A page that displays all glyphicons can be found at ~/touch/icons.html. Find the glyphicon that you want to use, and you can look up the corresponding class in the file “~/touch/bootstrap.css”.  It will be necessary in order to get the correct character code for the icon.

Finding the correct character code in the 'bootstrap.css' file.

Once the correct code has been located, it can be used in a custom CSS rule. The example below will place a large orange “alert” glyphicon in the “List” presentation style.

.app-listview:not(.app-grid) .myapp-country-usa > .ui-btn::after {display: inline-block;font-family: 'Glyphicons Halflings';font-style: normal;font-weight: normal;line-height: 1;position: absolute;/* change these properties*/content: "\e209";color: orange;font-size: 8em;bottom: 5px;right: 0;padding-left: 0.5em;opacity: .25;
}

The picture below shows the result.

The new rule shows a large orange alert glyphicon in the background of the card.

Glyphicons can also be used in a more subtle way. They can be placed next to any field using the “.app-field-[FieldName]” syntax. This rule will place them next to the correct grid column in the row, and the correct value in other presentation styles.

.app-grid .myapp-country-usa .app-field-CompanyName::after,.myapp-country-usa .app-field-CompanyName .app-field-data::after {display: inline-block;font-family: 'Glyphicons Halflings';font-style: normal;font-weight: normal;line-height: 1;padding-left: .5em;/* change these properties  */color: orange;content: "\e034";
}

The result is below.

A smaller orange 'flag' glyphicon has been added next to the CompanyName field of the grid.

Conditional styling is also supported in forms too! When the form is in read mode, the classes will be present. Make sure to add the style expressions defined at the beginning of this article to “editForm1” view of Suppliers controller.

The result can be seen below.

The same flag glyphicon has been added to the form.

Top Secret: New Form Layout Engine and “Lookup” Style in June 2016 Update

$
0
0

It’s been four months since the last software update. It does feel like an eternity, doesn’t it! 

Originally we intended to release an incremental set of changes in March of 2016.  A major rewrite of Touch UI form layout engine was also under way at that time.  One thing led to another and the team has decided to postpone the release by a couple of weeks to complete the new layout engine. Two weeks have stretched into a month and we have announced that the release will go out in the middle of May, which was too optimistic. Finally the development of the new code has been completed. We are validating the new capabilities and fine tuning the software.

Code On Time release 8.5.8.0 will become available on June 8, 2016.

The release incorporates our experience gained from the development of a few real-world projects. In the coming days we will post a collection of the highlights describing the product changes. Keep reading to see what’s new!

Layout Engine and Universal Input

The new layout engine has been introduced to enable custom form development with precise positioning of user interface elements in responsive fashion. We have developed a layering technique of HTML content that makes possible complex layouts without sacrificing performance.

The major runtime component of the layout engine is called Universal Input.  New version of Touch UI does not allocate multiple input controls when the form is rendered in the browser. An on-demand input control is created instead when a user interacts with the page content in edit mode. The input control takes the space allocated in the form layout for the data item. This makes possible positioning the fields with high precision. It is also creating an illusion of live inline editing of page content. Universal Input introduces keyboard-driven navigation for rapid data entry not found anywhere else.

Custom form development now becomes very similar to report development. You are developing a blueprint for data presentation and the data is “magically” editable as needed.  Custom form layouts are stored in the ~/Views folder of the project.

image

The follow up release 8.6.0.0 will introduce the Form Designer, the feature borrowed from the upcoming http://cloudontime.com.

If a custom form layout is not available then an automatic layout is created at runtime. The automatic layouts are similar to the most recent releases of Touch UI.

New Lookup Style

The screenshot shows an example of an Order record in edit mode. Notice that the text value of the customer company name is selected automatically. A tooltip is displayed when user hovers over the input field. The same field is also displayed at the bottom of this layout. It is now possible to place a data field on custom form any number of times with optional read-only flag when needed. 

The lookup data fields based on foreign keys are indicated by drop arrows pointing to the right. A user can tap on the arrow to make a selection or use keyboard Right key to activate the row selection from the full screen view of customers. The lookup data view is also activated if user presses Ctrl+Enter.

image

Up and Down keys will change the selection in the Grid, List, or Cards view of lookup records. Press Enter key or a tap on an item to select the lookup value.

image

Pressing Ctrl+Space or Ctrl+Down will activate a simplified selection mode of a lookup value.

image

User can choose a different value with Up/Down keys, manually activate the full screen selection mode of a lookup value, or create a new lookup item if enabled.

image

Typing a text in the input field will start auto-complete mode of lookup value search in the second instance of “customer company name” data field at the bottom of the layout in the next screenshot.

image

User will simply erase the lookup text to clear the value.

image

This is the same form layout displaying a record in the new mode in the next screenshot.

Notice that the forms in the new mode now display Save, Save And New, and Cancel buttons. Some of the shipping fields display custom placeholders with input instructions. Clicking on the field label or in the empty space will activate the input control.

image

Desktop UI users will recognize that the new lookup style combines the direct selection of lookup values from the multi-column view of records with the ability to type ahead in Auto Complete style.

The dedicated auto-complete mode is now also available for lookup fields in Touch UI. If this style of value selection is enabled then the arrow next to the field value will point down and See All option will not be available in the popup list of values.

The same presentation will be displayed for Drop Down List view style in forms. Inline editing in grid uses Auto Complete style input for Radio Button List and List Box styles of lookup selection.

8.5.8.0 Has Landed! New Form Rendering Engine, Advanced Lookup Input, Calendar Input, Data View Fields, Tiny Density, Save and New

$
0
0

The long awaited release 8.5.8.0 is here! Originally intended to be released in March of 2016, a shift in strategy has resulted in this release coming out in June. We greatly appreciate everyone’s patience, and hope that we find the result to be rewarding for everyone.

Form Rendering Engine

The biggest change in this release is an overhaul of the Form Rendering Engine. One of our biggest complaints for Touch UI was the lack of customizability of the form. The original implementation of forms provided for limited capability in ordering data fields. Categories were used to group data fields into new rows, columns, and tabs.

In response to these comments,we have added the ability to define HTML templates that allow precise positioning of data fields and custom content into the form. A simple example can be seen below.

Example of custom layout template in Touch UI.

These HTML templates will be placed under the ~/Views folder of your project. When loading a view, the application framework will attempt to find the file “[Controller Name].[View ID].html”. If not found, it will generate a default template.

A snippet from the template can be seen below:

<div data-layout="form"><div data-container="column" style="width:50%"><div data-container="collapsible" data-header-text="Order Information"><div data-container="row"><div data-control="description">This is the order information.</div></div><div data-container="row"><span data-control="label" data-field="CustomerID">CustomerID</span><span data-control="field" data-field="CustomerID">[CustomerID]</span></div><div data-container="row"><span data-control="label" data-field="EmployeeID">EmployeeID</span><span data-control="field" data-field="EmployeeID">[EmployeeID]</span></div>...

The entire template must be wrapped in a data-layout element, and various different data-container elements are available for easy positioning of elements. Rows can be used to automatically position fields. It is always possible to use your own elements and position items manually. More documentation on this feature will be coming soon.

These layouts work perfectly well on mobile devices, too.

Example of custom layout template in Touch UI on a small screen.

In order to make the process of developing form templates easy, a visual Form Designer will be included in future releases.

The engine utilizes our new Universal Input API in order to react to user clicks and key presses. When the user clicks on a label or field, the API will find and build the relevant input control in order to handle that field. When the user leaves the field, all values that show that field value will be updated. The API handles Tab, Shift+Tab, Up, Down, Left, Right, Enter, Shift+Enter keys in order to move between fields.

Lookup 2.0

With the new Form Rendering Engine, we decided to overhaul the lookup input control to allow your users to get their work done easier and faster. The new lookup allows the user to type in their search query, and a suggestion list will automatically be loaded. Use arrow keys to navigate up and down in the list. Press Enter on your keyboard to select an option.

The user can click on the arrow to the right of the field to navigate to the lookup view.

New lookup in Form Rendering Engine animation.

The user can also press Ctrl+Space to activate the list. From there, the user can create a new lookup record, or jump to the lookup view by pressing “See All”.  “Ctrl+Enter” will also activate the lookup view.

Client-side data caching and filtering is employed in order to ensure that performance is top-notch.

Calendar Input

Dates have always been a difficult data type to work with. Every browser implements native input differently, some working better than others. Rather than compromising in order to utilize the native input of every browser, a new Calendar Input has been developed. This input control is an extension of the calendar sidebar filter component, which also includes the upgrades.

New Calendar Input in Form Rendering Engine animation.

The input will be activated when the user focuses on the field. Selecting a day in the month will set that date. The user can drag or use the arrow buttons to move between different months. Clicking on the header will allow the user to select the month or year.

If the data field also renders time, a clock will be rendered. The user can click on an area in the clock to set the time. Clicking on the hour or minute part of the header will allow changing that part of the time. Clicking on AM/PM will toggle the time of day.

The user will continue to be able to manually edit the value in the input control.

If the input is activated on a very small screen or mobile device, the Calendar Input will be displayed in the center of the screen. The user must click “OK” to save the new value, “Cancel” to close the popup, or “Clear” to reset the value.

Calendar Input on small screens will cover input and show OK, Cancel, Clear buttons.

Notice that days that contain data in the month are bold. Hovering over the day will reveal a count of records on that day. The client library makes asynchronous requests to pull the data and caches it on the client. If performance is a concern, this feature can be disabled by tagging the data field “calendar-input-data-none”.

Data View Fields

In the past, Code OnTime users needed to configure pages with multiple data views in order to display lists of data related to the master record. This process led to a disconnect between the data and presentation layers of the application.

Release 8.5.8.0 changes the paradigm. A new field type has been introduced, “DataView”. This will allow users to embed lists of records directly into the forms of master records. This change brings controllers more inline with how users would intuitively understand business objects.

Simply define a field of type “DataView”, point to the correct controller, specify the filter field, and create a data field to bind it to the form. All pages that refer to that form will now reveal relevant child records.

Data View field example.

The traditional method of defining child data views still works. This can be used for child data views that should only be displayed on certain pages (or define another view that excludes the data view field).

Future releases of the app generator will allow users to perform inline editing of child records at the same time that the master record is being modified.

Grid Upgrades

This brings us to the new and improved grid. In previous releases, it was difficult to set the size of grid columns to match up with the intended look and feel. Release 8.5.8.0 has made the grid sizing process more transparent.

The grid will now use the exact size of each data field in columns when allocating space. If there are no columns defined, then the columns will be set to 2/3s of the length of the field, or various preconfigured lengths depending on the type of the field.

In order to make the client library more intelligent and require less involvement of the user, a new feature has been added to the grid – “Fit To Width”. This will automatically shrink the grid columns to fit the screen, down to a certain limit. The space allocated to each column is equal to the proportion of “columns” that field was assigned. This feature is automatically enabled for every grid. If the behavior is undesired, the data view can be tagged “grid-fit-none” to disable the functionality.

The width of the grid may surpass the width of the page – the user will then be able to drag the grid left and right to bring different columns into view. Touch input is now supported for dragging.

If a column is too small or big to see the data, the user can click and drag the divider between columns in order to resize.

Animation of grid dragging and column resizing.

Future releases will offer the ability to reorder the columns on the client.

“Tiny” Density

Touch UI applications offer several different display densities in order to fit the needs of every user. The smallest size, Condensed, was still larger than Desktop UI. Therefore, we are introducing “Tiny” display density, which uses the same font and font size of the desktop.

The picture below compares “Comfortable” and “Tiny” display densities.

Orders form with 'Comfortable' display density.    Orders form with 'Tiny' display density.

Business Object Model and Data Access Objects

Code business rules in previous releases of Code OnTime app generator would list each field in the parameters of the method. Controllers with over a hundred fields would result in sprawling and ungainly method signatures. To update a data field for the client, it was necessary to call the UpdateFieldValue() method. See an example of legacy code below.

using System;using System.Data;using MyCompany.Data;namespace MyCompany.Rules
{public partial class OrderDetailsBusinessRules : MyCompany.Data.BusinessRules{
        [Rule("r100")]public void r100Implementation(int? orderID,string orderCustomerID,string orderCustomerCompanyName,string orderEmployeeLastName,string orderShipViaCompanyName,FieldValue productID,string productProductName,string productCategoryCategoryName,string productSupplierCompanyName,FieldValue unitPrice,short? quantity,float? discount)
        {
            UpdateFieldValue("Quantity", 1);
        }
    }
}

Release 8.5.8.0 will now generate data model objects for each controller that has a code business rule, and will pass this object as a parameter to the method. The setters for each property of the data model object will update the corresponding field on the client side.

using System.Data;using MyCompany.Data;using MyCompany.Models;namespace MyCompany.Rules
{public partial class OrderDetailsBusinessRules : MyCompany.Data.BusinessRules{
        [Rule("r100")]public void r100Implementation(OrderDetailsModel instance)
        {
            instance.Quantity = 1;
        }
    }
}

The new business rule format is vastly easier to read and understand, even for non-professional C# or Visual Basic developers.

Legacy business rules will continue to function as they did before.

Release 8.5.8.0 no longer offers a way to enable data access objects globally. The developer will need to enable data access objects on each controller by enabling the “Generate Data Access Objects” checkbox. These objects will extend the business object models. Models and data access objects will now be stored under ~/App_Code/Models folder.

Miscellaneous

These are just some of the new features in release 8.5.8.0. A more comprehensive list can be seen below:

  • Fields now have the option to be set as “Virtual”. These fields will never be included in Insert or Update queries, but are still editable by the user and can be read and manipulated in business rules. Developers no longer need to mark fields as “not modified” in rules in order to use custom fields.
  • Controllers can now be generated with “Save” and “Save and New” in create forms. By default, new applications will have this enabled by default. It can be toggled with the “Use ‘Save’ and ‘Save and New’ in forms” checkbox in the Features page of the Project Wizard.
  • Vast performance enhancements in page loading, button clicking, form opening, grid rendering and dragging, calendar rendering and dragging. HTTP requests are now smaller and data is cached when possible.
  • Re-selecting a record in the form after creating a record will no longer go back to the grid before loading the edit form. This results in significantly faster workflow when inserting multiple records.
  • Support for Report Viewer 2015.
  • Touch gesture support for Drag & Drop API – tested with Surface Pro 4, iPhone 6 Plus, iPad Pro, Nexus 5x, S7 Edge. This API is used in calendar, grid, calendar input, and panels.
  • Model Builder Tooltip API has been ported to Touch UI.
  • “Borrowed” fields defined in data models will be copied when the lookup value is changed. These fields will now be included as read-only in the create form.
  • Changing namespace of application in Web App Factory will move data model files to correct location.
  • A grey overlay will cover the screen if the user attempts to “double” click an action while another action is executing.
  • Custom scrollbar ensures a uniform user experience across browsers and themes.
  • View templates can exclusively contain the file name of another template. The application framework will load the file with that file name.
  • The text “Loading” will be displayed when the page is loading.
  • Blob Adapters no longer require the user to be logged in when there is no membership enabled.
  • Data Text Field and Data Value Field are initialized correctly if a model exists for the lookup controller.
  • Virtual lookup fields are now correctly created when defined in the data model.
  • Removed installer dependency to .NET 3.5.
  • The web.config file will not be overwritten unless necessary to avoid the “AppDomain Unloaded” message in Visual Studio.
  • Many other minor bug fixes.

We were not able to finalize some of the features that we desired to include in this release, due to time constraints. Expect to see these features in future releases:

  • Modal forms in Touch UI.
  • Grid inline editing (Data Sheet mode).
  • Use of HTML templates to define Grid/List/Card layouts.
  • Swipe left/right action group. Actions placed in this action group will be revealed when user performs the relevant gesture in the grid.
  • Promoted action group. Actions placed in this action group will be revealed when user clicks on the floating promo button at the bottom of the screen.
  • Sidebar will be rendered in the left menu panel when the screen is small or sidebar is disabled.
  • Revealing mini calendar under Calendar mode selector when sidebar is not visible.
  • Reordering of grid columns via drag & drop. The order will be saved in the browser cache.
  • Support for Azure 2.9.
  • “Bucket” lookup will allow selecting multiple items from the lookup view.
  • Rich Text Editor in Touch UI.
  • Visual Form Designer.
  • Multi-day events in Calendar.

Web Site Factory

$
0
0

All project types have the same level of features, offered in different forms. Web Site Factory projects are the simplest and easiest to work with. They do not require Visual Studio or any extensions in order to compile just-in-time. The folder layout can be seen below.

Folder layout of Web Site Factory project.

All files necessary for Code OnTime app generator to create the project are located at the root. The solution file, used by Visual Studio, is also located at the root. All web site files and folders are located in the ~/WebSite folder. This folder layout makes it easy to place the entire project folder under source control.

Note that Web Site Factory projects created in release 8.5.8.0 or below will have all project and web site files and folders at the root of the project, and the solution file was placed at ~/Code OnTime/Solutions/Web Site Factory/[Project Name] folder. The app generator will ask to move the web site files under the ~/WebSite folder if an older project is detected in release 8.5.9.0 or above. Selecting ‘Yes’ will automatically move the files. If your project is under source control, press ‘No’ and move the files manually to match the folder layout above.

Learn how to get started creating a Web Site Factory project.

Source Code Version Control

$
0
0

Every user of a computer has experienced a situation when they really wish they could wind back time. From hardware failure losing recent work, to changes made to a file that need to be undone, this capability is necessary to ensure productivity is not lost.

Software development is no different. The most common solution to this problem is through the use of source control systems such as Git, Microsoft Team Foundation Services (TFS), or Apache Subversion (SVN). These solutions will monitor a specific set of files, and allow the user to “commit” a version of files to a repository. When necessary, the user can revert to older versions of these files. Even better, it allows the development of software projects among multiple users. 

Code OnTime app generator makes it easy to use source control with your project. When the type of source control is specified, the generator will create requisite files that allow easy exchange of application files and changes made to project configuration.

Getting Started With Source Control

Let’s place our sample Northwind project under source control using Git. On the home page of the app generator, click on the project name. Select “Settings” from the Project Action screen, and then select “Source Code and UI”.

From the Source Control dropdown, select “Git”.

Selecting a source control for the project.

Press the Finish button, and then press “Generate” to generate the application. If the project folder is inspected, two files have been added to the root.

Project with source control now generates sync files.

A default “.gitignore” file is added, based on the standard file created by Visual Studio, with several Code OnTime files listed at the bottom. If TFS source control was selected, a corresponding “.tfignore” file will be added.

The other file will be named “Sync.[Machine Name]-[User Name].xml”. This file holds all transactions made in the Project Designer by the current user and machine. When the application is refreshed, all “Sync.XXX.xml” files at the root of the project will be merged together and sorted by transaction timestamp. The merged file is used to create the “Controllers.Log.xml” and “Application.Log.xml”, which hold transactions that are applied to controllers and application pages, controls, and data views, respectively.

This allows work from multiple machines to be smoothly integrated, without having to deal with manually merging XML files.

Next, let’s push this project to a new repository. This process may differ based on the source control and tool used to initialize the repository.

On the home page of the app generator, select the project name and press Develop to open the project in Visual Studio.

In the Solution Explorer (typically found on the right side of the screen), right-click on the solution node and press “Add Solution to Source Control”.

Adding the solution to source control using Visual Studio.

In the “Choose Source Control” popup that opens, select “Git” and press OK.

Selecting Git for the source control.

If the Visual Studio Git Provider has not been used before, it will require configuring your user name and email address. Click the “Configure” link, visible at the top of the Team Explorer window, set your desired settings, and press Update.

Next, enter a commit message, and press Commit to create the first commit in your local repository. Make sure that the necessary files are included in the commit.

Creating the first commit.

If the commit was successful, a message will appear at the top of the screen, stating that the commit was created. It will also prompt to sync the repository with a server. Click the “Sync” link to sync to a server.

The same screen can be reached by pressing the Home icon from any screen, and selecting “Sync” option.

The first commit was created successfully locally. Time to synchronize online.

Several options will be available. For this example, we will use GitHub. If you have not logged into GitHub on this computer, click the “Login” button, enter your credentials, and press “Login” again.

Logging into your GitHub account.

Select “Get Started” link under the “Publish to Github” section.

Getting started to synchronize your repo with Github.

Select your account, enter a repository name, and add a description (optional). Please note that private repositories require a subscription on GitHub. If the repository is public, then anyone can find the source code on the Internet. Choose accordingly.

Press Publish to push your repo to GitHub.

Selecting project name and description for pushing to Github.

Once the upload process is complete, you will be able to access your repository online.

The online repository on Github.

Synchronizing Changes

Now that the repository is online, you will need to synchronize it. Suppose that several changes have been made to the web app. Pages have been shuffled around, data fields customized, models added, business rules changed. Make sure to generate the application before synchronizing any changes.

Open the project in Visual Studio, open the Team Explorer, and select “Changes”. You can also right-click on the solution and press “Commit”.

Uploading a new commit to Github.

Enter a commit message, and click the dropdown next to “Commit”.

Press the “Commit” button if you wish to create a local commit, but not upload your changes to the server.

Press “Commit and Push” to upload your commit to the server.

Press “Commit and Sync” to upload your commit, and download any changes that may have been pushed to the server previously.

At this point in time, press “Commit and Push”.

Commiting and pushing your commits to the online server.

When the process is complete, a message will be displayed.

Downloading a Web App From Source Control

Suppose a team member has joined your team. You will need to give your teammate access to your repository. Log into your repository server and give your team member’s account access to the repo.

For a GitHub repo, you will need to navigate to the correct webpage on the GitHub website. Select the Settings tab near the top of the screen, and switch to the “Collaborators & Teams” section. Enter your member’s screen name in the Search bar and press “Add collaborator”.

Adding a collaborator to the repo.

On your team member’s computer, start Visual Studio. Press “Open From Source Control…” on the Start Page if visible. Otherwise, press the green Connections icon on the Team Explorer.

Connect pane in Team Explorer.

Select the “Clone” link under GitHub section. Click the repository you shared with the team member, and enter the correct path. In this case, the path is “~/Documents/Code OnTime/Projects/Web Site Factory”.

Selecting a repository to clone.

Restart the app generator. If the repository has been placed in the correct location, a new project will appear in the project list.

Pulling Changes From The Server

Suppose that your team member has made some changes, and you wish to pull these changes down to your computer.

Open the project in Visual Studio. In the Team Explorer, select “Sync” button.

Home page of Team Explorer.

The Synchronization pane offers several options.

The “Fetch” button will download pending commits, but will not integrate changes.

The “Pull” button will download pending commits and perform merge operations if necessary to bring your repository in line with the server.

The “Sync” button will uploading pending commits, downloads commits from the server, and performs merge operations to integrate remote changes with your local changes.

At this time, press “Sync”. The commits made by your coworker will be downloaded and integrated.

One last step is needed. Switch back to Code OnTime app generator. Select the project name, and press “Refresh”. This will integrate synced changes into the current project.

Refreshing the project with Code OnTime app generator to integrate new changes into the project.

Enhanced Lookup Styles, Membership, and Source Code Version Control

$
0
0

Code On Time release 8.5.9.0 introduces an expanded set of lookup styles for Touch UI with new capabilities.

Mobile Factory and Web Site Factory projects now have a new file structure.

We are retiring the Sync Server. Source Code Version Control is now completely based on the file system and requires no additional external software. Learn more about configuring Source Code Version Control for your project.

Touch UI now offers customizable standard Login form, My Account, Password Recovery, and New Account Sign Up. These features are now a part of MyProfile data controller.

Make sure to refresh your project when generating a project with this release.

Take a look a the screen shots of the latest UI changes.

Radio Button Lists with a new styling:

image

The revived List Box view style:

image

The new style for many-to-many fields (Territories) and Auto Complete lookup style (Reports To).

image

Here are some of the fixes included in the release.

  • Desktop
    • Focus is displayed in Desktop UI around lookup inputs and checkboxes.
    • Desktop UI page will not lose scrolling after selecting an item from the lookup.
  • Touch UI
    • Calculated business rules now work in Touch UI forms.
    • “Password” Text Mode is now supported in Touch UI forms.
    • Enabled new horizontal scroll bars.
    • Enabled dragging on scroll bars.
    • Typing in form when child view is visible will no longer trigger search on the child view.
    • Greatly increased performance in form rendering.
    • Forms are re-rendered when the screen width changes.
    • Blob and signature fields are now supported.
    • Result.ShowAlert() now uses Touch UI styled popups. Desktop will still use standard browser alert.
  • General
    • Data Models will now be validated after project is refreshed. Fields no longer present in the table will be removed.
    • Model Builder will now check if a column exists and show a warning before executing query in Data tab.
    • Calendar data requests will no longer clash with manually defined chart definitions.
    • Many-to-many implementation is now handled within the application framework, instead of generated business rules. The corresponding methods in BusinessRules class have been replaced with stub definitions to avoid compilation errors. The framework will look to the target controller for lookup fields pointing to the primary controller and items controller to determine the correct field values to use.
    • GUID fields will not be included in grid and forms.

Next week we are planning to make available “basket” lookup style for many-to-many field processing.

Form Templates

$
0
0

Forms in Touch UI apps are laid out by HTML templates. When a form view is requested in the application framework, the ~/Views folder is queried for a template with file name of [Controller Name].[View Name].html. If the developer has placed a file matching that name in the Views folder, then the framework will read the file and pass it to the client library. The client will then use this template and inject data field inputs, labels, data views, and other controls into the template before rendering to the user. Otherwise, the client library will automatically build a template based on the definitions of categories and data fields.

The picture below shows the automatically built template for the default editForm1 view of Orders controller in the sample Northwind app.

The default template for Orders editForm1 view.

The generated template can be seen below. 

<div data-container="collapsible"data-wrap="false" data-header-text="Orders"><div data-container="row"><div data-control="description">These are the fields of the orders record that can be edited.</div></div><div data-container="row"><span data-control="label"data-field="CustomerID">CustomerID</span><span data-control="field"data-field="CustomerID">[CustomerID]</span></div><div data-container="row"><span data-control="label" data-field="EmployeeID">EmployeeID</span><span data-control="field" data-field="EmployeeID">[EmployeeID]</span></div><div data-container="row"><span data-control="label" data-field="OrderDate">OrderDate</span><span data-control="field" data-field="OrderDate">[OrderDate]</span></div><div data-container="row"><span data-control="label" data-field="RequiredDate">RequiredDate</span><span data-control="field" data-field="RequiredDate">[RequiredDate]</span></div><div data-container="row"><span data-control="label" data-field="ShippedDate">ShippedDate</span><span data-control="field" data-field="ShippedDate">[ShippedDate]</span></div><div data-container="row"><span data-control="label" data-field="ShipVia">ShipVia</span><span data-control="field" data-field="ShipVia">[ShipVia]</span></div><div data-container="row"><span data-control="label" data-field="Freight">Freight</span><span data-control="field" data-field="Freight">[Freight]</span></div><div data-container="row"><span data-control="label" data-field="ShipName">ShipName</span><span data-control="field" data-field="ShipName">[ShipName]</span></div><div data-container="row"><span data-control="label" data-field="ShipAddress">ShipAddress</span><span data-control="field" data-field="ShipAddress">[ShipAddress]</span></div><div data-container="row"><span data-control="label" data-field="ShipCity">ShipCity</span><span data-control="field" data-field="ShipCity">[ShipCity]</span></div><div data-container="row"><span data-control="label" data-field="ShipRegion">ShipRegion</span><span data-control="field" data-field="ShipRegion">[ShipRegion]</span></div><div data-container="row"><span data-control="label" data-field="ShipPostalCode">ShipPostalCode</span><span data-control="field" data-field="ShipPostalCode">[ShipPostalCode]</span></div><div data-container="row"><span data-control="label" data-field="ShipCountry">ShipCountry</span><span data-control="field" data-field="ShipCountry">[ShipCountry]</span></div></div>

Each category is converted to a div element with attribute data-container set to “collapsible”. A header bar will be rendered, and a border at the bottom of the container. The value of attribute “data-header-text” will be rendered as the text in the header bar. The “data-wrap” attribute is set to “false” in order to allow the field label and value to render in two columns for sufficiently wide screens. Collapsible containers will take the full width if they are the only container in that row. Otherwise, a border and drop shadow will be rendered on the left and right sides. Collapsible containers are an easy way to group fields in an attractive way.

Inside the category, several data containers of type “row” are added. These containers take the full width of the outer container, and will render a border above in order to delineate rows.

Inside each row container, there are various span elements marked with different data-control attributes.

The first data-control element is marked as “description”, and contains the category description. This text will be rendered smaller and with a lighter color.

The next data-control element is marked as “label”, and has a data-field attribute with value defined as the name of a data field in the view. The text of the element will be replaced by the label defined for that data field. When the form is in edit mode, the color of the text will be grey, and clicking on this element will shift focus to the nearest field control with matching data-field.

The other data-control element used in this template is “field”. The content of this element will be replaced by the value of the field matched by the name specified in the data-field attribute. The text wrapped in square brackets provide for easy debugging if the field is not matched to a data field in the view. The text will be rendered as grey when the form is in read-only mode. When the form is switched to edit mode, the color will change to black and the user will be able to click on the element to start editing the field value.

The default Orders editForm1 template in edit mode.

Note that there is no limit to the number of times a data field can be used for a label or field control. The client library will automatically synchronize the values of these fields after a user makes changes to the field.

There are various other utility containers that offer different capabilities for laying out your fields.

Tabs

Tabs are a common user interface element used to group fields. See an example below.

Two tabs rendered in editForm1 view of Orders page.

Tabs can be created by defining a “tabset” container that contains a set of tabs. Within this container, several “tab” containers can be defined, each with a “data-tab-text” value that defines the label displayed on the tab. The template used to create the example can be seen below.

<div data-container="tabset"><div data-container="tab"data-tab-text="Order Info"><div data-container="collapsible" data-header-text="Order Info"><div data-container="row"><span data-control="label" data-field="CustomerID">CustomerID</span><span data-control="field" data-field="CustomerID">[CustomerID]</span></div><div data-container="row"><span data-control="label" data-field="EmployeeID">EmployeeID</span><span data-control="field" data-field="EmployeeID">[EmployeeID]</span></div><div data-container="row"><span data-control="label" data-field="OrderDate">OrderDate</span><span data-control="field" data-field="OrderDate">[OrderDate]</span></div><div data-container="row"><span data-control="label" data-field="RequiredDate">RequiredDate</span><span data-control="field" data-field="RequiredDate">[RequiredDate]</span></div><div data-container="row"><span data-control="label" data-field="ShippedDate">ShippedDate</span><span data-control="field" data-field="ShippedDate">[ShippedDate]</span></div><div data-container="row"><span data-control="label" data-field="ShipVia">ShipVia</span><span data-control="field" data-field="ShipVia">[ShipVia]</span></div><div data-container="row"><span data-control="label" data-field="Freight">Freight</span><span data-control="field" data-field="Freight">[Freight]</span></div></div></div><div data-container="tab"data-tab-text="Shipping Info"><div data-container="collapsible" data-header-text="Shipping Info"><div data-container="row"><span data-control="label" data-field="ShipName">ShipName</span><span data-control="field" data-field="ShipName">[ShipName]</span></div><div data-container="row"><span data-control="label" data-field="ShipAddress">ShipAddress</span><span data-control="field" data-field="ShipAddress">[ShipAddress]</span></div><div data-container="row"><span data-control="label" data-field="ShipCity">ShipCity</span><span data-control="field" data-field="ShipCity">[ShipCity]</span></div><div data-container="row"><span data-control="label" data-field="ShipRegion">ShipRegion</span><span data-control="field" data-field="ShipRegion">[ShipRegion]</span></div><div data-container="row"><span data-control="label" data-field="ShipPostalCode">ShipPostalCode</span><span data-control="field" data-field="ShipPostalCode">[ShipPostalCode]</span></div><div data-container="row"><span data-control="label" data-field="ShipCountry">ShipCountry</span><span data-control="field" data-field="ShipCountry">[ShipCountry]</span></div></div></div></div>

This template can be used by creating a file at “~/Views/Orders.editForm1.html” and replacing the contents with the above HTML template.

Columns

Data fields can be placed into multiple columns using the data-container=“column” attribute.

Orders editForm1 view rendered in multiple columns.

Each column container must have a width specified. See example of template below:

<div data-container="tabset"><div data-container="tab" data-tab-text="Order Info"><div data-container="collapsible" data-header-text="Order"><div data-container="column"style="width: 50%"><div data-container="row"><span data-control="label" data-field="CustomerID">CustomerID</span><span data-control="field" data-field="CustomerID">[CustomerID]</span></div><div data-container="row"><span data-control="label" data-field="EmployeeID">EmployeeID</span><span data-control="field" data-field="EmployeeID">[EmployeeID]</span></div><div data-container="row"><span data-control="label" data-field="OrderDate">OrderDate</span><span data-control="field" data-field="OrderDate">[OrderDate]</span></div></div><div data-container="column"style="width: 49%"><div data-container="row" data-wrap="false"><span data-control="label" data-field="RequiredDate">RequiredDate</span><span data-control="field" data-field="RequiredDate">[RequiredDate]</span></div><div data-container="row"><span data-control="label" data-field="ShippedDate">ShippedDate</span><span data-control="field" data-field="ShippedDate">[ShippedDate]</span></div><div data-container="row"><span data-control="label" data-field="Freight">Freight</span><span data-control="field" data-field="Freight">[Freight]</span></div></div></div></div><div data-container="tab" data-tab-text="Shipping Info"><div data-container="row"><span data-control="label" data-field="ShipVia">ShipVia</span><span data-control="field" data-field="ShipVia">[ShipVia]</span></div><div data-container="row"><span data-control="label" data-field="ShipName">ShipName</span><span data-control="field" data-field="ShipName">[ShipName]</span></div><div data-container="row"><span data-control="label" data-field="ShipAddress">ShipAddress</span><span data-control="field" data-field="ShipAddress">[ShipAddress]</span></div><div data-container="row"><span data-control="label" data-field="ShipCity">ShipCity</span><span data-control="field" data-field="ShipCity">[ShipCity]</span></div><div data-container="row"><span data-control="label" data-field="ShipRegion">ShipRegion</span><span data-control="field" data-field="ShipRegion">[ShipRegion]</span></div><div data-container="row"><span data-control="label" data-field="ShipPostalCode">ShipPostalCode</span><span data-control="field" data-field="ShipPostalCode">[ShipPostalCode]</span></div><div data-container="row"><span data-control="label" data-field="ShipCountry">ShipCountry</span><span data-control="field" data-field="ShipCountry">[ShipCountry]</span></div></div></div>

Custom Content

One of the main reasons to define a custom template for your view would be to place custom content. The example below places several headers, images, and glyphicons among data field rows.

Orders editForm1 view with custom content, including headers, glyphicons, and images injected into the form.

Containers with a type of “content” allow placing any content into them, without any special effects being added by the client library. Styles are applied on the proper elements in order to ensure the correct positioning of form elements.

<div data-container="content" data-wrap="true"><div data-container="column" style="width: 50%"><div data-container="content"><h2 style="padding-left: 12px"><span class="glyphicon glyphicon-cog"></span> General Information</h2></div><div data-container="row"><span data-control="label" data-field="CustomerID">CustomerID</span><span data-control="field" data-field="CustomerID">[CustomerID]</span></div><div data-container="row"><span data-control="label" data-field="EmployeeID">EmployeeID</span><span data-control="field" data-field="EmployeeID">[EmployeeID]</span></div><div data-container="row"><span data-control="label" data-field="OrderDate">OrderDate</span><span data-control="field" data-field="OrderDate">[OrderDate]</span></div></div><div data-container="column" style="width: 49%"><div data-container="content"><h2 style="padding-left: 12px"><span class="glyphicon glyphicon-time"></span> Date Information</h2></div><div data-container="row" data-wrap="false"><span data-control="label" data-field="RequiredDate">RequiredDate</span><span data-control="field" data-field="RequiredDate">[RequiredDate]</span></div><div data-container="row"><span data-control="label" data-field="ShippedDate">ShippedDate</span><span data-control="field" data-field="ShippedDate">[ShippedDate]</span></div><div data-container="row"><span data-control="label" data-field="Freight">Freight</span><span data-control="field" data-field="Freight">[Freight]</span></div></div></div><div data-container="content"style="padding: 0 1em 0.5em; text-align: center; height: 100px;"><img src="/touch/logo-color.png" style="vertical-align: bottom; padding-right: 6px" /><h1>These are my shipping fields.</h1></div><div data-container="content" data-wrap="false"><div data-container="row"><span data-control="label" data-field="ShipVia">ShipVia</span><span data-control="field" data-field="ShipVia">[ShipVia]</span></div><div data-container="row"><span data-control="label" data-field="ShipName">ShipName</span><span data-control="field" data-field="ShipName">[ShipName]</span></div><div data-container="row"><span data-control="label" data-field="ShipAddress">ShipAddress</span><span data-control="field" data-field="ShipAddress">[ShipAddress]</span></div><div data-container="row"><span data-control="label" data-field="ShipCity">ShipCity</span><span data-control="field" data-field="ShipCity">[ShipCity]</span></div><div data-container="row"><span data-control="label" data-field="ShipRegion">ShipRegion</span><span data-control="field" data-field="ShipRegion">[ShipRegion]</span></div><div data-container="row"><span data-control="label" data-field="ShipPostalCode">ShipPostalCode</span><span data-control="field" data-field="ShipPostalCode">[ShipPostalCode]</span></div><div data-container="row"><span data-control="label" data-field="ShipCountry">ShipCountry</span><span data-control="field" data-field="ShipCountry">[ShipCountry]</span></div></div>

Actions

Form templates also allow positioning actions defined in the controller onto the form.

Orders editForm1 view with multiple actions positioned on the form.

Actions are defined in the HTML template by placing an element with attribute data-control of value “action”. Then, add an attribute “data-action” with value of “[Action Group ID]/[Action ID]”. The text of the element will be replaced by the action label.

<div data-container="content" data-wrap="true"><div data-container="column" style="width: 50%"><div data-container="content"><h2 style="padding-left: 12px"><span class="glyphicon glyphicon-cog"></span> General Information</h2></div><div data-container="row"><span data-control="label" data-field="CustomerID">CustomerID</span><span data-control="field" data-field="CustomerID">[CustomerID]</span></div><div data-container="row"><span data-control="label" data-field="EmployeeID">EmployeeID</span><span data-control="field" data-field="EmployeeID">[EmployeeID]</span></div><div data-container="row"><span data-control="label" data-field="OrderDate">OrderDate</span><span data-control="field" data-field="OrderDate">[OrderDate]</span></div></div><div data-container="column" style="width: 49%"><div data-container="content"><h2 style="padding-left: 12px"><span class="glyphicon glyphicon-time"></span> Date Information</h2></div><div data-container="row" data-wrap="false"><span data-control="label" data-field="RequiredDate">RequiredDate</span><span data-control="field" data-field="RequiredDate">[RequiredDate]</span></div><div data-container="row"><span data-control="label" data-field="ShippedDate">ShippedDate</span><span data-control="field" data-field="ShippedDate">[ShippedDate]</span></div><div data-container="row"><span data-control="label" data-field="Freight">Freight</span><span data-control="field" data-field="Freight">[Freight]</span></div></div></div><div data-container="content" style="padding: 0 1em 0.5em; height: 40px; text-align: center;"><h4 style="padding-bottom: 6px">Create a report of this record:</h4><span data-control="action"data-action="ag7/a1"style="width: 25%; float: left">PDF</span><span data-control="action" data-action="ag7/a2" style="width: 25%; float: left">Image</span><span data-control="action" data-action="ag7/a3" style="width: 25%; float: left">Excel</span><span data-control="action" data-action="ag7/a4" style="width: 25%; float: left">Word</span></div><div data-container="content" data-wrap="false"><div data-container="row"><span data-control="label" data-field="ShipVia">ShipVia</span><span data-control="field" data-field="ShipVia">[ShipVia]</span></div><div data-container="row"><span data-control="label" data-field="ShipName">ShipName</span><span data-control="field" data-field="ShipName">[ShipName]</span></div><div data-container="row"><span data-control="label" data-field="ShipAddress">ShipAddress</span><span data-control="field" data-field="ShipAddress">[ShipAddress]</span></div><div data-container="row"><span data-control="label" data-field="ShipCity">ShipCity</span><span data-control="field" data-field="ShipCity">[ShipCity]</span></div><div data-container="row"><span data-control="label" data-field="ShipRegion">ShipRegion</span><span data-control="field" data-field="ShipRegion">[ShipRegion]</span></div><div data-container="row"><span data-control="label" data-field="ShipPostalCode">ShipPostalCode</span><span data-control="field" data-field="ShipPostalCode">[ShipPostalCode]</span></div><div data-container="row"><span data-control="label" data-field="ShipCountry">ShipCountry</span><span data-control="field" data-field="ShipCountry">[ShipCountry]</span></div></div>

Note that the action will always be visible in the form. If the action is not configured to be usable in the current form mode, it will render as greyed out. For example, see the screenshot below to see the actions greyed out when the user presses “Edit”.

Custom positioned actions in the form template will be greyed out when not applicable.

Data View Fields

One powerful capability offered by form templates is the positioning of data view fields. The example below places a list of order details associated with the current order.

Orders editForm1 view with a custom template that positions a list of order details on the right side.

For the example below, make sure to add a new field to the Orders controller:

PropertyValue
Field NameOrderDetails
TypeDataView
Data View ControllerOrderDetails
Data Viewgrid1
Filter Field #1OrderID

Save the new field. Then, drag the new field onto editForm1 of Orders controller to create a data field.

The template for the example can be seen below. The data view field is placed in the template as a data-control with value “dataview”.

<div data-container="column" style="width: 50%"><div data-container="collapsible" data-header-text="Order"><div data-container="row"><span data-control="label" data-field="CustomerID">CustomerID</span><span data-control="field" data-field="CustomerID">[CustomerID]</span></div><div data-container="row"><span data-control="label" data-field="EmployeeID">EmployeeID</span><span data-control="field" data-field="EmployeeID">[EmployeeID]</span></div><div data-container="row"><span data-control="label" data-field="OrderDate">OrderDate</span><span data-control="field" data-field="OrderDate">[OrderDate]</span></div><div data-container="row"><span data-control="label" data-field="RequiredDate">RequiredDate</span><span data-control="field" data-field="RequiredDate">[RequiredDate]</span></div><div data-container="row"><span data-control="label" data-field="ShippedDate">ShippedDate</span><span data-control="field" data-field="ShippedDate">[ShippedDate]</span></div><div data-container="row"><span data-control="label" data-field="Freight">Freight</span><span data-control="field" data-field="Freight">[Freight]</span></div></div></div><div data-container="column" style="width: 49%"><div style="padding-left: 1em"><div data-control="dataview"data-field="OrderDetails">[OrderDetails]</div></div></div><div data-container="content" data-wrap="false"><div data-container="collapsible" data-header-text="More Info"><div data-container="row"><span data-control="label" data-field="ShipVia">ShipVia</span><span data-control="field" data-field="ShipVia">[ShipVia]</span></div><div data-container="row"><span data-control="label" data-field="ShipName">ShipName</span><span data-control="field" data-field="ShipName">[ShipName]</span></div><div data-container="row"><span data-control="label" data-field="ShipAddress">ShipAddress</span><span data-control="field" data-field="ShipAddress">[ShipAddress]</span></div><div data-container="row"><span data-control="label" data-field="ShipCity">ShipCity</span><span data-control="field" data-field="ShipCity">[ShipCity]</span></div><div data-container="row"><span data-control="label" data-field="ShipRegion">ShipRegion</span><span data-control="field" data-field="ShipRegion">[ShipRegion]</span></div><div data-container="row"><span data-control="label" data-field="ShipPostalCode">ShipPostalCode</span><span data-control="field" data-field="ShipPostalCode">[ShipPostalCode]</span></div><div data-container="row"><span data-control="label" data-field="ShipCountry">ShipCountry</span><span data-control="field" data-field="ShipCountry">[ShipCountry]</span></div></div></div>

Batch Edit, Surveys, Universal Input, Date Processing.

$
0
0

Please take a look at the Roadmap for 2016/ 2017. It covers the next six months of the development cycle.

Numerous new features and bug fixes are included in the release 8.5.10.0.

Batch Edit

This release re-introduces Batch Edit capability in both Desktop UI and Touch UI applications. If multiple selection is enabled and two or more rows are selected then Batch Edit command becomes availabe in the context menu of data rows.

image

Select the menu option and a standard form will display a list of fields.

image

Specify the field values and choose Update Selection to update the selected data rows. A similar dialog is displayed in Desktop UI.

For the feature to work, you must enable Multi-Selection. Also specify an action with the command name set to “BatchEdit” in the group with the “Row” context. If there is no argument then the “grid1” will become the source of fields. If  you have a form with a large number of fields then specify the form view ID in the action argument. For example, try editForm1.

You can also enable Batch Edit everywhere if you set the corresponding option in the Grid Properties of Features section in your project settings. Make sure to refresh the project and the Batch Edit action will be added to all data controllers.

Surveys

The dynamically created Batch Edit form is implemented as a data controller produced on demand with the help of the new technology called Survey Controller.  We will post a tutorial explaining how to work with the survery controllers. See the rodmap for more details.

In the future releases, we will utilize survey controllers to re-implement several features in the Touch UI:

  • Advanced Search
  • Field-Level Search
  • Import
  • Standard Calendar Event Dialog

Survey controllers can be used as replacements for “confirmation” data controllers. Here is an example of a confirmation survey controller that allows selecting Customer, Order, and Order Detail.

image

All questions asked in the survey are accessible to the server-side business rules with the “Parameters_” prefix.

This is the defintion of the controller stored in ~/scripts/surveys/ThreeLevelMD.js file:

image

The survery will be loaded and displayed for any action if you specify the following in the Confimation property of the action.

_survery=ThreeLevelMD

 

You will be suprised to learn that the new “survey” controller is essentially a repackaged version of XML data controllers. The difference is only in the language used to define it.

Code On Time v9 will introduce the visual designer that will enable drag & drop development of traditional and “survery” data controllers.

The roadmap provides some additonal insights into our wide-ranging plans for the surveys.

Universal Input

Countless enhanements are made to Touch UI.  Continue reading to learn more about individual capabilities and bug fixes.

We would like to highlight the ability to create new items directly from with the list inputs with the style of items set as List Box, Radio Button List, and Check Box List. The option is shown as the last item of Category Name in the screenshot.

image

Note that the lookups with Drop Down List style have a distinctive icon as shown in Discontinued field. Users can select items with Up and Down keys, via auto-complete, or via direct selection of options from the menu.

All inputs now provide excellent support for keyboard data entry and navigation.

Make sure to clear New Data View property of lookup fields with these presentation styles if you do not want your users to create new items.

Retired Project Types

We have retired Azure Factory and Mobile Factory projects. Microsoft considers Cloud Service apps to be in the legacy category. We recommend creating standard Web App Factory projects instead.

Mobile Factory projects are effectively Web Site Factory projects minus the ability to display Desktop UI. We have removed this project type from the menu of new projects.

Any existing projects of the retired types will still work. We recommend considering a conversion to the remaining project types.

Date Time Processing

We have completely re-designed handling of dates to eliminate any issued with the time zones.

Features and Enhancements

The list of features and enhancements introduced in relese 8.5.10.0 is presented below.

  • Visible When for data fields and categories is now fully supported in Touch UI. We have a brand new implementation designed specifically for the Universal Input controls.
  • Read Only When for data fields is now fully supported in Touch UI.
  • BLOB utility fields are correctly captured in Touch UI.
  • GEO utility fields are correctly captured in Touch UI.
  • Collapsible categories are now collapsing in Touch UI in response to user actions and when configured in Project Designer.
  • Touch UI now supports Causes Calculate with Universal Input.
  • Touch UI now supports cascading lookups with Universal Input.
  • JavaScript business rules do not trigger recursive Calculate in Touch UI.
  • JavaScript business rules of confirmation controllers can refernce the current row data fields as $current.FieldName.
  • Tab selection remains when user switches between read and write mode in a form in Touch UI.
  • Llong text fields and many-to-many fields have a 40 column minimum width in grid in Touch UI.
  • Ttooltip remains next to the input field when the page has been scrolled to set the focus in Touch UI.
    Touch UI correctly handles "_blank:" prefix in Hyperlink Format String property of data fields.
  • Method RefreshChildren works correctly in Touch UI and modal forms of Desktop UI.
  • Sidebar calendar remains inactive until it becomes visible.
  • Multi-selection mode does not reset selected row when activated more than once.
  • Fixed JavaScript business rule compilation issues related to field references.
  • Automatic configuration of "Copy" property now ensures fields are copied, even when lookup contains self-referring FK.
  • Model Builder no longer creates lookups if the field is borrowed from a different table.
  • Capture of exception on Windows 10 Build 1607.
  • Removed dependency on MSXML6.dll fromt he app generator.
  • User theme is now stored in cookie.
  • Touch UI themes are now served individually based on browser cookie.
  • ApplicationServices.UserTheme property added.
  • Web App Factory contains proper DLLs for ReportViewer.
  • DataView fields are hidden in grid1 and createForm1 at rutnime.
  • Added 'calendar-drag-disabled' tag to disable dragging in Calendar view.
  • Added "Normalize Model Names" checkbox to allow disabling removal of underscores and other non-word characters.
  • Fixed issue with "Edit Rule" in Visual Studio not looking in correct folder.
  • Touch UI  enables Google Maps for localhost only. Any production deployments now require a Google API key due to the policy changes by Google Inc.

Converting Mobile and Azure Factory Projects

$
0
0

As of Release 8.5.10.0, Mobile Factory and Azure Factory project types have been retired.

Both Web Site and Web App Factory projects offer the ability to use Touch UI as well as deploy to Azure. In addition, Azure Factory was built around the “Cloud Service” Azure resource type, which has been marked as “Classic” at the time of this writing.

It will not be possible to create new projects of these types. The app generator will continue to provide support for existing projects created with these project types. However, it is strongly recommended to migrate away from these project types in order to gain access to new features in future releases.

Migrating a Mobile Factory Project to Web Site Factory

Mobile Factory projects were originally based on Web Site Factory, with “Desktop” user interface disabled. Therefore, it is quite easy to migrate a project to Web Site Factory.

Open the app generator. In your list of projects, click on the project name, and press Open.

Opening the project folder for a mobile factory project.

This will open the project folder in File Explorer. Click on the “Up” arrow on the navigation bar to move to the parent directory.

Moving to the parent directory.

Right-click on the project and press “Cut”, or check the box next to the project folder and press “Cut” button on the ribbon.

Cutting the project folder.

Click on the “Up” arrow to navigate to the parent directory “Projects”. If a “Web Site Factory” folder does not exist, create the folder now.

Right-click on the “Web Site Factory” folder, and press Paste, or click once on the folder and press the “Paste” button on the ribbon.

Pasting the project folder into Web Site Factory folder.

Switch back to the list of projects in the app generator. Press “F5” to refresh the page. Notice that the project is now of type “Web Site Factory”.

The Mobile Factory has been converted to a Web Site Factory project.

Proceed to generate the application.

Converting Azure Factory to Web Site Factory

Azure Factory projects are more complicated than Mobile Factory projects. In order to convert these types of projects, multiple files and folders will need to be moved. Follow the table below in order to properly convert your project to Web Site Factory:

SourceDestination
~/Azure Factory/[Project]/Application.Log.xml~/Web Site Factory/[Project]/Application.Log.xml
~/Azure Factory/[Project]/Controllers.Log.xml~/Web Site Factory/[Project]/Controllers.Log.xml
~/Azure Factory/[Project]/DataAquarium.Project.xml~/Web Site Factory/[Project]/DataAquarium.Project.xml
~/Azure Factory/[Project]/DataAquarium.Version.xml~/Web Site Factory/[Project]/DataAquarium.Version.xml
~/Azure Factory/[Project]/DataAquarium.Log.xml~/Web Site Factory/[Project]/DataAquarium.Log.xml
~/Azure Factory/[Project]/[Namespace]/Controllers~/Web Site Factory/[Project]/WebSite/Controllers
~/Azure Factory/[Project]/[Namespace]/Views~/Web Site Factory/[Project]/WebSite/Views
~/Azure Factory/[Project]/[Namespace]/Rules~/Web Site Factory/[Project]/WebSite/App_Code/Rules
~/Azure Factory/[Project]/WebRole1/Controls~/Web Site Factory/[Project]/WebSite/Controls
~/Azure Factory/[Project]/WebRole1/Pages~/Web Site Factory/[Project]/WebSite/Pages

In addition, any other custom files such as classes and stylesheets will need to be moved to the corresponding location in the destination folder. It may be necessary to link these files to the solution after generation.

Once all files have been moved, switch back to the app generator and press F5 to refresh the list of projects. Click on the project name and press “Refresh”. Proceed to generate the application.

Deploying Web Site Factory Project to Azure

$
0
0

Microsoft Azure is composed of a collection of integrated cloud services. It enables easy storage of databases and deployment of web applications to the Internet, without having to deal with the hassle of infrastructure maintenance. When it comes time to offer your application to a larger number of users, your services can be scaled easily to fit your needs. Azure offers pay-as-you go services to scale up or down to match demand.

Let’s deploy a sample Northwind Web Site Factory project to Azure using Visual Studio 2015.

Start the app generator, click on the project name, and press “Develop” to open the project in Visual Studio.

Opening Northwind project in Visual Studio.

In the Solution Explorer (F4), right-click on the “WebSite” node and press “Publish Web App”.

Publishing a web app from Visual Studio.

In the list of publish targets, select “Microsoft Azure App Service”.

Publishing to Microsoft Azure App Service.

If you have not logged into your Microsoft account, enter your credentials in the login window that appears and proceed to log in.

In the App Service window, press “New..” to create a new resource group for your application.

Creating a new resource group for Azure.

Assign a Web App Name to this deployment. Next to App Service Plan, press “New…”.

Specifying a web app name and app service plan for the azure deployment.

Select an app service plan suitable for your deployment. Every tier provides different compute capabilities and features at different price points.

Please note that a dedicated (non-shared) app service plan must be selected in order for reports to be generated. The smallest available size that enables the use of reporting is “Basic – 1” (B1).

Configuring an app service plan for the web app.

Press “OK” to save the app service plan. Then, click “Create” to create the required Azure resources.

When the process is complete, the Publish screen will open with pre-filled values. Leave the values as default and press “Next” to configure settings.

The Publish configuration has been automatically populated.

Check the box next to “Remove additional files at destination”. This will ensure that the deployment directory will match the local directory.

Enabling removal of additional files at the destination.

Press “Publish” to deploy your application to the cloud. When publish is complete, the application will open in your default web browser.

Including Report Viewer DLLs

If Reporting is enabled in the web application, a server error will be displayed. ReportViewer DLLs must be included in the published app.

Open File Explorer by pressing Win+E, and navigate to

C:\Windows\assembly\GAC_MSIL\Microsoft.ReportViewer.WebForms

Open the folder for the version of Report Viewer required by your application. Applications using “.NET 4.6” require version 12.

Right-click on the DLL file and press “Copy”.

Creating a copy of the ReportViewer DLL.

In Visual Studio’sSolution Explorer, right-click on “WebSite” project node and press “Add | New Folder”.

Adding a new folder to the project.

Assign the name “bin” to the folder. Right-click on the new folder and press “Paste”.

Pasting Report Viewer DLL to the bin folder.

The DLL will copy into the “bin” folder.

Copy two more DLLs, found at these locations:

  1. C:\Windows\assembly\GAC_MSIL\Microsoft.ReportViewer.Common
  2. C:\Windows\assembly\GAC_MSIL\Microsoft.ReportViewer.ProcessingObjectModel

Next, re-publish the app by right-clicking on the “WebSite” node and pressing “Publish Web App”.

Publishing the web app with report viewer DLLs.a

Then, press “Publish” to initiate the process. Once complete, the app will open in your web browser and open the home page of your application running in the cloud.

“Auto Complete Anywhere” in Lookups

$
0
0

Touch UI applications created with Code On Time offer powerful lookups that allow the user to activate the grid view of the lookup controller, use auto complete to find a value, or select the value from a list.

By default, auto complete will search for values that begin with the typed-in query. For example, the picture below shows that typing in “es” in the Supplier Company Name lookup will result in finding the single value “Escargots Nouveaux”.

Touch UI lookups will auto complete for values that start with the search query.

Lookups also support the ability to match values anywhere in the value. In order to enable this functionality, the data field must have Search Options configured with the tag “$autocompleteanywhere”.

Start the Project Designer. In the Project Explorer, switch to the Controllers tab, and expand to “Products / Views / editForm1 / c1 – Products”. Double-click on “SupplierID” data field.

Selecting the SupplierID data field of Products controller.

Make the following changes:

PropertyValue
Search Options$autocompleteanywhere

Press OK to save the data field, and press Browse to regenerate and open the web app in the default browser.

Navigate to the Products page, edit a product, and start typing in the Supplier Company Name lookup. Notice that the typed text will now be matched anywhere in the lookup values.

The Supplier Company Name lookup now matches the auto complete string anywhere in the lookup value.

Disabling “Create New” in Lookups

$
0
0

Lookups in applications created with Code On Time offer the ability to create new lookup items on the spot. This allows users to instantly add missing lookup options inside the same page.

The “Create New” action is supported in Lookup, Auto Complete, Drop Down List, List Box, and Check Box List lookup styles.

The "Create New" action is available on all types of lookups.

Pressing the “Create New” action will open the create form for the lookup controller. If a value has been typed into an Auto Complete, Drop Down List, or Lookup input, then this value will populate the relevant alias field in the create form automatically.

Pressing Create New while a value is present in the input will populate that value in the create form of the lookup controller.

The “Create New” functionality can be disabled by clearing the “New Data View” property for the field.

Start the Project Designer, switch to the Controllers tab, and double-click the “Orders / Fields / CustomerID” node.

Editing the CustomerID field of Orders controller.

Clear the New Data View property by clicking the eraser icon next to the value.

PropertyValue
New Data ViewN/A

Press OK to save the field. Repeat the above process for fields “EmployeeID” and “ShipVia”.

When complete, press Browse on the toolbar. Once generation is complete and the app opens in your default browser, navigate to the Orders page. Select and edit an order. Notice that all “Create New” actions have been removed.

The "Create New" action has been removed from all lookups.

Data View Fields

$
0
0

Every database entity contains a list of properties, stored as columns in the table. These columns are represented by fields in the model and controller. When an entity requires a repeated, varying amount of related information, these properties are externalized to a separate table. This detail entity must be defined as a model in the project, and a data view can be placed under the master entity to display a list of these items.

Let’s take the Northwind sample database as an example. Every order contains a discrete list of properties that are represented as columns in the database. Any number of details for the order can be added. Each order detail contains an OrderID foreign key column, which refers to OrderID primary key of the order record.

Orders and Order Details table and relationship.

In the default app created by Code On Time app generator, a field is created for every column present in the database entity.

Orders form with no child info.

The natural next step is to display a list of details in the order form.

Make sure the sample project contains models for both Orders and Order Details database entities. Start the Project Designer. In the Project Explorer, switch to the Controllers tab. Right-click on the “Orders / Fields” node, and press “New Field”.

Adding a new field to Orders controller.

Enter the following properties:

PropertyValue
NameDetails
TypeDataView
Data View ControllerOrderDetails
Data Viewgrid1
Filter Field #1OrderID

Press OK to save the new field. Next, drag the new Details field onto “Orders / Views / editForm1” to create a data field in the order form.

Dropping Details field onto 'editForm1' view of Orders controller.     Details data field has been created in 'editForm1' view of Orders controller.

On the toolbar, press Browse to generate the application. Navigate to the Orders page and select a record. Notice that a list of related details are displayed at the bottom of the form.

A list of order details is displayed in the order form.

This data view field be placed in any position on the form, or placed in a custom location using a form template.

Calculating Values with C#/Visual Basic Business Rules

$
0
0

It is a common requirement for forms of the application to feature a custom calculation or operation that must be triggered by the user pressing a button visible on the screen.

For example, let’s use the Orders page of the Northwind sample project. It may be useful to have an action that will mark the order as shipped by populating the Shipped Date field, and setting a default value for Freight if it has not been specified.

The orders form has a "Mark as Shipped" button.

The first step is to add an action to the form scope that the user will be able to press to trigger a business rule.

Start the Project Designer. In the Project Explorer, switch to the Controllers tab. Right-click on “Orders / Actions / ag2 (Form)”, and press New Action.

Adding a new action to the form of Orders controller.

Set the following properties:

PropertyValue
Command NameCustom
CommandArgumentMarkAsShipped
Header TextMark as Shipped
When Last Command NameEdit

Press OK to save the new action.

Next, let’s create a business rule that will perform the calculations. Right-click on “Orders / Business Rules” node, and press “New Business Rule”.

Adding a new business rule to Orders controller.

Specify the following values so that the business rule will be triggered by the action created above.

PropertyValue
TypeC# / Visual Basic
Command NameCustom
Command ArgumentMarkAsShipped
PhaseExecute

Press OK to save the business rule. On the toolbar, press Browse to regenerate the application and ensure that the rule file is created.

When generation is complete, press “Edit Rule” on the action bar. This will open the business rule in Visual Studio.

Replace the contents of the file with the following code.

C#:

using System;using System.Data;using MyCompany.Data;using MyCompany.Models;namespace MyCompany.Rules
{public partial class OrdersBusinessRules : 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 "MarkAsShipped"./// </summary>[Rule("r100")]public void r100Implementation(OrdersModel instance)
        {
            instance.ShippedDate = DateTime.Now;if (!instance.Freight.HasValue || instance.Freight == 0)
                instance.Freight = 13.5m;

            PreventDefault();
        }
    }
}

Visual Basic:

Imports MyCompany.DataNamespace MyCompany.RulesPartial Public Class OrdersBusinessRulesInherits 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 "MarkAsShipped".'''</summary><Rule("r113")>Public Sub r113Implementation(instance As OrdersModel)'This is the placeholder for method implementation.instance.ShippedDate = DateTime.NowIf Not instance.Freight.HasValue OrElse instance.Freight = 0 Theninstance.Freight = 13.5DEnd IfPreventDefault()End Sub
    End Class
End Namespace

The code will set the ShippedDate field to the current date and time. It will then check if Freight has a value, and if the value is equal to 0. If so, then the Freight will be set to the decimal number 13.5. Finally, PreventDefault() is called in order to prevent the form from navigating back to the grid.

Save the file, and refresh the web browser. Navigate to Orders page and edit a record. Notice that the “Mark as Shipped” action is now available. Pressing this action will now populate the Shipped Date with the current date and time. If the Freight field was empty, then it will be set to $13.50.

Pressing the "Mark as Shipped" button has set the value of both ShippedDate and Freight fields.


Wizards in Touch UI

$
0
0

Commonly, multiple screens are connected and the user is required to page through these forms in order to complete their task. This pattern of presentation is called the “Wizard”. Starting with release 8.5.11.0, it is possible to create wizards in Touch UI. The picture below shows an example of a Create Employee Wizard in the Northwind sample database.

Sample New Employee wizard.

Each step of the wizard contains one or more categories. If all categories belonging to a particular step are rendered invisible via the Visible When property, then that step will be hidden.

Let’s implement the wizard shown above.  Start the Project Designer. In the Project Explorer window, switch to Controllers tab. Double-click on “Employees / Views / createForm1 / c1 – New Employees” category.

Selecting the category 'c1' in createForm1 of Employees controller.

Make the following changes and press OK to save:

PropertyValue
Header TextGeneral Info
DescriptionEnter employee general information below.
WizardGeneral

Next, let’s create several new categories. Right-click on “Employees / Views / createForm1” and press “New Category”.

Creating a new category in createForm1 view of Employees controller.

The second category will display in a new column alongside the previous category in the first step of the wizard.

PropertyValue
Header TextContact Info
DescriptionEnter employee contact information below.
New ColumnYes
WizardGeneral

The next category will have the following configuration. Note the use of curly brackets wrapping field names. These will be replaced by the value of the field at runtime.

PropertyValue
Header TextAddress
DescriptionEnter the home address of {FirstName}{LastName} below.
WizardAddress

The last category representing the final wizard step is configured below. Notice that the Visible When property is configured to hide the category when the Title field is equal to the value “President”.

PropertyValue
Header TextEmployee Info
DescriptionEnter {TitleOfCourtesy} {LastName}'s employee information below.
WizardEmployee
Visible When
$row.Title != 'President'

Any categories that do not have a “Wizard” property assigned will be displayed on every step, either above or below the wizard content, depending on the position of the category relative to the first wizard category.

Rearrange the data fields as presented in the picture below using drag & drop.

The correct position of Employees data views for the Create Employee Wizard.

On the toolbar, press Browse to regenerate the app. Once generation is complete, navigate to the Employees page and create a new employee.

The correct position of Employees data views for the Create Employee Wizard.

Notice that a Status Bar has automatically been defined. The “Prev” and “Next” actions have been automatically injected into the form action group. Enter some values for the fields, including specifying “President” in the Title field.

Entering 'President' will hide the only category representing the 'Employee' wizard step, therefore hiding that step.

Notice that the “Employee” tab has been removed from the Status Bar. By pressing “Next”, the Address wizard step will be displayed. The field names surrounded by curly brackets have been replaced with the field values defined by the user.

The category description contains field values.

Note that when using custom form templates, wizards can be defined by encapsulating each step by an element with attribute “data-wizard-step”. The value of the attribute will be displayed in the status bar. See a simplified example below:

<div data-wizard-step="General"><div data-container="collapsible" data-header-text="General Info">...</div>...</div><div data-wizard-step="Address">...</div>

Smart Dates

$
0
0

At a glance, dates can be hard to comprehend without having to open a calendar. Starting with release 8.5.11.0, date values will be replaced with Smart Dates. These smart dates represent text labels that will replace the original date value and show simplified versions of the value that are significantly easier to read and understand.

Smart dates will follow this algorithm:

  1. If the date is in the current year,
    1. and the date is in future days,
      1. and the date is tomorrow, the word “Tomorrow” will be shown.
      2. and the date is occurring within the next 7 days, then the shortened day of the week will be displayed.
      3. and the date is occurring 7-14 days in the future, then the label will be “Next” plus the day of the week.
      4. Otherwise, month and date will be displayed.
    2. and the date is today,
      1. and the time is midnight, then the word “Today” will be displayed.
      2. and it was within the last hour, then the words “XX min ago” will be displayed.
      3. and it is happening within the hour, then the words “in XX min” will be displayed.
      4. Otherwise, the time will be displayed.
    3. and the date is in past days,
      1. and the date is yesterday, the word “Yesterday” will be shown.
      2. and the date occurred < 7 days ago, the label will be “Last” plus the day of the week.
      3. Otherwise, the month and date will be displayed.
  2. Otherwise, the full value is displayed.

When the time value is not midnight, then the time will be displayed after the date.

See an example in the following picture.

List of Orders with Smart Dates enabled.

These smart dates are much simpler to read and understand than the original values, displayed below.

List of orders with Smart Dates disabled.

Hovering over the smart date will display the original value, when needed.

Hovering over a Smart Date will show the original value.

The same smart dates are displayed in the form.

Smart Dates displayed in the form

When the user edits the field, the true value will be displayed.

Editing a value in the form, the original date will be displayed.

The user can choose to disable this feature from the Settings panel. Click on the three-bar “hamburger” menu in the top left corner of the web app.

Activating the hamburger menu.

Select the “Settings” option in the panel that appears.

Selecting the Settings panel from the menu panel.

From the list of settings, select “Smart Dates”. Select Yes or No, and confirm to refresh the page in order to enable or disable the feature.

Enabling or disabling Smart Dates from the Settings panel.

The default value for this user setting can be configured in the Touch UI section of the Features page of the Project Wizard.

Modifying the default value for Smart Dates in the Features page of the Project Wizard.

Data Field Search Options Index

$
0
0

The Search Options data field property restricts and reorders the search options available to the end user on the Advanced Search Bar.

Employees grid view with advanced search bar. Birth Date search options are visible.

The search options available are dependent on the field type.

Below is a table of all search options and their description.

Numeric Filters
Search OptionTextDescription
=EqualsThe search will find exact matches of the parameter
<>Does Not EqualThe search will exclude all exact matches of the parameter
<=Less ThanThe search will include all results that are less than the parameter
>=Greater ThanThe search will include all results that are greater than the parameter
$betweenBetweenThe search will include all results that are between two parameters
$inIncludesThe search will include all selected parameters (will open a modal window to select items)
$notinDoes Not IncludeThe search will exclude all selected parameters (will open a modal window to select items)
Text Filters
Search OptionText Description
=EqualsThe search will find exact matches of the parameter
<>Does Not EqualThe search will exclude all exact matches of the parameter
$beginswithBegins WithThe search will find all matches that begin with the parameter
$doesnotbeginwithDoes Not Begin WithThe search will exclude all matches that begin with the parameter
$containsContainsThe search will find all matches that contain the parameter
$doesnotcontainDoes Not ContainThe search will find all matches that do not contain the parameter
$endswithEnds WithThe search will find all matches that end with the parameter
$doesnotendwithDoes Not End WithThe search will exclude all matches that end with the parameter
$inIncludesThe search will include all selected parameters (will open a modal window to select items)
$notinDoes Not IncludeThe search will exclude all selected parameters (will open a modal window to select items)
Logical Filters
Search OptionText Description
$trueYesThe search will find all results that equal “True”.
$falseNoThe search will find all results that equal “False”.
Date Filters
Search OptionText Description
=EqualsThe search will find exact matches of the parameter
<>Does Not EqualThe search will exclude all exact matches of the parameter
<Less ThanThe search will include all results that are less than the parameter
>Greater ThanThe search will include all results that are greater than the parameter
$betweenBetweenThe search will include all results that are between two parameters
$inIncludesThe search will include all selected parameters (will open a modal window to select items)
$notinDoes Not IncludeThe search will exclude all selected parameters (will open a modal window to select items)
$tomorrowTomorrowThe search will find all results that match the day preceding the current date.
$todayTodayThe search will find all results from the current date.
$yesterdayYesterdayThe search will find all results that match the day after the current date.
$nextweekNext WeekThe search will find all results that match the week preceding the current week.
$thisweekThis WeekThe search will find all results from the current week.
$lastweekLast WeekThe search will find all results that match the week after the end of the current week.
$nextmonthNext MonthThe search will find all results that match the month preceding the current month.
$thismonthThis MonthThe search will find all results from the current month.
$lastmonthLastMonthThe search will find all results that match the month after the end of the current month.
$nextquarterNext QuarterThe search will find results that match the quarter after the current one.
$thisquarterThis QuarterThe search will find results that match the current quarter.
$lastquarterLast QuarterThe search will find results that match the quarter before the current one.
$nextyearNext YearThe search will find results that match the year after the end of the current one.
$thisyearThis YearThe search will find results in the current year.
$yeartodateYear To DateThe search will find results from the beginning of the current year up to the current date.
$lastyearLast YearThe search will find results that match the year before the beginning of the current one.
$PastPastThe search will find all results before the current date.
$FutureFutureThe search will find all results after the current date.
$quarter1All Dates In Period: Quarter 1The search will find all results in the first quarter.
$quarter2All Dates In Period: Quarter 2The search will find all results in the second quarter.
$quarter3All Dates In Period: Quarter 3The search will find all results in the third quarter.
$quarter4All Dates In Period: Quarter 4The search will find all results in the fourth quarter.
$month1All Dates In Period: JanuaryThe search will find all results in the month of January.
$month2All Dates In Period: FebruaryThe search will find all results in the month of February.
$month3All Dates In Period: MarchThe search will find all results in the month of March.
$month4All Dates In Period: AprilThe search will find all results in the month of April.
$month5All Dates In Period: MayThe search will find all results in the month of May.
$month6All Dates In Period: JuneThe search will find all results in the month of June.
$month7All Dates In Period: JulyThe search will find all results in the month of July.
$month8All Dates In Period: AugustThe search will find all results in the month of August.
$month9All Dates In Period: SeptemberThe search will find all results in the month of September.
$month10All Dates In Period: OctoberThe search will find all results in the month of October.
$month11All Dates In Period: NovemberThe search will find all results in the month of November.
$month12All Dates In Period: DecemberThe search will find all results in the month of December.

 

The “All Dates In Period” search options will include intervals from five years ago to one year ahead.

There are also several modifiers that can be used to change the behavior of the data field.

Search OptionDescription
$autocompleteanywhereAuto complete in fields can be configured to search anywhere in field values, instead of using “begins with” matching.
$disableautocompleteText search options will no longer offer auto complete capabilities.
$disablemultiplevaluesThe “Filter…” option under the column header will be removed – users will not be able to filter by multiple values.
$disablesamplesQuick filtering samples under the column header will be removed.
$quickfindWill exclusively filter fields tagged with “$quickfind” when using Quick Find.
$quickfinddisabledWill exclude fields tagged with “$quickfinddisabled” when using Quick Find.

Speeding Up Quick Find

$
0
0

The Quick Find feature is available by default in all data views of an application. This feature allows searching every field available in the grid all at once.

Quick Find can be triggered by pressing on the Search icon in the top right corner of the data view, or by typing when a full screen data view is in focus.

Activating the Quick Find by pressing the Search icon.

Type in a value and hit “Enter” key on the keyboard to begin the search.

Typing in a value to the Quick Find input box.

When the search is complete, the search query will be displayed in the view header and the results will be displayed in the grid.

When Quick Find is triggered, the query is displayed in the header and the results below.

Each word separated by a space will search for results containing both words. Words separated by commas will search for results containing either word. Results can be negated by adding a dash (-) before the word. Exact phrases can be wrapped in “double quotes”. The example below executes the following search:

“Camembert Pierrot”, tea –grandma

The search returns records that contain the phrase “Camembert Pierrot” exactly, or records that contain “tea” and do not contain “grandma”.

Two results are returned.

However, while using Quick Find is perfect for small to medium size tables or views with a small number of columns, it can cause a substantial performance hit when the grid contains many different columns, and there is a large number of records in the table. Each column must be searched for that particular combination of keywords. While it is still possible to use AdvancedSearch in order to query specific columns, it does not beat the convenience offered by Quick Find.

In order to avoid the performance hit caused by searching every column, it is possible to reduce the Quick Find search scope to an inclusive or exclusive set of fields in the grid.

Excluding Specific Fields Using “$quickfinddisabled”

The quickest way to add performance is to add the tag “$quickfinddisabled” to the Search Options property of the data field. This will exclude the column from the search.

Let’s remove the QuantityPerUnit data field from the Quick Find query of Products page in the sample Northwind project.

Start the Project Designer. Switch to the Project Explorer tab. Double-click on “Products / Views / grid1 / QuantityPerUnit” data field.

Editing the QuantityPerUnit data field of grid1 View of Products controller.

Make the following change:

PropertyValue
Search Options$quickfinddisabled

Press OK to save. On the toolbar, press Browse.

Navigate to the Products page and execute a Quick Find search. Notice that Quantity Per Unit will now be ignored when using Quick Find.

Quick Find will no longer use Quantity Per Unit field in the filter.

Including Specific Fields Using “$quickfind”

It is also possible to only include specific fields by using the “$quickfind” tag. Let’s reduce the Quick Find scope on Products page to only ProductName and CategoryName fields.

Switch back to the Project Designer. Make sure to clear any “$quickfinddisabled” tags, as these are exclusive.

Double-click on “Products / Views / grid1 / ProductName” data field node.

Editing ProductName data field in grid1 view of Products controller.

Make the following change:

PropertyValue
Search Options$quickfind

Press OK to save the data field.

The next data field to modify is CategoryName. However, this data field is being used as the Alias for CategoryID data field, and has not been added to grid1 view. We will need to add CategoryName data field to grid1 in order to modify the behavior. This data field will not be rendered twice.

Drag the field “Products / Fields / CategoryName” onto “Products / Views / grid1” view to instantiate a data field for CategoryName field.

Dragging CategoryName field onto grid1 view.  The CategoryName data field has been added to grid1.

Next, change the configuration for CategoryName data field.

PropertyValue
Search Options$quickfind

Press OK to save. On the toolbar, press Browse. Navigate to Products page and search for “tea”. Notice that Supplier Company Name is not searched - results do not include those with Supplier of “Grandma Kelly’s Homestead”.

The Quick Find query has excluded all fields that were not tagged with "$quickfind".

Show Action Buttons

$
0
0

Every form in web applications created with Code On Time display a row of buttons. The typical actions available in the “Form” scope include Edit, Delete, Close/Cancel, Save, and Save and New. In addition, actions that trigger custom calculations are often put in the “Form” scope. The default presentation mode for form actions is called “Auto”.

Auto

The “Auto” mode will present form buttons in the best location depending on the size of the screen. On medium size screens, the buttons will be aligned to the right side of a fixed bar at the bottom of the screen. This ensures that the buttons are in the same position every time a user opens the form, resulting in a smaller learning curve to the application.

On small screens, form action buttons are rendered in a fixed button bar at the bottom of the screen, aligned to the right.

Larger screens will result in the form buttons shifting to the center of the button bar, closer to the field values.

Large screens will render form actions aligned to the center of a fixed bar at the bottom of the screen.

If the screen is too small to display all form buttons, they will be automatically collapsed into a three-dot menu.

When action buttons do not fit in the available space, these actions will be folded under a three-dot menu.

If the screen is both narrow and short, the form buttons will be rendered at the bottom of the form. This will ensure that devices with small screens can maximize the amount of space used for display of field values.

Very small screens will render buttons at the bottom of the form.

None

It may be desirable to hide the form actions bar from the screen. Let’s remove the form buttons from the Orders screen of the sample Northwind project.

Start the Project Designer. In the Project Explorer, double-click on “Orders / container1 / view1 (Orders, grid1)” node.

Modifying view1 that shows Orders grid1 in Orders page.

Make the following change:

PropertyValue
Show Action ButtonsNone

Press OK to save, and press Browse on the toolbar to regenerate the app.

When the app comes up in the default browser, click on a record on Orders page to view the form. Notice that the form action buttons are no longer visible. The actions are still accessible in the top right corner of the screen.

The Orders form with form action buttons hidden.

The user can also access all actions by clicking on the three-dot menu in the top right corner to access the action panel.

The form action buttons are still available in the action sidebar.

Top

When Show Action Buttons is set to “Top”, the action buttons will be rendered above the form.

Action buttons are rendered at the top of the form.

Bottom

When Show Action Buttons is set to “Bottom”, the buttons will be rendered below the form.

Action buttons are rendered at the bottom of the form.

Top And Bottom

When Show Action Buttons is set to “Top and Bottom”, the buttons will be rendered both above and below the form. This can be helpful when the form is very long.

Action buttons are rendered at the top and bottom of the form.

Viewing all 336 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>