Blog

Labels
AJAX(112) App Studio(9) 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(178) 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(184) 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(3) 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
Sunday, September 21, 2008PrintSubscribe
Header and Footer Text in Form Views

Custom headers and footers can boost ease of use of your applications created with Data Aquarium Framework.  Take a look at the following screen shot.

image

Data field Unit Price features custom header and footer. Here is how we have defined this view in ~/Controllers/Products.xml of our sample application.

<view id="editForm1" type="Form" commandId="command1" label="Review Products">
  <headerText>Please review products information below. 
    Click Edit to change this record, click Delete to delete the record, 
    or click Cancel/Close to return back.</headerText>
  <categories>
    <category headerText="Products">
      <description>These are the fields of the products record 
        that can be edited.</description>
      <dataFields>
        <dataField fieldName="ProductName" columns="40" />
        <dataField fieldName="SupplierID" aliasFieldName="SupplierCompanyName" />
        <dataField fieldName="CategoryID" aliasFieldName="CategoryCategoryName" />
        <dataField fieldName="QuantityPerUnit" columns="20" />
        <dataField fieldName="UnitPrice" dataFormatString="c" columns="15">
          <headerText>Price of Unit:</headerText>
          <footerText>
            <![CDATA[ 
            <div style="color:navy">
            Enter price of unit in USD. Make sure to consult catalog of products 
            sold by our competitors at
            <a href="http://www.amazon.com" target="_blank">amazon.com</a>
            </div>]]>
          </footerText>
        </dataField>
        <dataField fieldName="UnitsInStock" columns="15" />
        <dataField fieldName="UnitsOnOrder" columns="15" />
        <dataField fieldName="ReorderLevel" columns="15" />
        <dataField fieldName="Discontinued" />
      </dataFields>
    </category>
  </categories>
</view>

HeaderText is displayed above the field value while the FooterText is displayed just under the field value. By default the field header is inherited from the label attribute of the base field.

You can break down the fields in the standard views in a few categories to further improve the form presentation.

Header and footer text will also automatically display in a custom form. Define the following markup in your web form that displays products.

<aquarium:DataViewExtender ID="ProductsExtender" runat="server" 
    Controller="Products" TargetControlID="ProductList" />
<div id="Products_editForm1" style="display: none">
    {ProductName}<br />
    {SupplierID}<br />
    {CategoryID}<br />
    {UnitPrice}
</div>

This simple markup will alter the form view presentation shown in the screen shot above to look like the one below.

image

Custom form templates allow ad hoc form view presentation when standard layout does not provide enough flexibility.

Sunday, September 21, 2008PrintSubscribe
Building a Better UI With Data Aquarium Framework

Data Aquarium Framework has introduced a new feature that allows developers and designers to affect presentation of data fields in grid and form views.

Generated applications are using a default theme for a consistent and efficient presentation. There will situations when you need to customize some screens without affecting the entire application. Consider the following illustration.

image

By default all columns values in the grid view are aligned horizontally to the left. You might want to have Unit Price column values aligned to the right and Discontinued flag to be centered.

Add a CSS stylesheet with default name to ~/App_Themes/MyCompany folder and enter the following text in its body.

table.DataView tr.Row td.UnitPrice,
table.DataView tr.AlternatingRow td.UnitPrice
{
    text-align: right;
    padding-right: 4px;
    background-color:Yellow;
    color:red;
}

table.DataView tr.HeaderRow th.UnitPrice a
{
    color:Blue;
}

table.DataView tr.Row td.Discontinued, table.DataView tr.AlternatingRow td.Discontinued
{
    text-align: center;
    background-color: #CCFFCC;
}

The first CSS rule definition will ensure that Unit Price column values are displayed on a yellow background, aligned to the right with a four pixel padding, and red font color.

The second rule will make a link in the header of the column Unit Price to be of blue color.

The third rule centers text and changes the background color of the Discontinued column.

image

How does it work?

Presentation of the grid is rendered in a client browser by Web.DataView component that can be found in  ~/Scripts/DataView.js. The presentation rendering code adds a field name to the list of classes on corresponding table cells of the view. Your custom CSS stylesheet can provide rules to take advantage of these classes.

It is important to name the stylesheet in such a way that is will be the last stylesheet of your application theme.

Here is a snippet of HTML generated for the sample page if you view the page source.

<head>
    .............
    <link href="App_Themes/MyCompany/Aquarium.css" type="text/css" 
        rel="stylesheet" />
    <link href="App_Themes/MyCompany/StyleSheet.css" type="text/css" 
        rel="stylesheet" />
    .............
</head>

Our stylesheet with default name Stylesheet.css follows the standard style sheet that comes with Data Aquarium Framework. These ensures that our CSS rules are going to override or extend those defined in the standard stylesheet.

Similar features are available in form views. If you need help in figuring out correct rules then please post a comment on this blog or drop us a line at http://www.codeontime.com/contactus.aspx.

Saturday, September 20, 2008PrintSubscribe
Displaying Detail Information in an Arbitrary Part of The Page Based on a Field in a Selected Master Record

Aquarium Express and Data Aquarium Framework offer excellent support for master-detail pages. See a live demo of three level master-detail page.

Master-detail support has been further extended with the latest release. Now you can link master and detail DataViewExtender components by any matching field.

Previously a detail DataViewExtender was expected to specify filter fields that are matched to the primary key fields of the master. The updated version will also try to set a link to primary key fields by name. If a primary key field has not been matched to a field specified in FilterFields property of the detail DataViewExtender then the entire set of fields is being searched. This allows to create additional master-detail AJAX views that can serve as informational panels to any selected records as long as the field names of master-detail link are matched.

Another enhancement in master-detail support simplifies cross-container links that can see "through" the templates. Previous releases of the framework were relying on $find method to locate a client master component specified by property FilterSource. It works great if all of your components are placed in the same naming container. This isn't so when a DataViewExtender is placed in a template. The new enhancement allows master-detail links between components that are not in the same naming container.

Consider the following example, which is designed to work with Aquarium Express or Data Aquarium Framework project created from Northwind database.

In a new web form based on MasterPage.master enter the following markup.

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
    CodeFile="InfoPanel.aspx.cs" Inherits="InfoPanel" Title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="Header1Placeholder" runat="Server">
    Info Panel Demo
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="Header2Placeholder" runat="Server">
    Northwind
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="BodyPlaceholder" runat="Server">
    <act:TabContainer ID="OrderManager" runat="server">
        <act:TabPanel ID="CustomersTab" runat="server" HeaderText="Customers">
            <ContentTemplate>
                <div id="CustomerList" runat="server" />
                <aquarium:DataViewExtender ID="CustomersExtender" runat="server" 
                    Controller="Customers" TargetControlID="CustomerList" />
            </ContentTemplate>
        </act:TabPanel>
        <act:TabPanel ID="OrdersTab" runat="server" HeaderText="Orders">
            <ContentTemplate>
                <div id="OrderList" runat="server" />
                <aquarium:DataViewExtender ID="OrdersExtender" runat="server" 
                    Controller="Orders" FilterFields="CustomerID" 
                    FilterSource="CustomersExtender" TargetControlID="OrderList" />
            </ContentTemplate>
        </act:TabPanel>
        <act:TabPanel ID="DetailsTab" runat="server" HeaderText="Details">
            <ContentTemplate>
                <div id="DetailsList" runat="server" />
                <aquarium:DataViewExtender ID="DetailsExtender" runat="server" 
                    Controller="OrderDetails" FilterFields="OrderID" 
                    FilterSource="OrdersExtender" TargetControlID="DetailsList" />
            </ContentTemplate>
        </act:TabPanel>
    </act:TabContainer>
</asp:Content>

This markup defines a TabContainer from Ajax Control Toolkit with three level arrangement of Customers, Orders, and Order Details, linked in a master-detail relationship. DataViewExtender components and corresponding placeholder div elements are placed on an individual tab of the container

Run this page to see the "cross container" master-detail links in action. This was not possible with the previous releases of the framework.

image 

This form will benefit if we display a customer information summary somewhere on the page. The natural location is the top of the screen but that may differ from one application to another.

Open ~/Controllers/Customers.xml data controller descriptor and create an exact copy of editForm1. Name this copy infoForm1. We need this extra view since we don't want editForm1 of Customers controller on Customers tab to be affected when we finish customization.

Insert the following div element above the TabContainer.

    <div id="CustomerInfo" runat="server" />

Append this DataViewExtender right after the TabContainer.

    <aquarium:DataViewExtender ID="CustomerInfoExtender" runat="server" 
        Controller="Customers" View="infoForm1" FilterFields="CustomerID" 
        FilterSource="CustomersExtender" TargetControlID="CustomerInfo" />

The location of CustomerInfo div is irrelevant but the detail extender component must be defined below the master component specified by FilterSource property when a component container tree is created by ASP.NET page parser. Run this page and make sure that whenever you select a customer record on Customer tab the corresponding CustomerInfo div at the top is refreshed with the matching record.

image

As you can see the top of the page is completely occupied by editable customer view, which is not what we want. Let's change this view to display just a few of the fields and hide the view description, action bar and action buttons.

We accomplish this by adding class attribute to CustomerInfo div. We also define a custom form template Customers_infoForm1. Then we insert a few CSS definitions in Content1 placeholder, which will end up embedded in the head element of the HTML form. All this techniques will alter the appearance of the page and are described in details in a post dedicated to custom form templates.

Here is a complete text of the web form.

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
    CodeFile="InfoPanel.aspx.cs" Inherits="InfoPanel" Title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
    <style type="text/css">
        .CustomerInfo
        {
            padding: 0px;
            margin-bottom: 8px;
            background-color: White;
        }
        .CustomerInfo table.DataView tr.CategoryRow td.Fields
        {
            border: solid 1px silver;
            background-color: #E4F3E4;
        }
        .CustomerInfo .HeaderTextRow, .CustomerInfo .ActionRow, 
        .CustomerInfo .ActionButtonsRow
        {
            display: none;
        }
    </style>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="Header1Placeholder" runat="Server">
    Info Panel Demo
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="Header2Placeholder" runat="Server">
    Northwind
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="BodyPlaceholder" runat="Server">
    <div id="CustomerInfo" runat="server" class="CustomerInfo" />
    <act:TabContainer ID="OrderManager" runat="server">
        <act:TabPanel ID="CustomersTab" runat="server" HeaderText="Customers">
            <ContentTemplate>
                <div id="CustomerList" runat="server" />
                <aquarium:DataViewExtender ID="CustomersExtender" runat="server" 
                    Controller="Customers" TargetControlID="CustomerList" />
            </ContentTemplate>
        </act:TabPanel>
        <act:TabPanel ID="OrdersTab" runat="server" HeaderText="Orders">
            <ContentTemplate>
                <div id="OrderList" runat="server" />
                <aquarium:DataViewExtender ID="OrdersExtender" runat="server" 
                    Controller="Orders" FilterFields="CustomerID" 
                    FilterSource="CustomersExtender" TargetControlID="OrderList" />
            </ContentTemplate>
        </act:TabPanel>
        <act:TabPanel ID="DetailsTab" runat="server" HeaderText="Details">
            <ContentTemplate>
                <div id="DetailsList" runat="server" />
                <aquarium:DataViewExtender ID="DetailsExtender" runat="server" 
                    Controller="OrderDetails" FilterFields="OrderID" 
                    FilterSource="OrdersExtender" TargetControlID="DetailsList" />
            </ContentTemplate>
        </act:TabPanel>
    </act:TabContainer>
    <aquarium:DataViewExtender ID="CustomerInfoExtender" runat="server" 
        Controller="Customers" View="infoForm1" FilterFields="CustomerID" 
        FilterSource="CustomersExtender" TargetControlID="CustomerInfo" />
    <div id="Customers_infoForm1" style="display: none">
        <table style="width: 100%">
            <tr>
                <td>
                    {CustomerID}
                </td>
                <td style="font-weight: bold;">
                    {CompanyName}
                </td>
                <td>
                    {ContactName}
                </td>
                <td>
                    {ContactTitle}
                </td>
                <td>
                    {Phone}
                </td>
            </tr>
        </table>
    </div>
</asp:Content>

Here is an example of this form running in a web browser when user has selected a customer record and switched to Orders tab.

image

The green information panel at the top is automatically refreshed if you select a customer. The detail extender component is linked to a primary key field of a master record.

You can also link the same CustomerInfoExtender to a matching field of OrdersExtender component. The data controller of this component has CustomerID field, which is  a foreign key that points to Customers table. The new feature of Data Aquarium Framework will kick in to make such link work. Just change CustomerInfoExtender.FilterSource to OrdersExtender. The behavior of the screen will change. You have to select an order to get the green panel at the of the screen to refresh itself.

In a more realistic example you would like to have Employee information panel connected to OrdersExtender to provide details about employee who has placed the order. We leave this task up to you.