Thursday, 10 September 2015

Automatic Totals on your List page in Dynamic Data

So the idea here is add an attribute to your table (TotalsAttribute in this case) and then have a total appear on your list page.

Note: Note this will only work on Numeric columns int, Decimal, float etc.

Figure 1 shows what we are going to achieve, the columns here don’t make sense to total but it’s only an example  for real i would add a computed column that multiplied the unit cost with the qty in stock and total that but here it’s just to show how it works with decimal and int values.

finished-page

Figure 1 – Footer row with totals.

The Attribute

We will need an attribute because we want this to happen automatically and not have to create a custom page, for this I have decided to add a class level attribute called TotalsAttribute you can see the code in Listing 1.

[AttributeUsage(AttributeTargets.Class)]
public class TotalsAttribute : Attribute
{
public String[] Columns { get; set; }

public TotalsAttribute()
{
Columns = new String[0];
}

public TotalsAttribute(params String[] columns)
{
Columns = columns;
}
}

Listing 1 – TotalsAttribute

All we are doing here is keeping an array of column names that we want totals on, most of the time it will be single column, but it’s nice to have the option of multiple.

[Totals("UnitPrice", "UnitsInStock", "UnitsOnOrder")]
[MetadataType(typeof(Product.Metadata))]
public partial class Product
{
internal sealed class Metadata
{
public Int32 ProductID { get; set; }

public String ProductName { get; set; }

[DataType(DataType.Currency)]
public Nullable<int> UnitPrice { get; set; }

public Nullable<int> UnitsInStock { get; set; }

//... other column removed for simplicity
}
}

Listing 2 – example of attribute in use.

In the example [Totals("UnitPrice", "UnitsInStock", "UnitsOnOrder")] in Listing 2 we are telling the system that we want totals on three columns “UnitPrice”, “UnitsInStock”, “UnitsOnOrder”.

The Custom Code in the List page

There are two things we need in the page first we will need to check if there are totals on this table and if so wire it all up. In Listing 3 we have all the code we need to test if there are totals for the current Table and if so wire up the Row DataBound even handler which you can see in Listing 4.

In Listing 3 we single get the attribute from the table and test to see if what we got is not null, if not we can the wire up the event handler. But also we need to turn on the footer.

!Important: I found this bit missing from most of the articles I found whilst searching for examples of how to do this; everything works without this, it just doesn't display. The bit you must have is GridView1.ShowFooter = true;
Note: I am using some custom extension methods to get the attribute, these are in the root of the application and the file is called “AttributeExtensionMethods.cs”
public partial class List : System.Web.UI.Page
{
    protected TotalsAttribute totalsAttribute;
    protected MetaTable table;

    protected void Page_Init(object sender, EventArgs e)
    {
        table = DynamicDataRouteHandler.GetRequestMetaTable(Context);
        GridView1.SetMetaTable(table, table.GetColumnValuesFromRoute(Context));
        GridDataSource.EntityTypeFilter = table.EntityType.Name;

        // get the attribute
        totalsAttribute = table.GetAttribute<TotalsAttribute>();

        // if the attribute is not null then we have some totals
        if (totalsAttribute != null && totalsAttribute.Columns.Count() > 0)
        {
            // show the footer
            GridView1.ShowFooter = true;
            // wire up the row data bound event
            GridView1.RowDataBound += OnRowDataBound;
        }
    }
// rest of code behind removed for simplicity

Listing 3 – testing if we have any totals for this table.

Now all we need the workhorse code the stuff that is going to total up and then display the totals in the footer. See Listing 4 I have tried to put a lot of comments in there to help but here’s a brief explanation of what it does:

The code in the event handler is split into two sections one for the DataRow and one for the Footer you can see there are encased in two if statements. Also note we have a global variable “totals” this is used to keep a total of each column we are totalling and is a dictionary of Decimal values.

The DataRow

Here we iterate through the totals columns from the attribute and sum up each one, you will notice that I am testing if the column is a valid column by checking the metadata to see if it is an int or an floating point this stops us having a nasty error.

// NOTE: if you are using a column generator (IAutoFieldGenerator) 
// the this may not work if it re-orders the displayed columns
protected Dictionary<String, Decimal> totals = new Dictionary<String, Decimal>();
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    // this will only be wired up and called if there are totals so we don't need to test.
    // Get a List<String> of column names if the order that they appear in the GridView1
    var displayedColumns = table.GetScaffoldColumns(DataBoundControlMode.ReadOnly, ContainerType.List).ToList();

    // if this is a data row get the totals
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        foreach (var column in totalsAttribute.Columns)
        {
            // get the MetaColumn
            var metaColumn = displayedColumns.First(c => c.Name == column);

            // check this column is a valid column to total i.e. int Decimal, float etc.
            if (metaColumn.IsFloatingPoint || metaColumn.IsInteger)
            {
                // initialize variable if not present
                if (!totals.ContainsKey(column))
                    totals.Add(column, 0);

                // add to total
                totals[column] += Convert.ToDecimal(DataBinder.Eval(e.Row.DataItem, column));
            }
        }
    }

    // if we are on the footer row render the totals.
    if (e.Row.RowType == DataControlRowType.Footer)
    {

        // set total description name
        e.Row.Cells[0].Text = "Total:";
        // add alignment style
        e.Row.Cells[0].CssClass = "right";

        foreach (var column in totalsAttribute.Columns)
        {
            // get index of column plus offset of 1 for the command button column
            var index = displayedColumns.FindIndex(c => c.Name == column) + 1;

            var metaColumn = displayedColumns.First(c => c.Name == column);
            if (metaColumn.IsFloatingPoint || metaColumn.IsInteger)
            {
                // for the Footer, display the running totals
                e.Row.Cells[index].Text = metaColumn.FormatValue(totals[column]);

                // add alignment style
                e.Row.Cells[index].CssClass = "numeric";
            }
        }
    }
}

Listing 4 – OnRowDataBound event handler and global totals variable.

Finally the second section the Footer we we simply render the totals to the footer

Note: The plus 1 I am adding to the index, is to account for the Command column with the Edit buttons etc.

Sample Code

Tuesday, 2 June 2015

Asp.Net Identity for Web Forms Introduction

I am starting a new series on the new Asp.Net Identity there are plenty of resources for MVC etc. but little for Web Forms so i thought I’d do a little investigation and document it here.

I am using Visual Studio 2013 Ultimate, remember Visual Studio 2013 Community is the new free edition of Visual Studio 2013 it is equivalent to Pro but has been stripped down to make it a smaller download, but I believe most of the bits that have been removed to create the community edition can be added back in, see Connect(); Microsoft Visual Studio vNext & Azure on Channel9.

Overview of the new Project Templates

Requirements .Net 4.5 and above, if you select .Net 4 as your framework type from the new Project dialog you will not see the One ASP.Net dialog and you will get the classic Membership added and this is not what you want as we are talking about the new Identity system.

web-forms-dot-net-4-web-application

Add new project template here for comparison.

Figure 1 – .Net 4 Web Application Project

Now we need to select the project template with a .Net framework of 4.5 as a minimum.

selecting-the-project-template

Figure 2 – Selecting the project template

one-asp-net-dialog

Figure 3 – The One Asp.Net dialog

You will get the One Asp.net dialog from this you can change the the authentication type.

change-authentication-dialog

Figure 4 – Change Authentication dialog

Let’s examine the four options offered here:

No Authentication

This is simple enough no authentication will be added to the project, it’s worth noting that this is not the default so you will need to select this option of you want a project without authentication.

change-authentication-dialog-option-2

Figure 5 – Option 1

Individual User Accounts

This option is equivalent to the old Membership system default,

change-authentication-dialog-option-1

Figure 6 – Option 2

Organizational Accounts

This is an area of big improvement over the old Membership system allowing us greater flexibility, all these options are using some form of Active Directory Federation Services Overview i.e. ADFS, Azure Active Directory. but none connect directly with Active Directory if I understand this correctly, this is probably a good thing as the issue with AD is that it’s slow so if you are looking for Roles membership in AD you would need to cache as the delays can become very long.

change-authentication-dialog-option-3a

Figure 7 – Option 3

change-authentication-dialog-option-3b

Figure 8 – More Options

  1. Choose this option to connect to your Microsoft Azure Active Directory tenet.
  2. Enter the domain name of you Microsoft Azure Active Directory tenet.
  3. Indicate what access the application will have to the directory. For an application that queries the directory using the Directory Graph API, choose an option that enables reading or writing.
  4. Enter a unique URI to identify this application. (If you leave it blank, a URI will be created automatically by appending the project name to the Microsoft Azure Active Directory domain with a number if needed to make it unique.)

change-authentication-dialog-option-3c

Figure 9 – On-Premises option for Active Directory

  1. Choose On-Premises if the organization manages user accounts by using Windows Server Active Directory or ADFS and you don’t want to use Microsoft Azure Active Directory.
  2. The metadata document contains the coordinates of the authority. Your application will use those coordinates to drive the web sign on flow.
  3. Provide a unique URI that Windows Server Active Directory can use to identify this app.

Windows Authentication

This is the same as the original Windows Authentication, in fact if you look at Figure 11 you can see the changes to the web.config are the same as the always have been for “Windows Authentication”.

change-authentication-dialog-option-4

Figure 10 – Option 4

option-4-web-config

Figure 11 – web.config authentication changes

So that’s the introduction done next we will be adding Identity to a existing WebForms application.

Friday, 17 April 2015

Register to attend the Microsoft MVP Virtual Conference

Hi All – I wanted to let you know about a great free event that Microsoft and the MVPs are putting on, May 14th & 15th.  Join Microsoft MVPs from the Americas’ region as they share their knowledge and real-world expertise during a free event, the MVP Virtual Conference.

The MVP Virtual Conference will showcase 95 sessions of content for IT Pros, Developers and Consumer experts designed to help you navigate life in a mobile-first, cloud-first world.  Microsoft’s Corporate Vice President of Developer Platform, Steve Guggenheimer, will be on hand to deliver the opening Key Note Address.

Why attend MVP V-Conf? The conference will have 5 tracks, IT Pro English, Dev English, Consumer English, Portuguese mixed sessions & Spanish mixed sessions, there is something for everyone! Learn from the best and brightest MVPs in the tech world today and develop some great skills!

Be sure to register quickly to hold your spot and tell your friends & colleagues.

The conference will be widely covered on social media, you can join the conversation by following @MVPAward and using the hashtag #MVPvConf.

Register now and feel the power of community!

clip_image001

Monday, 17 November 2014

Updated my Alternating Line Color Visual Studio Extension

I have just updated my Alternating Line Visual Studio Extension to support Visual Studio 2015 Preview. have fun Smile

vsix_AlternatingLineColorTextAdornment_large

It does what is says on the time adds those alternating lines to the code editor.

Coming soon adding custom color so you can customise it for the other themes.

Thursday, 9 October 2014

Just Updated “NotAClue Bootstrap Friendly WebForms Controls”

I have just updated my NotAClue Bootstrap Friendly WebForms Controls to version 0.1.4 you can find the source code on GitHub here Bootstrap Web Controls
I have added a Bootstrap Tabs control to enable the use of bootstrap tabs in a web forms application and support for Bootstrap 3.x
bootstrap-tabs-in-action
Figure 1 – note here there are two sets of Tabs and each remembers it’s own currently selected tab
I have made the current version work but using cookies so there is no post-back but the currently selected tab will be remembered over post-back, also note that all the controls are rendered for ALL tabs so when switching tab there is no post-back to the server.
P.S. sorry it took so long but I’ve been busy and I lost access to my GitHub account due to not fully understanding two factor auth (or just not reading the instructions).
Updated: version 0.1.5 now has a dependency on jQuery.cookie to remember the selected tab before postback
Updated: Finally I am now clearing the cookie when you first land on the page,when is not a post-back i.e. if(!Page.IsPostBack)
More posts to come around Bootstrap and Dynamic Data.

Monday, 30 December 2013

Bootstrap Friendly Dynamic Data Project Template Goes Live

Today I finished my Bootstrap Friendly Dynamic Data Project Template you can find the source up on GitHub and the Project Template on Visual Studio Gallery 

There will be more to come with many addition already on NuGet that just need minor tweaks to make them Bootstrap compatible and much much more.

Sunday, 22 December 2013

Moving My Source Code to GitHub

This is just a note to let fans know I am moving my source code to GitHub this is not because I don’t love Codeplex I do but people see to feel it’s easier to send in bug fixes and feature requests there and it does seem to be the Home of Open Source Stuff these days.

So I’m moving my bits there over the next few months starting with my Bootstrap Friendly Controls and then my Bootstrapped Dynamic Data Project Template for Entity Framework.

See you there.

Thursday, 29 August 2013

CheckBox and CheckboxList that look like Bootstrap buttons-checkbox

I really Like Bootstrap and I had the need for the Bootstrap buttons-checkbox see Figure 1 below but not being a client side genius Smile with tongue out and could not workout how I would get the selected values, and I like the use the right tool or the right job (i.e. Checkbox for Checkbox and Radio button for Radio button) So I looked around and found this article here Stuff you can do with the “Checkbox Hack” and I thought I can make that work for me Ninja

Bootstrap buttons-checkbox

Figure 1 – Bootstrap buttons-checkbox

So I made my own CSS (in LESS of course until I can get SASS) so here is the LESS source

// checkbox and rtadio button styles
.checkbox-buttons
{
// hide the checkbox/radio button
input[type=checkbox],
input[type=radio]
{
// hide checkbox
display: none;
}

// Default State
label
{
display: inline-block;
*display: inline;
padding: 6px 12px;
margin-bottom: 0;
*margin-left: .3em;
font-size: 14px;
line-height: 20px;
color: #7c7c7c;
text-align: center;
-webkit-text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
vertical-align: middle;
cursor: pointer;
background-color: #f5f5f5;
*background-color: #e6e6e6;
background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
background-repeat: repeat-x;
border: 1px solid #cccccc;
*border: 0;
border-color: #e6e6e6 #e6e6e6 #bfbfbf;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
border-bottom-color: #b3b3b3;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
font-weight: bolder;
}
// Toggled State
input[type=checkbox]:checked + label,
input[type=radio]:checked + label
{
color: #333333;
background: rgb(74, 238, 48);
*background-color: rgb(112, 255, 124);
//background: linear-gradient(top, #1e5799 0%, #7db9e8 100%);
//background: linear-gradient(to bottom, rgb(112, 255, 124), rgb(4, 212, 21));
-webkit-text-shadow: 0px 0px 6px rgba(255, 255, 255, 0.9);
text-shadow: 0px 0px 6px rgba(255, 255, 255, 0.9);
}
// Mouse over State
input[type=checkbox]:hover + label,
input[type=radio]:hover + label
{
-webkit-box-shadow: inset 2px 3px 2px #cccccc, 0 1px 6px rgba(255, 255, 255, 0.2);
box-shadow: inset 2px 3px 2px #cccccc, 0 1px 6px rgba(255, 255, 255, 0.2);
}
}

.with-border-radius
{
& > label:first-of-type
{
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}

& > label:last-of-type
{
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
}

Listing 1 - checkbox-buttons and with-border-radius classes

So I have put it on NuGet here

Bootstrap buttons checkbox and radio buttons nuget package

Bootstrap buttons checkbox and radio buttons NuGet package

Use

Add the package to your project from NuGet

From the Package Manager Console type:
Install-Package NotAClue.Checkbox.Css.Buttons

It will add a Content folder to your project if it’s not already there with the checkbox-buttons LESS and CSS files add a reference to the min.css file to your master page and then decorate you CheckBoxes, CheckBoxLists, RadioButtons and RadioButtonLists with the “checkbox-buttons“ CSS class and if you want to have the ends of the buttons rounded add the “with-border-radius” CSS class. You will get the following:

checkbox-buttons-in-action

Figure 3 – Checkbox Buttons in action

In Figure 3 you will see I have made the selected style more differentiated than the on in Bootstrap, it’s just a matter of style and usability I have some none computer literate mobile users in mind and wanted to make it clear that they had set a value.

Download

Everything you need is on NuGet.

Wednesday, 28 August 2013

Adding a simple BootstrapMenu to Dynamic Data With Bootstrap

We are going to add the new ASP.Net web forms BootstrapMenu control to a Dynamic Data project, I like to clean it up a little first.

clean project

Figure 1 – Clean project

So what I did to clean my project was to create a new Dynamic Data project and then remove the scripts folder and the RegisterScripts method and method call from the Global.asax.cs file. This will leave us with no Scripts (jQuery Modenizr etc.) in the project we are no ready to add the BootstrapMenu control.

open nuget

Figure – 2 Open NuGet

Next we search for NotAClue packages and scroll down to the last package

get bootstrap menu control

Figure 3 – Get bootstrap menu control

Click Install

installing bootstrap menu control

Figure 4 – Installing bootstrap menu control

bootstrap menu control installed

Figure 5 – Bootstrap menu control installed

Next we need to add the script and style sheet references.

adding the scripts and style sheets

Figure 6 – Adding the scripts and style sheets

Lets clean out the Default.aspx and it’s code behind file

Default.aspx file

Figure 7 – Default.aspx file

Default.aspx.cs file

Figure 8 – Default.aspx.cs file

Now we add the menu to the Site.master

Adding the bootstrap menu mark-up

Figure 9 – Adding the bootstrap menu mark-up

Adding the bootstrap menu code behind

Figure 10 – Adding the bootstrap menu code behind

So after all that here it is the first part of our Bootstrap Dynamic Data Project Template

Working Bootstrap Menu Control

Figure 11 – Working Bootstrap Menu Control

Download

As usual you can get the code from the Project on Bootstrap Friendly Control Adaptors and on my SkyDrive

Tuesday, 27 August 2013

Bootstrap Friendly Web Controls

A big project rename after discovering that the Menu does not play well with Control Adapters and that this is not the way forward I have now renamed the project to Bootstrap Friendly Web Controls and I have added the first control which is the BootstrapMenu

bootstrap-freindly-logo

Bootstrap Friendly Web Controls is now Live on Codeplex  and NuGet

BootstrapMenu

Next I will create tutorial on using the BootstrapMenu control.

Wednesday, 21 August 2013

GridView Bootstrap Update

It would appear that issue that pushed me towards using Control Adapters to fix my issues with the GridView were “Not entirely accurate” it seems that if you do the following to the default List pages we will get the GridView to perform as we wish with Bootstrap. Scott Hunter has a post here Cleaning up Default GridView Mark-up this showed me we can clean the mark-up up fully without resorting to Control Adapters.

Default GridView Mark-Up For Dynamic Data

Figure 1 – Default GridView Mark-Up For Dynamic Data

Going back to my original post Bootstrap Friendly Dynamic Data I showed the mark-up in Figure 2 and demonstrated this caused issues with Bootstrap and other CSS styles applied to the grid.

table mark-up Issues

Figure 2- Table mark-up issues

So we change the mark-up to that in Figure 3 and then we get this nicely cleaned mark-up in Figure 4

Updated GridView Mark-Up For Dynamic Data

Figure 3 – Updated GridView Mark-Up For Dynamic Data

table mark-up fixed

Figure 4 – table mark-up fixed

GridView output with Bootstrap

Figure 5 – GridView output with Bootstrap

Hope that helps

Download

As usual you can get the code from the Project on Bootstrap Friendly Control Adaptors and on my SkyDrive

Sunday, 18 August 2013

Adding Validation Using Bootstrap Popover

I noticed an article by Damien Edwards called Updating the ASP.NET validator controls to change invalid control’s CSS class on non-JavaScript clients this got me thinking could I create an Control Adapter that would work for ALL Validators and would take advantage of the Bootstrap Tooltip or Popover JavaScript effects, Figure 1 is what I came up with.

Bootstrap Tooltip in action

Figure 1- Bootstrap Popover in action

So how did I do it, well I’m not entirely sure this is good practice, I’m using a Control Adapter to get the the Pre-Render event and then I get the the control as a BaseValidator get access to the ControlToValidate the about 30 lines of code and we have the above for any Validator.

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);

var validator = Control as BaseValidator;
var controlType = Control.GetType().ToString();
var stringType = controlType.Substring(controlType.LastIndexOf(".") + 1, controlType.Length - controlType.LastIndexOf(".") - 1);

// build unique CCS class per validator type
var validatorError = String.Format("{0}-{1}", stringType, ERROR_CLASS);
var controlToValidate = Control.NamingContainer.FindControl(validator.ControlToValidate) as WebControl;
if (controlToValidate != null)
{
if (validator.IsValid)
{
// remove validator class
var className = String.Join(" ", controlToValidate.CssClass.Split(' ').Where(c => !c.Equals(validatorError)).ToArray());
controlToValidate.CssClass = className;
}
else
{
// add validator class
if (controlToValidate.CssClass.Split(' ').FirstOrDefault(c => c.Equals(validatorError)) == null)
controlToValidate.CssClass = String.IsNullOrEmpty(controlToValidate.CssClass)
? validatorError
: String.Format("{0} {1}", controlToValidate.CssClass, validatorError);

// add tooltip
controlToValidate.Attributes.Add("data-placement", "right");
controlToValidate.Attributes.Add("data-toggle", "popover");
controlToValidate.Attributes.Add("data-trigger", "hover");
controlToValidate.Attributes.Add("data-delay", "500");

// add title
controlToValidate.Attributes.Add("data-original-title", "Error!");
//TODO: add append errors to tooltip
controlToValidate.Attributes.Add("data-content", validator.ErrorMessage);

//$(document).ready(function () { $("#test").tooltip(); });
var datePickerScript = String.Format("$(document).ready(function () {{ $('#{0}').popover(); }});\n", controlToValidate.ClientID);
Control.Page.AddStartupClientScript(controlToValidate.ClientID, datePickerScript);
}
}
}

Listing 1 – Control Adapter OnPreRender

This piece of code does it all it finds the control we are validating and then add the CSS class or removes it depending on it being valid or not.

.inner-glow (@radius: 3px, @color: #f3ffa7)
{
-webkit-box-shadow: 0 0 @radius @radius @color inset !important;
box-shadow: 0 0 @radius @radius @color inset !important;
}

.required
{
.inner-glow;
}

.RequiredFieldValidator-validation-error,
.RegularExpressionValidator-validation-error,
.CompareValidator-validation-error,
.CustomValidator-validation-error,
.RangeValidator-validation-error,
.DynamicValidator-validation-error
{
.inner-glow(2px, fadeout(#ff0000, 50%));
border: 1px solid fadeout(#ff0000, 40%) !important;
}

Listing 2 – LESS Classes

I did the the styling using LESS as it’s available readily now with Mads Kristensen’s Web Essentials for Visual Studios 2012 and 2013.

Note: I think in the long term I want to do what Damien Edwards said inn his post and create an updated Validator for each of the main validators and also do a custom Popover that can be styles independently of the Bootstrap one.

Download

As usual you can get the code from the Project on Bootstrap Friendly Control Adaptors and on my SkyDrive

Sunday, 11 August 2013

Adding Some More Bootstrap Love to the Dynamic Data Project Template

In this article I want to add some of the nice features of Bootstrap to Dynamic Data

  • Bootstrap Navbar
  • Bootstrap Date Picker

Navbar

First of all we will move the list of table from the Default Page to the Site.master and have it as a menu in the nave bar.

Navbar

Figure 1 – the Navbar

All we need for this is to move the Page_Load from the Default.ascx.cs page to the code behind of the Site.master.cs and then add the mark-up the Site.master see the two pages below:

<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="#">Dynamic Data</a>
<ul class="nav">
<li>
<asp:LinkButton ID="LinkButton1" runat="server" PostBackUrl="~/Default.aspx">Home</asp:LinkButton>
</li>
<asp:ListView ID="Menu1" runat="server">
<LayoutTemplate>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Tables&nbsp;<b class="caret"></b></a>
<ul class="dropdown-menu">
<li runat="server" id="itemPlaceholder"></li>
</ul>
</li>
</LayoutTemplate>
<ItemTemplate>
<li runat="server">
<asp:DynamicHyperLink ID="HyperLink1" runat="server"><%# Eval("DisplayName") %></asp:DynamicHyperLink>
</li>
</ItemTemplate>
</asp:ListView>
</ul>
</div>
</div>

Listing 1 – the Menu mark-up

protected void Page_Load(object sender, EventArgs e)
{
System.Collections.IList visibleTables = Global.DefaultModel.VisibleTables;
if (visibleTables.Count == 0)
{
throw new InvalidOperationException("There are no accessible tables...");
}
Menu1.DataSource = visibleTables;
Menu1.DataBind();
}

Listing 2 – the Page_Load moved to Site.master

Date Picker

Add the Bootstrap Date Picker using NuGet

Bootstrap Date Picker

Figure 2 – Bootstrap Date Picker

Then copy the DateTime and DateTime_Edit Field Templates and rename to Date and Date_Edit, then add a script and CSS references to the Site.master.

<div class="controls">
<div class="input-append date" id="DivDate" runat="server">
<div class="input-append">
<asp:TextBox
ID="TextBox1"
runat="server"
CssClass="input-small" />
<span class="add-on"><i class="icon-calendar"></i></span>
</div>
<asp:RequiredFieldValidator
runat="server"
ID="RequiredFieldValidator1"
CssClass=""
ControlToValidate="TextBox1"
Display="Static"
Enabled="false"/>
<asp:RegularExpressionValidator
runat="server"
ID="RegularExpressionValidator1"
CssClass=""
ControlToValidate="TextBox1"
Display="Static"
Enabled="false"/>
<asp:DynamicValidator
runat="server"
ID="DynamicValidator1"
CssClass=""
ControlToValidate="TextBox1"
Display="Static"/>
<asp:CustomValidator
runat="server"
ID="DateValidator"
CssClass=""
ControlToValidate="TextBox1"
Display="Static"
EnableClientScript="false"
Enabled="false"
OnServerValidate="DateValidator_ServerValidate"/>
</div>
</div>

Listing 3 – Date_Edit.ascs mark-up

// get default display format
var dateFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;

// create script
var datePickerScript = String.Format("$('#{0}').datepicker();", DivDate.ClientID);
Page.AddStartupClientScript(String.Format("{0}{1}BootstrapDatePicker", Table.Name, Column.Name), datePickerScript);

DivDate.Attributes.Add("data-date-format", dateFormat.ToLower());
TextBox1.Attributes.Add("placeholder", dateFormat);
TextBox1.ToolTip = Column.Description;

TextBox1.Columns = DateTime.Now.ToString(dateFormat).Length;

Listing 3 – Date_Edit.ascx.cs

Listings 2 & 3 show the necessary code to create the Date Field Templates

Bootstrap Date Picker in Action

Figure 3 – Bootstrap Date Picker in Action

The Project is on Bootstrap Friendly Control Adaptors and on my SkyDrive

Converting the Dynamic Data Project Template to Bootstrap

Next we will convert the rest of the standard Dynamic Data Project Templates to Bootstrap, this will required the us to deal with the following parts of Dynamic Data’s components.

  • Page & Entity Templates (Details, Edit & Insert)
  • Field Templates
  • Filters
  • Validation

Page and Entity Templates

If we look at the Edit page Figure 1 rendered you can see it has been rendered using a table

EditTemplate

Figure 1 – Edit Template (with border turned on)

If we look at the mark-up we can see what we have to deal with, the FormView Edit template (Figure 2) it contains a Table with some cell padding next look at the Entity Template mark-up (Figure 3) we see each item will be rendered as a table row with the first cell having the label and the second having the field.

Edit Template mark-up

Figure 2 - Edit Template mark-up

Edit Entity Template mark-up

Figure 3 – Edit Entity Template mark-up

If we look at the Bootstrap Forms we see that forms have a layout that looks like similar to the output of the default templates the Horizontal Form this is what we will go for.

Edit Template mark-up Bootstrappified

Figure 4 – Edit Template mark-up Bootstrapified

Edit Entity Template mark-up Bootstrappified

Figure 5 – Edit Entity Template mark-up Bootstrapified

If you look at Figures 4 & 5 you can see all I have done is add the example mark-up in place of the table mark-up and you can see from Figure 6 that it has made the edit template look a little more like the Bootstrap Form. 

Note: you will need to do this in the Details, Edit and Insert Page Templates and in the three Default Entity Templates.

Edit Template Post Bootstrapifing

Figure 6 - Edit Template Post Bootstrapifing

To complete the transformation we will need to look at ALL the field templates.

Field Templates

Since Each field template is made up of other controls we will need to make sure the mark-up for each is configured to the Bootstrap mark-up. Take a look at the (Figure 7) Text_Edit Field Template.

Text_Edit Field Template

Figure 7 – Text_Edit Field Template

What we see here is typical of all Edit Field Templates we have the field control followed by the Validators since these exist in the page as spans so they need to be encapsulated otherwise they will push the format around and mess it up.

Validators Presence In mark-up

Figure 8 – Validators Presence In mark-up

ValidatorsPresenceMarkUp

Figure 9 – Validators Presence mark-up

As it turns out this is quite simple though long winded see Figure 10 this excerpt from the Bootstrap Forms (2.3.2) documentation.

Horizontal-Form

Figure 10 – Horizontal Form

Bootstrapified Edit Template With Field Templates

Figure 11 – Bootstrapified Edit Template with Field Templates

You can see from Figure 11 that adding the DIV with the controls class sorts the layout out nicely.

Updated: that the Details page template displays the field text out of line add the read-only-field to the div that surrounds all field templates to fix this. 
ReadOnlyCssClass ReadOnlyFields
 

Filters & Validation

I will tackle Filters and Validation together.

Validation & Filters in List Page Template

Figure 12 – Validation & Filters in List Page Template

To make the Validation show well with Bootstrap we need to look at the Alerts in Bootstrap, we will replace “DDValidator” class with the “alert alert-error” in all pages see Figure 13

Replace DDValidator with alerts

Figure 13 – Replace DDValidator with alerts

Then we remove the DIV from around the Validators and Filters see Figure 14 for the details, this ends up looking like this:

UpdatedValidationAndFilters

Figure 14 – Filters

And if we cause the validators to show, we now get a Bootstrap alert to show our errors.

ValidatorsShowing

Figure 15 – Validators showing

Next up adding a Menu and Navbar to the site.

The Project is on Bootstrap Friendly Control Adaptors and on my SkyDrive