Blog: Posts from January, 2013

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

Let’s create a page that will contain a custom user control and a data view. The user control will contain several buttons that will programmatically change the filter on the data view.

Adding the Page

Start the Project Designer. On the Project Explorer toolbar, click on the New Page icon.

Creating a new page.

Assign a name to the page:

Property Value
Name Custom Filter Panel

Press OK to save. Drop the Custom Filter Panel page node on the right side of Home page node to place it second in the menu.

Dropping 'Custom Filter Panel' page on the right side of 'Home' page.     Page 'Custom Filter Panel' has been placed second in the menu.

Right-click on Custom Filter Panel node, and press New Container.

Adding a new container to the 'Custom Filter Panel' page.

Keep the default configuration and press OK to save the container. Right-click on Custom Filter Panel / c101 container node, and press New Control.

Creating a new control in container 'c101'.

Next to the User Control lookup, click on the New User Control icon.

Creating a new user control.

Assign the user control a name:

Property Value
Name FilterPanel

Press OK to create the new user control. Press OK to add the control to the page.

Implementing the User Control

On the Project Designer toolbar, press Browse to generate the application and user control file.

When complete, right-click on Custom Filter Panel / c101 / control1 – FilterPanel node and press Edit in Visual Studio.

Editing the custom user control file in Visual Studio.

The user control file will be opened in Visual Studio. Replace the code base after the <%@ Control %> element with the following:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <div style="margin-bottom:4px">
            <h2 style="margin-bottom:4px; margin-top:6px;">Select a filter:</h2>
            <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Shipped" />
            <asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Not Shipped" />
            <asp:Button ID="Button3" runat="server" OnClick="Button3_Click" Text="High Freight" />
            <asp:Button ID="Button4" runat="server" OnClick="Button4_Click" Text="Reset" />
        </div>
    </ContentTemplate>
</asp:UpdatePanel>
<div id="OrderList" runat="server">
</div>
<aquarium:DataViewExtender ID="dve1" runat="server" TargetControlID="OrderList"
    Controller="Orders" />

The code above will add four buttons and an Orders data view. Right-click and press View Code.

'View Code' context menu option for the user control file in Visual Studio.

Replace the existing code base with the following:

C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MyCompany.Web;
using MyCompany.Data;

public partial class Controls_FilterPanel : System.Web.UI.UserControl
{
    // assign filter when page loads
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            dve1.AssignStartupFilter(new FieldFilter[] { 
                new FieldFilter(
                    "ShippedDate", 
                    RowFilterOperation.DoesNotInclude,
                    null) });
    }
    // filter ShippedDate to not null
    protected void Button1_Click(object sender, EventArgs e)
    {
        dve1.AssignFilter(new FieldFilter[] { 
            new FieldFilter(
                    "ShippedDate", 
                    RowFilterOperation.DoesNotInclude,
                    null), 
            new FieldFilter(
                "Freight",
                RowFilterOperation.None) });
    }
    // filter ShippedDate to null
    protected void Button2_Click(object sender, EventArgs e)
    {
        dve1.AssignFilter(new FieldFilter[] { 
            new FieldFilter(
                "ShippedDate", 
                RowFilterOperation.Equal,
                null), 
            new FieldFilter(
                "Freight",
                RowFilterOperation.None) });
    }
    // filter Freight to >30
    protected void Button3_Click(object sender, EventArgs e)
    {
        dve1.AssignFilter(new FieldFilter[] { 
            new FieldFilter(
                "Freight", 
                RowFilterOperation.GreaterThan, 
                30), 
            new FieldFilter(
                "ShippedDate",
                RowFilterOperation.None)});
    }
    // reset filter when Reset button clicked
    protected void Button4_Click(object sender, EventArgs e)
    {
        dve1.AssignFilter(new FieldFilter[] { 
            new FieldFilter(
                "ShippedDate", 
                RowFilterOperation.None), 
            new FieldFilter(
                "Freight",
                RowFilterOperation.None) });
    }
}

Visual Basic:

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text.RegularExpressions
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports MyCompany.Web
Imports MyCompany.Data


Partial Public Class Controls_FilterPanel
    Inherits Global.System.Web.UI.UserControl
    ' assign filter when page loads
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        If Not IsPostBack Then
            dve1.AssignStartupFilter(New FieldFilter() {
                                     New FieldFilter(
                                         "ShippedDate",
                                         RowFilterOperation.Equal,
                                         Nothing)})
        End If
    End Sub
    ' filter ShippedDate to not null
    Protected Sub Button1_Click(sender As Object, e As EventArgs)
        dve1.AssignFilter(New FieldFilter() {
                                     New FieldFilter(
                                         "ShippedDate",
                                         RowFilterOperation.NotEqual,
                                         Nothing),
                                    New FieldFilter(
                                        "Freight",
                                        RowFilterOperation.None)})
    End Sub
    ' filter ShippedDate to null
    Protected Sub Button2_Click(sender As Object, e As EventArgs)
        dve1.AssignFilter(New FieldFilter() {
                                     New FieldFilter(
                                         "ShippedDate",
                                         RowFilterOperation.Equal,
                                         Nothing),
                                    New FieldFilter(
                                        "Freight",
                                        RowFilterOperation.None)})
    End Sub
    ' filter Freight to >30
    Protected Sub Button3_Click(sender As Object, e As EventArgs)
        dve1.AssignFilter(New FieldFilter() {
                                     New FieldFilter(
                                         "ShippedDate",
                                         RowFilterOperation.None),
                                    New FieldFilter(
                                        "Freight",
                                        RowFilterOperation.GreaterThan,
                                        30)})
    End Sub
    ' reset filter when Reset button clicked
    Protected Sub Button4_Click(sender As Object, e As EventArgs)
        dve1.AssignFilter(New FieldFilter() {
                                     New FieldFilter(
                                         "ShippedDate",
                                         RowFilterOperation.None),
                                    New FieldFilter(
                                        "Freight",
                                        RowFilterOperation.None)})
    End Sub
End Class

The code will assign filters when any of the buttons are pressed. Save the file.

Viewing the Results

Switch to the open web application and refresh the page. Navigate to Custom Filter Panel page. The page will contain four buttons and an Orders data view. The data view will be filtered to show only rows that have a value in Shipped Date field.

The data view on 'Custom Filter Panel' page will be filtered when the page loads.

Click on one of the first three buttons. The filter will change accordingly.

Clicking on one of the buttons will change the filter.

Clicking on the Reset button will clear all filters.

The 'Reset' button will clear all filters.

Saturday, January 19, 2013PrintSubscribe
“Filter Field” Property for Data Views

The Filter Field property specifies the foreign key field on the child data view that will be filtered in a master-detail relationship.

Drag & drop techniques can be used in order to automatically configure the relationship. For example, the picture below shows how to configure CustomerID as the filter field between Customers and Orders data views.

Dropping CustomerID field onto 'view1' to create a master-detail relationship.     Master-detail relationship created between view1 and view2.

However, when the master data view has a compound primary key, the relationship must be configured manually.

Let’s add a Notes table to the database that will have a compound primary key that refers to OrderID and ProductID.

Notes table diagram.

The table will then be added to the project. A Notes data view will be added to the default Orders page in order to compose a three-level master-detail relationship.

Creating the Notes Table

Start SQL Server Management Studio and connect to your database. In the Object Explorer, right-click on Databases / Northwind node, and press New Query.

Creating a new query for Northwind database.

Paste in the following script:

create table dbo.Notes(
    IDofOrder int not null,
    IDofProduct int not null,
    Notes ntext not null,
    Created datetime not null,
     constraint PK_Notes primary key clustered
    (
        IDofOrder asc,
        IDofProduct asc
    )
)

alter table dbo.Notes add constraint FK_Notes_OrderDetails_OrderID foreign key (IDofOrder)
references dbo.Orders (OrderID)

alter table dbo.Notes add constraint FK_Notes_OrderDetails_ProductID foreign key (IDofProduct)
references dbo.Products (ProductID)

Click on Execute on the toolbar to run the query.

Adding the Table to the Project

Start the web application generator. Click on the project name, and press Refresh. Check the box next to dbo.Notes table to add it to the project, and press Refresh.

Adding the Notes table to the project.

Adding Notes Data View

Right-click on Notes controller node, and press Copy.

Copying the Notes controller.

Switch back to the Pages tab. Right-click on Customers / Orders page node, and press Paste. The data controller will be instantiated as a data view in a new container.

Pasting the Notes controller onto Orders page.     Notes controller instantiated as a view on the page.

Configuring Master-Detail Relationship

Double-click on Customers /Orders / c101/ view4(Notes) node.

'View4' view on the Orders controller.

Make the following changes:

Property New Value
View grid1
Text Notes
Filter Source view3
Filter Field #1 IDofOrder
Filter Field #2 IDofProduct
Auto Hide Container

Press OK to save.

Viewing the Results

On the Project Designer toolbar, press Browse. Navigate to the Orders page. Select an order from the list, and then select an order detail. The Notes data view will appear underneath, filtered by OrderID and ProductID.

Notes data view is being filtered by OrderID and ProductID of Order Details view.Notes data view is being filtered by OrderID and ProductID of Order Details view.

Thursday, January 17, 2013PrintSubscribe
Conditional Data Editing

The When Client Script property allows controlling the display of an action based on a JavaScript expression. When the expression evaluates to true, the action is displayed. When it evaluates to false, the action is hidden. This property can be used to prevent users from editing a record based on certain conditions.

The property may be manually set in the Project Designer for every action that needs to be hidden. However, this may result in a large number of changes to be made. If the requirements of the web application were to change, all actions would need to be modified.

A simpler method would be to use virtualization node set plugins. The data controllers will be virtualized to conditionally add a When Client Script parameter for a subset of actions. When project requirements change, the virtualization code can be modified once.

For example, suppose that the web application described in the When Client Script tutorial has been created. The three Edit actions in the Orders controller are not displayed when the Status field of the order is set to “Committed”.

Edit actions removed from the Orders controller.

However, orders may still be deleted and order details can be modified. Let’s implement virtualization node set plugins to ensure that the user cannot make any changes to committed orders.

First, make sure to clear any When Client Script values that have been set previously.

Including Status Field in Order Details Controller

In order to prevent order details from being edited, the Status field must be included in the Order Details controller using denormalization.

Start the web application generator. Click on the project name, select Settings, and activate Business Logic Layer. Select Denormalization Map from the list, and make the highlighted addition:

dbo.Order Details => dbo.Orders
OrderDate
RequiredDate
ShippedDate
ShipVia
Freight
ShipName
ShipAddress
ShipCity
ShipRegion
ShipPostalCode
ShipCountry
Status

dbo.Orders => dbo.Employees
FirstName

Press Finish to navigate to the Summary page. Click on Refresh, and check the box next to OrderDetails controller. Press Refresh and confirm.

Refreshing the OrderDetails controller.

On the Summary page, press Design to activate the Project Designer. In the Project Explorer, switch to the Controllers tab. Double-click on OrderDetails / Fields node.

'OrderStatus' field of OrderDetails controller.

Mark the field as hidden.

Property New Value
The field is hidden from users. true

Press OK to save. Drop OrderStatus (String(50), read-only) field node onto OrderDetails / Views / grid1 node.

Dropping field 'OrdersStatus' onto 'grid1' view.     'OrderStatus' data field instantiated.

Adding Business Rule

Right-click on Orders controller node and press Edit Handler in Visual Studio.

Using the context menu option 'Edit Handler in Visual Studio'.

The handler file will open in Visual Studio. Append the SharedBusinessRules class with the two highlighted methods:

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 SharedBusinessRules()
        {
        }

        protected override void EnumerateDynamicAccessControlRules(string controllerName)
        {
            if (Context.Request.UrlReferrer != null)
            {
                if (Context.Request.UrlReferrer.ToString().ToLower().Contains("orderform.aspx"))
                    RegisterAccessControlRule("OrderID",
                        "select OrderID from Orders where Status = 'Draft'",
                        AccessPermission.Allow);
                else
                    RegisterAccessControlRule("OrderID",
                        "select OrderID from Orders where Status = 'Committed'",
                        AccessPermission.Allow);
            }
        }

        public override bool SupportsVirtualization(string controllerName)
        {
            if (controllerName == "Orders" || controllerName == "OrderDetails")
                return true;
            else
                return false;
        }
protected override void VirtualizeController(string controllerName) { if (controllerName == "Orders") NodeSet().SelectActions("Edit", "Delete") .WhenClientScript("[Status] != 'Committed'"); else if (controllerName == "OrderDetails") NodeSet().SelectActions("Edit", "Delete", "New", "Duplicate") .WhenClientScript("[OrderStatus] != 'Committed'"); } } }

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 Sub New()
            MyBase.New()
        End Sub

        Protected Overrides Sub EnumerateDynamicAccessControlRules(controllerName As String)
            If Context.Request.UrlReferrer <> Nothing Then
                If Context.Request.UrlReferrer.ToString().ToLower().Contains("orderform.aspx") Then
                    RegisterAccessControlRule("OrderID",
                                            "select OrderID from Orders where Status = 'Draft'",
                                            AccessPermission.Allow)
                Else
                    RegisterAccessControlRule("OrderID",
                                            "select OrderID from Orders where Status = 'Committed'",
                                            AccessPermission.Allow)
                End If
            End If
        End Sub

        Public Overrides Function SupportsVirtualization(controllerName As String) As Boolean
            If controllerName = "Orders" Or controllerName = "OrderDetails" Then
                Return True
            Else
                Return False
            End If
        End Function
Protected Overrides Sub VirtualizeController(controllerName As String) If controllerName = "Orders" Then NodeSet().SelectActions("Edit", "Delete").WhenClientScript( "[Status] != 'Committed'") ElseIf controllerName = "OrderDetails" Then NodeSet().SelectActions("Edit", "Delete", "New", "Duplicate").WhenClientScript( "[OrderStatus] != 'Committed'") End If End Sub End Class End Namespace

The business rule will virtualize the Orders and OrderDetails controllers. For Orders, all Edit and Delete actions will be selected. For OrderDetails, all Edit, Delete, New, and Duplicate actions will be selected. Then, a When Client Script parameter will be assigned to hide the actions when the Status field is equal to “Committed”.

Viewing the Results

Save the file, and run the web application in your browser. Navigate to the Orders page. The Edit and Delete actions are no longer available in the user interface.

All Edit and Delete actions on Orders controller are unavailable.

Select an order to view the order details. All Edit, Delete, New, and Duplicate actions will not be available.

image