Blog: Posts from May, 2012

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
Posts from May, 2012
Wednesday, May 23, 2012PrintSubscribe
Customizable Main Menu with Two Levels

Database web applications may contain multiple pages with a complex navigation hierarchy. Traditional multi-level menus do a good a job of presenting such hierarchies. 

Consider the following web app created from Adventure Works database with Code On Time. The navigation menu has multiple levels reflecting the relationships between database tables. Developers will likely want to change the automatically configured menu structure but will still be forced to create multiple levels of navigation menu options.

The automatically composed menu structure of 'Adventure Works' app created with Code On Time web application generator

A web application can be configured to use an advanced two-level menu.

Start the web application generator, select the project name, choose Settings option, and proceed to alter the layout of application pages under Layouts section.

Choose Advanced Two-Level menu presentation style and click Finish.

Generate the app and inspect the new look of the navigation menu in the browser. The second level of the menu is rendered flat with indentation reflecting the hierarchy. All navigation menu levels are visible and accessible immediately.

Advanced two-level menu in 'Adventure Works' sample created with Code On Time web application generator

The accessibility of menu options can be further improved by breaking them into multiple columns.

Start Project Designer and select Pages tab. Select New | New Page option on the action bar. Enter the following properties and click OK to save the page.

Property Value
Name ProductionFirstColumn
Index 1345
External Url about:blank
Path Production| First Column
Roles *

Select  Home link in designer bread crumbs and create another page configured with these properties.

Property Value
Name ProductionSecondColumn
Index 1485
External Url about:blank
Path Production | Second Column
Custom Style menu-new-column
Roles *

These is the partial hierarchy of the pages in Project Explorer with some of the child nodes under Production page collapsed for clarity.

image

The highlighted page properties affect the menu presentation.

  • If about:blank is found in the External Url property, then the corresponding physical page is not created by the application generator. The menu option will be rendered as a static text.
  • It is mandatory to enter “*” in the Roles property. Otherwise the security trimming mechanism will remove the option from the menu at runtime.
  • If the CSS class with the name menu-new-column is entered in Custom Styles, then a new column of options is started in the second level of the advanced two-level menu.

The indexes of new pages were selected so that they would precede pages Production | Product and Production | Location.

Here is the effect of the changes. All navigation menu options under Production are rendered in two columns.

Customized advanced two-level menu with two columns of options in 'Adventure Works' sample created with Code On Time web application generator

If an option of any sub-level is selected, then the user interface of the main menu reflects that.

The advanced two-level menu reflects selection of any options on its sub-levels

The second level of advanced two-level menu can be further enhanced with the custom CSS style sheets. Create a custom CSS stylesheet in the project and enter following rules.

div.two-level div.production-menu
{
    background-image: url(../_Shared/Page_Categories.png);
    background-repeat: no-repeat;
    background-position: 110% top;
}

div.two-level div.human-resources-menu
{
    background-image: url(../_Shared/Page_Announce.png);
    background-repeat: no-repeat;
    background-position: 130% top;
    padding-right:70px!important;
}

Start Project Designer and modifying the following pages.

Page Name Page Path Property New Value
HumanResources_Home Human Resources Custom Style human-resources-menu
Production_Home Production Custom Style production-menu

Generate the app, refresh the browser page, and inspect Human Resources and Production options on the top level of the main menu.

A custom CSS rule displays a background image in the second level of 'Human Resources' menu option in 'Adventure Works' sample created with Code On Time web application generator

A custom CSS rule displays a background image in the second level of 'Production' menu option in 'Adventure Works' sample created with Code On Time web application generator

These are the examples of advanced two-level menu with other available themes.

An example of a customized advanced two-level menu in web app with the 'Graham' theme

An example of a customized advanced two-level menu in web app with the 'Social' theme

Tuesday, May 22, 2012PrintSubscribe
Modifying User Interface with CSS

Code On Time web applications use Cascading Style Sheets (CSS) to theme the application elements, including colors, fonts, backgrounds, borders, paddings, margins, and other embellishments.

The screen below shows the Employees page of a web application generated using Social theme.

Employees page of a Code On Time web application using Social theme.

Most modern browsers have built-in page inspection capabilities. For example, if you are using Internet Explorer 9, you will need to press F12 to bring up Developer Tools. On the menu, click on Disable / CSS menu option.

Disable CSS using the Developer Tools in Internet Explorer 9.

The page style sheet will be disabled, and the page will look like the screenshot below. You can see that it is now “black on white” - just black text and blue links. If you want to completely revamp the page, it may be best to start from here.

Employees page of a Code On Time web application with CSS disabled.

Alternatively, you can add incremental enhancements to existing themes. Let’s make a cosmetic enhancement to the Social theme.

On the Developer Tools menu bar, click on Disable / CSS menu option again to enable the site styling. Click on the Arrow icon on the toolbar to activate Inspection mode. In this mode, when you mouse over an element in the page, it will be surrounded by a blue border.

Developer Tools Inspection mode will overlay a blue background on moused over page elements.

Click on the first cell underneath the Address column. The Developer Tools window will find the HTML corresponding to the selected element. Three CSS classes Cell, Address, and StringType are currently assigned to the table cell. Let’s create a CSS class that will add a gray background to the Address column.

Select the first cell underneath the Address column on the Employees page of the Code On Time web application.

Start Code On Time web application generator, click on the project name, and press Develop to open the project in Visual Studio. In the Solution Explorer, right-click on the ~/App_Themes/MyCompany folder and click on Add New Item option. If you changed the namespace of your application, then choose the corresponding folder.

In the Solution Explorer, right-click on the ~/App_Themes/MyCompany folder and click on Add New Item option.

In the window that opens, select your programming language, and then choose Style Sheet. Optionally rename the file, and then press Add.

Select 'Style Sheet' option, and press Add.

Replace the default text in the style sheet with the following rule.

.Cell.Address
{
    background-color:#F2F2F2!important;
    border-bottom-color:#F2F2F2!important;
}

Note the use of the !important suffix. This suffix needs to be used when your custom CSS rules come into conflict with the core theme, and you would like your own rule to prevail.

Save the file, and refresh the web page. You will see that the Address column now has a gray background.

The Address column of the Employees grid view is now stylized with a gray background.

Cascading style sheets offer an infinite number of options to affect the presentation of pages without changing a single line in the web application itself. Applications created with Code On Time do not explicitly specify colors or fonts anywhere in the source code. You can alter your application to your exact specifications.

Friday, May 18, 2012PrintSubscribe
Assigning an Email Address in Business Rules

The examples of simple and conditional email business rules are explicitly defining the sender and recipient of notifications.

The sender is specified in the From parameter of the email business rule script. The recipients are specified in the To parameter.

From: "Sales Admin" <YOUR_EMAIL_ADDRESS@gmail.com>
To: RECEIPIENT@northwind.com
Subject: Price of "{ProductName}" has been changed
. . . . .

Most real-world web applications will use the same email address as the “From” parameter. This email address is also known as system administrator.

Multi-tenant web applications may require a different system administrator for each tenant.

There are also instances when an email is sent on behalf of a person associated with the data  that has changed. For example, a notification about a new customer may be sent from a regional sales manager to a subordinate sales representative.

It is not uncommon to have multiple recipients for a single notification.

Referencing “Sender” and “Recipient” Fields

If the sender and recipients of a notification are stored in the fields of the data controller, then the field names can be referenced directly in From and To parameters. The format of the reference is similar to the ProductName in the Subject of notification from the email business rule fragment presented above.

For example, the fragment of the notification can be changed as follows.

From: {SalesManagerEmail}
To: {SalesRepEmail}
Subject: Price of "{ProductName}" has been changed
. . . . .

The example makes an assumption that the data controller views include the data fields with the names SalesManagerEmail and SalesRepEmail.

The actual email addresses may be quite flexible.

The address in the From data field may be stored with or without a display name. The address in the To field follows the same specification. Multiple email addresses can be stored in this field as well. Email business rules will automatically parse and detect multiple addresses and optional display names.

For example, the following list can be stored in the database in the table column SalesRepEmail.

johndoe@acme.com, john.doe@acme.com,
John Doe <john.doe@acme.com>; "Doe, John" <johndoe@acme.com>

The application framework will parse the field value and will send the email to four recipients.

Using SQL Business Rules to Determine Sender and Recipient

Consider the Northwind sample, a line-of-business app of a mail order company.

Suppose that there is a business requirement to notify the sales rep placing an order if this is a repeat purchase by customer.  A personal thank you note must be written to a repeat customer.

Another business requirement is to send a shipping reminder to an employee associated with an order when its shipping date has changed.

Let’s make an assumption that every employee has a user account composed of their first and last names separated with period. The user account andrew.fuller is shown in the screenshot of Membership Manager.

Several user accounts were created with user names composed of the first and last names of employees separated with 'period'

Sending a “Thank You” Note Reminder to Current User

If the data fields with sender and recipients are not available, then you can determine this information with a help of an SQL business rule that makes use of a current user identity.

Create a new SQL business rule in Orders data controller with the following properties.

Property Value
CommandName Insert|Update
Type SQL
Phase After
Script
set @BusinessRules_Whitelist = 'Empty'
if @Arguments_CommandName = 'Insert'
begin 
    -- count the number of orders
    declare @NumberOfOrders int
    select @NumberOfOrders = count(*)
    from Orders where CustomerID = @CustomerID
    -- update the Whitelist if this is the second order
    if @NumberOfOrders = 2 
    begin
        set @BusinessRules_Whitelist = 
            @BusinessRules_Whitelist + ',ThankYouReminder'
        -- find the company name of the "repeat" customer
        select @Session_RepeatCustomer = CompanyName
        from Customers where CustomerID = @CustomerID
        -- find the email address of the current user
        select @Session_EmailAddress = m.Email 
        from aspnet_Membership m 
          inner join aspnet_Users u on m.UserId = u.UserId
        where
            u.UserName = @BusinessRules_UserName
    end
end

The script determines if the current order is the second order placed for the customer by the sales rep.

The parameter named @BusinessRules_UserName is used to find the email address of the current user. The other highlighted parameters are used in the script of the email.

Proceed to create a new Email business rule in the same data controller

Property Value
Command Name Insert
Name ThankYouReminder
Type Email
Phase After
Script
Host: smtp.gmail.com
Port: 587
UserName: YOUR_EMAIL_ADDRESS@gmail.com
Password: PASSWORD
EnableSSL: true

From: "Sales Admin" <YOUR_EMAIL_ADDRESS@gmail.com>
To: {@Session_EmailAddress}
Subject: Customer "{@Session_RepeatCustomer}" placed the second order!

Please send a personal "Thank You" note to the customer.

Northwind,
Administrator

Make sure to change the highlighted STMP account parameters with your values.

The hierarchy of the data controller with two business rules is shown next.

Two business rules are configured to send a 'Thank You' note notification to the current user when the second order is placed for a customer

Generate the app, sign in as andrew.fuller and change the user email address in My Account settings to your own email. Create a new customer and place the first order - there will be no notification. Place a second order for the same customer and a notification will be waiting in your inbox.

'Thank You' note reminder in the Gmail inbox of the sales person

Standard UserEmail Parameter

The SQL business rule can be made shorter thanks to the property UserEmail available in BusinessRules class of the application framework. Remove the code that assigns a value to @Session_EmailAddress and change the email business rule as shown in the next fragment.

. . . . .
To: {@BusinessRules_UserEmail}
Subject: Customer "{@Session_RepeatCustomer}" placed the second order!
. . . . .

The property returns the email address of the current user. The parameter value will be equal to the value of the property.

Sending a Shipping Notification

The partial database schema of Northwind database shows Orders and Employees tables.

A relationship between Orders and Employees in Northwind database

We can easily determine the user name of an employee thanks to our assumption that the user name is composed of a period-separated first name and last name (andrew.fuller, steven.buchanan, etc.)

Let’s send another notification that will go out as soon as an order has a new shipping date. The email will be sent to an employee specified in Orders.EmployeeID field.

Change the SQL business rule script by adding the following condition at the end of the original.

-- send an order shipping notification to the sales rep
if @ShippedDate_Modified = 1 and @ShippedDate_NewValue is not null
begin
    -- find the user name of the sales rep
    declare @SalesRepUserName nvarchar(50)
    select @SalesRepUserName = lower(FirstName) + '.' + lower(LastName)
    from Employees where EmployeeID = @EmployeeID
    -- find the email address of the sales rep
    select @Session_SalesRepEmailAddress = m.Email 
    from aspnet_Membership m 
      inner join aspnet_Users u on m.UserId = u.UserId
    where
        u.UserName = @SalesRepUserName
    -- update the Whitelist to allow notification
    if @Session_SalesRepEmailAddress is not null
    begin
       set @BusinessRules_Whitelist = 
            @BusinessRules_Whitelist + ',ShippingNotification'
       -- prepare a session variable used in the notification
       select @Session_ShipCustomer = CompanyName
       from Customers where CustomerID = @CustomerID
    end
end

The highlighted parameter from SQL script will be referenced in the To parameter of the email notification.

Add another Email business rule with these properties.

Property Value
Command Name Insert|Update
Name ShippingNotification
Type Email
Phase After
Script
Host: smtp.gmail.com
Port: 587
UserName: YOUR_EMAIL_ADDRESS@gmail.com
Password: PASSWORD
EnableSSL: true

From: "Sales Admin" <YOUR_EMAIL_ADDRESS@gmail.com>
To: {@Session_SalesRepEmailAddress}
Subject: Order placed by "{@Session_ShipCustomer}" has shipped

Order placed on {OrderDate,d} by {@Session_ShipCustomer} has shipped on {ShippedDate,dddd, m/d/yyyy}.
The amount of freight is {Freight,c}.

Northwind,
Administrator

Notice the custom data format strings in the field OrderDate, ShippedDate, and Freight.

This is the new hierarchy of Orders data controller.

Data controller 'Orders' with one SQL business rule and two 'named' Email business rules

This is how the shipping notification will look in the Gmail inbox of the sales representative.

The shipping notification in the Gmail inbox of the sales representative.

Carbon Copy and Blind Carbon Copy

If you need to copy additional recipients when sending a notification, then specify parameters Cc and Bcc in the scrip of the email business rules.

Both parameters follow the same format as To parameter.