Workflow

Labels
AJAX(112) App Studio(7) Apple(1) Application Builder(245) Application Factory(207) ASP.NET(95) ASP.NET 3.5(45) ASP.NET Code Generator(72) ASP.NET Membership(28) Azure(18) Barcode(2) Barcodes(3) BLOB(18) Business Rules(1) Business Rules/Logic(140) BYOD(13) Caching(2) Calendar(5) Charts(29) Cloud(14) Cloud On Time(2) Cloud On Time for Windows 7(2) Code Generator(54) Collaboration(11) command line(1) Conflict Detection(1) Content Management System(12) COT Tools for Excel(26) CRUD(1) Custom Actions(1) Data Aquarium Framework(122) Data Sheet(9) Data Sources(22) Database Lookups(50) Deployment(22) Designer(177) Device(1) DotNetNuke(12) EASE(20) Email(6) Features(101) Firebird(1) Form Builder(14) Globalization and Localization(6) How To(1) Hypermedia(2) Inline Editing(1) Installation(5) JavaScript(20) Kiosk(1) Low Code(3) Mac(1) Many-To-Many(4) Maps(6) Master/Detail(36) Microservices(4) Mobile(63) Mode Builder(3) Model Builder(3) MySQL(10) Native Apps(5) News(18) OAuth(9) OAuth Scopes(1) OAuth2(13) Offline(20) Offline Apps(4) Offline Sync(5) Oracle(11) PKCE(2) Postgre SQL(1) PostgreSQL(2) PWA(2) QR codes(2) Rapid Application Development(5) Reading Pane(2) Release Notes(183) Reports(48) REST(29) RESTful(29) RESTful Workshop(15) RFID tags(1) SaaS(7) Security(81) SharePoint(12) SPA(6) SQL Anywhere(3) SQL Server(26) SSO(1) Stored Procedure(4) Teamwork(15) Tips and Tricks(87) Tools for Excel(2) Touch UI(93) Transactions(5) Tutorials(183) Universal Windows Platform(3) User Interface(338) Video Tutorial(37) Web 2.0(100) Web App Generator(101) Web Application Generator(607) Web Form Builder(40) Web.Config(9) Workflow(28)
Archive
Blog
Workflow
Saturday, April 21, 2012PrintSubscribe
Complex Action Confirmations

Application business requirements may specify actions demanding user-defined values. Field values of a selected data record are not sufficient to complete such actions.

Consider the example of implementing a custom business logic with “SQL” action. The example explains how to create a Standard Discount action that can be executed on any order in the Northwind sample application. The action will increment the discount of line items of a selected order by 1%.

The screen shot shows the application in action.

A custom action in the group with 'Grid' scope in a web app created with Code On Time application generator

The properties of the action are defined as follows.

Property Value
Command Name SQL
Header Text Standard Discount
Data
update "Order Details"
set Discount = 0
where 
    OrderID = @OrderID and Discount = 0.1
    
update "Order Details"
set Discount = cast(Discount as decimal(3,2)) + 0.01
where 
    OrderID = @OrderID and Discount < 0.1
Confirmation The discount will be increased by 1%.

If the action is selected then a simple confirmation is displayed.

A simple action confirmation in a web app created with Code On Time

A more flexible implementation of this action would allow a user to enter the exact discount that will apply to order line items. Let’s implement a confirmation that will allow capturing the discount and have it passed to the action implementation.

Start the application generator and click on the project name, click Design to activate the Project Designer. Select the Controllers tab in Designer and choose New | New  Controller option on the action bar.

Creating a new data controller in a Code On Time web application

Enter the following property values and click OK button.

Property Value
Name DiscountDialog

Right-click the DiscountDialog / Fields node on the Controllers tab in Project Explorer and select the New Field option.

Adding a new field to a data controller

Enter the following property values and click OK button to save the new field.

Property Value
Name Discount
Type Double
Code Default 0.01
Label Discount
Data Format String p

Our “confirmation” data controller is ready.

Select Orders / Actions / ag1 (Grid) / a100 – SQL | Standard Discount action node on the Controllers tab in Project Explorer.

Action with command name 'SQL' selected in Project Explorer

Change the action properties and click OK button.

Property New Value
Header Text Apply Discount
Data
update "Order Details"
set Discount = @Parameters_Discount
where 
    OrderID = @OrderID
Confirmation

_controller=DiscountDialog
_title=Apply Discount to Order Details
_width=500

Click Browse on the Project Designer toolbar to have the application generated. The home page of the app will open in the default web browser. Navigate to the Orders page and select Apply Discount option in the context menu of an order.

The modal form view will display. Enter a discount and click OK button to execute the action.

 A modal confirmation of 'SQL' action in a web app created with Code On Time web application generator

Any field values entered in the modal action parameter form are accessible in the “SQL” action script if your prefix the field name with “Parameters_”. Our script is referencing the entered Discount as @Parameters_Discout parameter.

If you are writing a custom business rules class or implementing shared business rules then you can reference the action parameter field by name “Parameters_Discount” as you would use any other field of a data controller.

The application client library displays a modal view if you define the confirmation property of the action as a collection of name/value arguments.

The library supports the following arguments. Only the “_controller” attribute is mandatory.

Argument Description
_controller The name of the data controller.
_view The ID of the view that must be activated in the modal popup. If left blank, then the first view of the data controller is activated. Optional.
_commandName The name of the start command. If left blank, then New command is the start command. Optional.
_commandArgument The optional argument of the start command.
_title The title of the action confirmation modal popup. If left blank, then the view label is displayed instead. Optional.
_width The width of the action confirmation modal popup. If left blank, then the default width of 800 is used. If the specified value exceeds 80% of the browser window width, then the popup width will be reduced to that value. Optional

The DiscountDialog controller defines a single field. There are no commands, views, or actions.

A data controller must define one or more fields to be used as an 'action confirmation'

The application framework treats data controllers that do not have a command as virtual controllers. Virtual Data Controllers are not based on a database table or view. The assumption is made that the controller has one data row only.

If the controller does not define its own views or actions then the application framework will complete the controller definition at runtime. This configuration is equivalent to the custom-defined controller shown in the picture.

A minimal 'action confirmation' data controller with custom views and actions

The virtual data controller used for action confirmation is not different from any other data controller based on a real database table or view. You can implement business rules and custom actions that may in turn require other virtual controllers for confirmation.

Developers can apply data controller virtualization techniques to customize the data controller actions at runtime according to the custom workflow requirements. For example, the action properties Data and Confirmation may be stored in a dedicated database table and applied to data controllers based on user identity.

Saturday, March 31, 2012PrintSubscribe
Dynamic Creation of Static Lookup Items

Suppose that you want to change a field that renders as a textbox into a static drop down list of items, such as the Reorder Level field in the Products controller of the Northwind sample. By default, users can enter any numeric value in the field.

'Reorder Level' field showing numbers and as a textbox

Let’s change this by offering a drop down list of predefined items, and have the item values displayed as words.

You can do this at design time, as explained in Creating Static Lookup Items. However, there may be other situations when you don’t want to change the physical properties of the application. For example, the static items maybe displayed only to users in specific roles. For this purpose, you can use virtualization node sets.

First, you will need to enable shared business rules.

Next, switch to the web application generator, select the project name, and press Develop. This will open the project in Visual Studio.

Develop button in Code On Time web application generator

In the Solution Explorer, navigate to ~/App_Code/Rules/SharedBusinessRules.cs(vb). The code will need to enable virtualization if the controller name is “Products”. The virtualized Products controller will have a modified ReorderLevel field. The Items Style will be changed to “Drop Down List”, and it will have the following static items:

Value Text
0 Zero
5 Five
10 Ten
15 Fifteen
20 Twenty
25 Twenty-five
30 Thirty

Place the code into your SharedBusinessRules.cs(vb) file:

C#:

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using MyCompany.Data;

namespace MyCompany.Rules
{
    public partial class SharedBusinessRules : MyCompany.Data.BusinessRules
    {
        public override bool SupportsVirtualization(string controllerName)
        {
            if (controllerName == "Products")
                return true;
            return false;
        }

        protected override void VirtualizeController(string controllerName)
        {
            if (controllerName == "Products")
            {
                NodeSet().SelectField("ReorderLevel")
                    .SetItemsStyle("DropDownList")
                    .CreateItem(0, "Zero")
                    .CreateItem(5, "Five")
                    .CreateItem(10, "Ten")
                    .CreateItem(15, "Fifteen")
                    .CreateItem(20, "Twenty")
                    .CreateItem(25, "Twenty-five")
                    .CreateItem(30, "Thirty");
            }
        }
    }
}

Visual Basic:

Imports MyCompany.Data
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq

Namespace MyCompany.Rules

    Partial Public Class SharedBusinessRules
        Inherits MyCompany.Data.BusinessRules

        Public Overrides Function SupportsVirtualization(controllerName As String) As Boolean
            If (controllerName = "Products") Then
                Return True
            Else  
Return False End If End Function Protected Overrides Sub VirtualizeController(controllerName As String) If (controllerName = "Products") Then NodeSet().SelectField("ReorderLevel") _ .SetItemsStyle("DropDownList") _ .CreateItem(0, "Zero") _ .CreateItem(5, "Five") _ .CreateItem(10, "Ten") _ .CreateItem(15, "Fifteen") _ .CreateItem(20, "Twenty") _ .CreateItem(25, "Twenty-five") _ .CreateItem(30, "Thirty") End If End Sub End Class End Namespace

Save this file and run the web application. You will see that the Products controller now displays Reorder Level filter options as words, and the field is rendered as a drop down list.

Reorder Level field in Products now showing static items as words, and as a drop down list

Friday, March 30, 2012PrintSubscribe
Virtualization Node Sets Made Easy

The workflow dashboard tutorial explains data controller virtualization.

Implementation of method VirtualizeController creates virtualization node sets to alter the data controller XML definition.

For example, the following snippet sorts the grid view grid1 in descending order of “Required Date” and rearranges its data fields by making “ShippedDate”, “EmployeeID”, and “ShipCity” appear first. The code snippet is written in Visual Basic.

If (IsTagged("OrdersShippedLate")) Then
    ' sort and rearrange 'grid1' by placing ShippedDate, EmployeeID, and ShipCity first
    NodeSet("view[@id='grid1']") _
        .Attr("sortExpression", "RequiredDate desc") _
        .Select("dataField") _
        .Arrange("@fieldName", "ShippedDate", "EmployeeID", "ShipCity")
End If

This is the data view without the virtualization node set:

The data controller view without the virtualization node set

This is the result of the virtualization node set executed at runtime:

Virtualization node set sorts the grid view grid1 in descending order of “Required Date” and rearranges its data fields by making “ShippedDate”, “EmployeeID”, and “ShipCity” appear first

Virtualization node sets alter the in-memory copy of the data controller XML definition. The in-memory copy is discarded as soon as the request from the data view has been processed.

This allows treating the entire application as a large toolkit full of building blocks. Each block may allow a maximum set of capabilities.

Developer uses virtualization node sets when implementing virtualization rules to change the building blocks. The data controller elements can be removed or changed in an arbitrary fashion. For example, the virtualization node set can be executed if a certain use case of the data controller is detected. The user identity may also trigger the virtualization node set execution.

Developers can also elect to add new capabilities to the data controller that were not defined at design time.

The example above uses the method BusinessRules.NodeSet() to create the virtualization node set. Chained calls of Attr(), Select(), and Arrange() methods are altering the data controller XML definition. Each method works on the collection of XML nodes produced by the previous call in the chain.

The basic virtualization node set methods allow selecting, deleting, arranging, and changing attributes and elements of the XML document. Selector expressions written in XPath are used as arguments of the basic methods.

The collection of named plugins is also available. The specially named methods of the virtualization node sets make the node sets much easier to understand. They do not require knowledge or understanding of XPath. Instead the methods are named after the familiar logical elements that developers are modifying in the Project Designer.

The following implementations of method VirtualizeController are written with the use of “plugin” methods instead of the basic ones. Basic methods are shown in the workflow dashboard tutorial. Each virtualization node set starts with the call to method NodeSet() without parameters and continues with calls of “named plugin” methods altering specific areas of the data controller.

C#:

protected override void VirtualizeController(string controllerName)
{
    if (controllerName == "Orders" && IsTagged("OrdersWaitingToShip", "OrdersShippedLate"))
    {
        // make the controller read-only by removing editing actions
        NodeSet().SelectActions("New", "Edit", "Delete", "Duplicate", "Import")
            .Delete();
        // delete all remaining actions in the 'Grid' scope 
        NodeSet().SelectActionGroups("Grid")
            .SelectActions()
            .Delete();
        // add new 'Navigate' action to the 'Grid' scope 
        NodeSet().SelectActionGroups("Grid")
            .CreateAction(
                "Navigate",
                "Orders.aspx?OrderID={OrderID}&_controller=Orders" +
                "&_commandName=Edit&_commandArgument=editForm1");
    }
    if (IsTagged("OrdersWaitingToShip"))
    {
        // sort grid1 and hide the 'ShippedDate' data field
        NodeSet().SelectView("grid1")
            .SetSortExpression("RequiredDate asc")
            .SelectDataField("ShippedDate")
                .Hide();
        // add data field 'ShipCountry' to 'grid1' view
        NodeSet().SelectView("grid1")
            .CreateDataField("ShipCountry");
    }
    if (IsTagged("OrdersShippedLate"))
        // sort and rearrange 'grid1' by placing ShippedDate, EmployeeID, and ShipCity first
        NodeSet().SelectView("grid1")
            .SetSortExpression("RequiredDate desc")
            .ArrangeDataFields("ShippedDate", "EmployeeID", "ShipCity");
}

Visual Basic:

Protected Overrides Sub VirtualizeController(controllerName As String)
    If (controllerName = "Orders" AndAlso IsTagged("OrdersWaitingToShip", "OrdersShippedLate")) Then
        ' make the controller read-only by removing editing actions
        NodeSet().SelectActions("New", "Edit", "Delete", "Duplicate", "Import") _
            .Delete()
        ' delete all remaining actions in the 'Grid' scope 
        NodeSet().SelectActionGroups("Grid") _
            .SelectActions() _
            .Delete()
        ' add new 'Navigate' action to the 'Grid' scope 
        NodeSet().SelectActionGroups("Grid") _
            .CreateAction(
                "Navigate",
                "Orders.aspx?OrderID={OrderID}&_controller=Orders" +
                "&_commandName=Edit&_commandArgument=editForm1")
    End If
    If (IsTagged("OrdersWaitingToShip")) Then
        ' sort grid1 and hide the 'ShippedDate' data field
        NodeSet().SelectView("grid1") _
            .SetSortExpression("RequiredDate asc") _
            .SelectDataField("ShippedDate") _
                .Hide()
        ' add data field 'ShipCountry' to 'grid1' view
        NodeSet().SelectView("grid1") _
            .CreateDataField("ShipCountry")
    End If
    If (IsTagged("OrdersShippedLate")) Then
        ' sort and rearrange 'grid1' by placing ShippedDate, EmployeeID, and ShipCity first
        NodeSet().SelectView("grid1") _
            .SetSortExpression("RequiredDate desc") _
            .ArrangeDataFields("ShippedDate", "EmployeeID", "ShipCity")
    End If
End Sub

This is the effect of the virtualization node sets evaluated at runtime.

Effect of virtualization node sets on the data views