tag:blogger.com,1999:blog-69078738034037379792024-03-05T04:44:56.071+00:00C# BitsASP.Net, Dynamic Data and c# stuff: Focused on what new and cool, code tutorials and useful tricks and tips on getting the most out of ASP.Net. All in C#Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.comBlogger174125tag:blogger.com,1999:blog-6907873803403737979.post-56495040426667937572018-05-25T15:48:00.001+01:002018-05-25T15:49:56.781+01:00Blazoring a New Path<p>I’ve been looking for a successor to Web Forms for a long while now and for the last 12 to 18 months I’ve looked at various thing mainly AngularJS and Angular. but in the back ground I’ve been keeping an eye on Steve Sanderson’s baby Blazor. The first time I saw it was on YouTube as a concept in his his NDC video <a href="https://www.youtube.com/watch?v=F3GwkMI6XrM" target="_blank">Web Apps can’t really do *that*, can they? - Steve Sanderson</a> in August 2017 and then again in January 2018 with the same sort of thing <a href="https://www.youtube.com/watch?v=9G8HEDI3K6s" target="_blank">Web Apps can’t really do *that*, can they? - Steve Sanderson</a> it was the bit about Web Assembly that caught my eye, the possibility of running .Net in the browser. We had Silverlight but that was a plug-in and is dead for all intents and purposes. but this is different from that it’s the .Net Standard running in the browser running on the <a href="http://www.mono-project.com/news/2017/08/09/hello-webassembly/" target="_blank">Mono</a> implementation.</p><p>And so I became a follower always checking where it was up to and now it’s in preview <a href="https://blogs.msdn.microsoft.com/webdev/2018/05/02/blazor-0-3-0-experimental-release-now-available/">Blazor 0.3.0 experimental release now available</a> and on GitHub here <a href="https://github.com/aspnet/Blazor" target="_blank">aspnet/Blazor</a>.</p><p>So here we are first I think I am going to need to learn the basics of Blazor and I hope you’ll come along for the ride. So as <a href="https://github.com/aspnet/Blazor" target="_blank">Blazor</a> move forward I will be also and I will be creating bits for Blazor and writing it all up here.</p><p><img style="border-image: none;" src="https://i.ytimg.com/vi/52r5Ow3I3Rg/hqdefault.jpg"></p><p>Going forward I believe this could be the new Web Forms but done right.</p>Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-65890485533600690662015-09-10T16:55:00.001+01:002021-01-19T16:01:33.855+00:00Automatic Totals on your List page in Dynamic Data<p><span style="font-variant: small-caps"></span>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. <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: gray 1px dotted; margin: 4px; padding-right: 4px; background-color: #ffffcc"><strong>Note: </strong>Note this will only work on Numeric columns int, Decimal, float etc.</div> <p><strong>Figure 1</strong> 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 <strong>int</strong> values.</p> <p><a href="http://lh3.googleusercontent.com/-kYvCzRxWVPs/VfGnz4N-B-I/AAAAAAAADew/ho2yUQfv9rk/s1600-h/finished-page4.jpg"><img title="finished-page" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="finished-page" src="http://lh3.googleusercontent.com/-QRD-bKR-SZQ/VfGn0vqytvI/AAAAAAAADe0/X6VWiL38hfk/finished-page_thumb2.jpg?imgmax=800" width="692" height="644"></a></p> <p><strong>Figure 1 – Footer row with totals.</strong></p> <h3>The Attribute</h3> <p>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 <strong>Listing 1</strong>.</p><pre class="brush: csharp;">[AttributeUsage(AttributeTargets.Class)]<br>public class TotalsAttribute : Attribute<br>{<br> public String[] Columns { get; set; }<br><br> public TotalsAttribute() <br> { <br> Columns = new String[0];<br> }<br><br> public TotalsAttribute(params String[] columns)<br> {<br> Columns = columns;<br> }<br>}
</pre>
<p><strong>Listing 1 – TotalsAttribute</strong></p>
<p>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.</p><pre class="brush: csharp;">[Totals("UnitPrice", "UnitsInStock", "UnitsOnOrder")]<br>[MetadataType(typeof(Product.Metadata))]<br>public partial class Product<br>{<br> internal sealed class Metadata<br> {<br> public Int32 ProductID { get; set; }<br><br> public String ProductName { get; set; }<br><br> [DataType(DataType.Currency)]<br> public Nullable<int> UnitPrice { get; set; }<br><br> public Nullable<int> UnitsInStock { get; set; }<br><br> //... other column removed for simplicity<br> }<br>}
</pre>
<p><strong>Listing 2 – example of attribute in use.</strong></p>
<p>In the example <strong>[Totals("UnitPrice", "UnitsInStock", "UnitsOnOrder")]</strong> in <strong>Listing 2</strong> we are telling the system that we want totals on three columns “UnitPrice”, “UnitsInStock”, “UnitsOnOrder”.</p>
<h3>The Custom Code in the List page</h3>
<p>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 <strong>Listing 3</strong> 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 <strong>Listing 4.</strong> </p>
<p>In <strong>Listing 3</strong> 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.
<div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #ff0000; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: gray 1px dotted; margin: 4px; padding-right: 4px; background-color: #ffdddd"><strong>!Important: </strong>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 <font face="Courier New"><strong>GridView1.ShowFooter = true;</strong></font></div>
<div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: gray 1px dotted; margin: 4px; padding-right: 4px; background-color: #ffffcc"><strong>Note: </strong>I am using some custom extension methods to get the attribute, these are in the root of the application and the file is called <strong>“AttributeExtensionMethods.cs”</strong></div><pre class="brush: csharp;">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
</pre>
<p><strong>Listing 3 – testing if we have any totals for this table.</strong></p>
<p>Now all we need the workhorse code the stuff that is going to total up and then display the totals in the footer. See <strong>Listing 4</strong> I have tried to put a lot of comments in there to help but here’s a brief explanation of what it does:</p>
<p>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.</p>
<p><strong>The DataRow</strong></p>
<p>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 <strong>int</strong> or an <strong>floating point</strong> this stops us having a nasty error.</p><pre class="brush: csharp;">// 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";
}
}
}
}</pre>
<p><strong>Listing 4 – OnRowDataBound event handler and global totals variable.</strong></p>
<p>Finally the second section the <strong>Footer</strong> we we simply render the totals to the footer
<div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: gray 1px dotted; margin: 4px; padding-right: 4px; background-color: #ffffcc"><strong>Note: T</strong>he <strong>plus 1</strong> I am adding to the index, is to account for the Command column with the Edit buttons etc.</div>
<h3>Sample Code</h3><iframe height="120" src="https://onedrive.live.com/embed?cid=96845E7B0FAC1EED&resid=96845E7B0FAC1EED%21111362&authkey=ANRicDEesj8_Sa4" frameborder="0" width="98" scrolling="no"></iframe> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-40018483528791265962015-08-17T10:48:00.001+01:002015-08-17T10:48:49.869+01:00Useful Links for Windows 10 and Universal Windows Platform Apps<ul> <li>Links to <a href="https://www.visualstudio.com/?Wt.mc_id=DX_MVP4024743" target="_blank">Developer Tools Download</a> </li> <li><a href="https://dev.windows.com/en-us/getstarted/whats-new-windows-10/?Wt.mc_ic=dx_MVP4024743" target="_blank">What’s New for Developers in Windows 10</a></li> <li><a href="https://dev.windows.com/en-us/getstarted/?Wt.mc_ic=dx_MVP4024743" target="_blank">Get Started with Windows 10 Universal apps</a></li> <li><a href="https://dev.windows.com/en-us/design/?Wt.mc_ic=dx_MVP4024743" target="_blank">Designing Universal Windows Platform Apps</a> </li> <li><a href="https://dev.windows.com/en-us/develop/?Wt.mc_ic=dx_MVP4024743" target="_blank">Developing Universal Windows Platform Apps</a> </li> <li><a href="https://dev.windows.com/en-us/publish/?Wt.mc_ic=dx_MVP4024743" target="_blank">Publishing your Universal Windows Platform Apps</a></li> <li><a href="https://www.microsoftvirtualacademy.com/en-US/training-courses/getting-started-with-windows-10-for-it-professionals-10629/?Wt.mc_ic=dx_MVP4024743" target="_blank">training for Universal Windows Platform Apps (Windows 10 courses in MVA)</a></li> <li><a href="https://channel9.msdn.com/windows/?Wt.mc_ic=dx_MVP4024743" target="_blank">See Channel 9 for loads of videos on developing Universal Windows Platform Apps</a></li></ul> <p>I have put these links here to make it easy to find what you need to develop Universal Windows Platform Apps. </p> <p>I can’t wait until we can have the same app on Phone PC and XBox one <img class="wlEmoticon wlEmoticon-openmouthedsmile" style="border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none" alt="Open-mouthed smile" src="http://lh3.googleusercontent.com/-qdkDg1e-xFM/VdGt_9jks4I/AAAAAAAADec/8gC_pPPW1r4/wlEmoticon-openmouthedsmile%25255B2%25255D.png?imgmax=800"></p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-90933653827474476702015-06-02T22:29:00.001+01:002015-06-02T22:29:30.235+01:00Asp.Net Identity for Web Forms Introduction<p>I am starting a new series on the new <a href="http://www.asp.net/identity" target="_blank">Asp.Net Identity</a> 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.</p> <p>I am using Visual Studio 2013 Ultimate, remember <a href="http://msdn.microsoft.com/en-us/visual-studio-community-vs.aspx" target="_blank">Visual Studio 2013 Community</a> 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 <a href="http://channel9.msdn.com/Events/Visual-Studio/Connect-event-2014">Connect(); Microsoft Visual Studio vNext & Azure</a> on <a href="http://channel9.msdn.com" target="_blank">Channel9</a>.</p> <h3>Overview of the new Project Templates</h3> <p>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.</p> <p><a href="http://lh3.googleusercontent.com/-m5aPjB_Daqw/VW4gB122h7I/AAAAAAAADYg/pB0XxT0N8bA/s1600-h/web-forms-dot-net-4-web-application6.png" target="_blank"><img title="web-forms-dot-net-4-web-application" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="web-forms-dot-net-4-web-application" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj52tr1yWSwQdH2em7MhlMArzFRk3YlGDEFn4ucvU29qNDSAORVILt9BnWoCspDRxpLhxc0Y4lYMsdAcO_UM-w3qwutVF0rm122rF2joIWiG8jXPanR5S_NlmINyXMi-olH48WnQeneW90/?imgmax=800" width="415" height="228"></a></p> <p>Add new project template here for comparison.</p> <p><strong>Figure 1 – .Net 4 Web Application Project</strong></p> <p>Now we need to select the project template with a .Net framework of 4.5 as a minimum.</p> <p><a href="http://lh3.googleusercontent.com/-GO2a2jqGazs/VW4gDHiJHKI/AAAAAAAADYw/VQmfoPkafhE/s1600-h/selecting-the-project-template6.png" target="_blank"><img title="selecting-the-project-template" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="selecting-the-project-template" src="http://lh3.googleusercontent.com/-DO4zmV2IRhw/VW4gEPJQIxI/AAAAAAAADY0/OrIXbL8G6Ts/selecting-the-project-template_thumb.png?imgmax=800" width="640" height="447"></a></p> <p><strong>Figure 2 – Selecting the project template</strong></p> <p><a href="http://lh3.googleusercontent.com/-Q5dmEmTht4o/VW4gEgh8S3I/AAAAAAAADY8/dd3o0SN3hgU/s1600-h/one-asp-net-dialog5.png" target="_blank"><img title="one-asp-net-dialog" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="one-asp-net-dialog" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqXUF9DzTLOy2GTPIXhv46HbpB75R0x230919Cpv1iL2ry58dFGflWZeEeOHKh6NhDtbL8Tlp8xq56NduQ-IFrKEY3NHS6NrFec7Qcj5-X1IZsFpCNL7IYTFEYy795TiKZgpVqSr8FQMk/?imgmax=800" width="635" height="480"></a></p> <p><strong>Figure 3 – The One Asp.Net dialog</strong></p> <p>You will get the One Asp.net dialog from this you can change the the authentication type.</p> <p><a href="http://lh3.googleusercontent.com/-zsKSMxsv654/VW4gGLn9UoI/AAAAAAAADZM/SwJoGXZcVEw/s1600-h/change-authentication-dialog5.png"><img title="change-authentication-dialog" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="change-authentication-dialog" src="http://lh3.googleusercontent.com/-knBhGzQlak0/VW4gG6vqhkI/AAAAAAAADZU/_bF1vn9CAm8/change-authentication-dialog_thumb3.png?imgmax=800" width="640" height="291"></a></p> <p><strong>Figure 4 – Change Authentication dialog</strong></p> <p>Let’s examine the four options offered here:</p> <h4></h4> <h4>No Authentication</h4> <p>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.</p> <p><a href="http://lh3.googleusercontent.com/-h7RCK1FtA4c/VW4gHGjpbuI/AAAAAAAADZc/W_YsG9l2218/s1600-h/change-authentication-dialog-option-%25255B11%25255D.png" target="_blank"><img title="change-authentication-dialog-option-2" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="change-authentication-dialog-option-2" src="http://lh3.googleusercontent.com/-vo6hERW7GHo/VW4gHvv1T7I/AAAAAAAADZk/F_PCcaUByYI/change-authentication-dialog-option-%25255B2%25255D.png?imgmax=800" width="640" height="291"></a></p> <p><strong>Figure 5 – Option 1</strong></p> <h4>Individual User Accounts</h4> <p>This option is equivalent to the old Membership system default, </p> <p><a href="http://lh3.googleusercontent.com/-vyZP_KPM8DU/VW4gIBcGcnI/AAAAAAAADZs/WHZ9T12_Q70/s1600-h/change-authentication-dialog-option-%25255B12%25255D.png" target="_blank"><img title="change-authentication-dialog-option-1" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="change-authentication-dialog-option-1" src="http://lh3.googleusercontent.com/-8Ry-kpqqt1Q/VW4gIsThbpI/AAAAAAAADZ0/E2AF9jvuCds/change-authentication-dialog-option-%25255B8%25255D.png?imgmax=800" width="640" height="291"></a></p> <p><strong>Figure 6 – Option 2</strong></p> <h4>Organizational Accounts</h4> <p>This is an area of big improvement over the old Membership system allowing us greater flexibility, all these options are using some form of <a href="http://technet.microsoft.com/en-us/library/hh831502.aspx" target="_blank">Active Directory Federation Services Overview</a> 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.</p> <p><a href="http://lh3.googleusercontent.com/-u3cOMUgJpSo/VW4gJI2L1XI/AAAAAAAADZ8/Mo7XHyqNGzI/s1600-h/change-authentication-dialog-option-%25255B14%25255D.png" target="_blank"><img title="change-authentication-dialog-option-3a" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="change-authentication-dialog-option-3a" src="http://lh3.googleusercontent.com/-IDMNS628vkI/VW4gJ1Uv-6I/AAAAAAAADaE/XT4Mzy4A0rQ/change-authentication-dialog-option-%25255B9%25255D.png?imgmax=800" width="640" height="312"></a></p> <p><strong>Figure 7 – Option 3</strong></p> <p><a href="http://lh3.googleusercontent.com/-n446GEfGjC0/VW4gKQPzTZI/AAAAAAAADaM/BC4LSEu5UJo/s1600-h/change-authentication-dialog-option-%25255B5%25255D.png" target="_blank"><img title="change-authentication-dialog-option-3b" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="change-authentication-dialog-option-3b" src="http://lh3.googleusercontent.com/-uY1mHCa79k0/VW4gLOTLwzI/AAAAAAAADaY/s4toJLKeSBE/change-authentication-dialog-option-%25255B7%25255D.png?imgmax=800" width="640" height="372"></a></p> <p><strong>Figure 8 – More Options </strong></p> <ol> <li>Choose this option to connect to your Microsoft Azure Active Directory tenet. <li>Enter the domain name of you Microsoft Azure Active Directory tenet. <li>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. <li>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.)</li></ol> <p><a href="http://lh3.googleusercontent.com/-rjdbCjJ-CaI/VW4gL40Hj3I/AAAAAAAADac/r1K06jC2dC8/s1600-h/change-authentication-dialog-option-%25255B13%25255D.png" target="_blank"><img title="change-authentication-dialog-option-3c" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="change-authentication-dialog-option-3c" src="http://lh3.googleusercontent.com/-tapq1Z9YdNk/VW4gMV5TZ0I/AAAAAAAADak/01Q6ytIYZHY/change-authentication-dialog-option-%25255B3%25255D.png?imgmax=800" width="640" height="292"></a></p> <p><strong>Figure 9 – On-Premises option for Active Directory</strong></p> <ol> <li>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. <li>The metadata document contains the coordinates of the authority. Your application will use those coordinates to drive the web sign on flow. <li>Provide a unique URI that Windows Server Active Directory can use to identify this app.</li></ol> <h4>Windows Authentication</h4> <p>This is the same as the original Windows Authentication, in fact if you look at <strong>Figure 11</strong> you can see the changes to the web.config are the same as the always have been for “Windows Authentication”.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9gtH5i4sE-dOmWtLMaprGrJFV73uQK50t7KE92JZre-XleWqUZZT6F-S34qF5LqIzLXoIvFSav4DzlQY35isDsW5e2wQJLUSk0Zfq8fc1suIr0xmKKRLTnZLEpAdvzo-53F3u807m8uw/s1600-h/change-authentication-dialog-option-%25255B4%25255D.png" target="_blank"><img title="change-authentication-dialog-option-4" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="change-authentication-dialog-option-4" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL9Ysm2C6_QY5QShEh5CVS91_BdIb0opyffYLURFiKYKjROos8NEYj1bOmp6BpKxy7wnpm3ouORpSfj8sKfv1w7gTC-JzFr_EEH_HvSMq7fFQJAN0KKEdPnNOlLZifoqnHbLCZUikwiBc/?imgmax=800" width="640" height="291"></a></p> <p><strong>Figure 10 – Option 4</strong></p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyX_EkeQLyE1nQG2MOrA_SgQE0EqELgcc98zKbkHpRwc-k_g6IuE132Uk_h68vl-4X30ai1o8h8TpB9bOIErSmPngKFNHgo3qhBMeHR4MDbBMgdxzT0vSLUt98fJp1LfX7gKeOMZ_M3gg/s1600-h/option-4-web-config7.png" target="_blank"><img title="option-4-web-config" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="option-4-web-config" src="http://lh3.googleusercontent.com/-WshaR1IkTKE/VW4gOCswPSI/AAAAAAAADbE/bsgLQpCoDhs/option-4-web-config_thumb5.png?imgmax=800" width="650" height="231"></a></p> <p><strong>Figure 11 – web.config authentication changes</strong></p> <p>So that’s the introduction done next we will be adding Identity to a existing WebForms application.</p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com2tag:blogger.com,1999:blog-6907873803403737979.post-59437985088171056802015-04-17T10:31:00.001+01:002015-04-17T10:31:40.369+01:00Register to attend the Microsoft MVP Virtual Conference<p>Hi All – I wanted to let you know about a great free event that Microsoft and the MVPs are putting on, May 14<sup>th</sup> & 15<sup>th</sup>. Join Microsoft MVPs from the Americas’ region as they share their knowledge and real-world expertise during a free event, the <a href="http://mvp.microsoft.com/en-us/virtualconference.aspx">MVP Virtual Conference</a>. <p>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, <a href="http://blogs.msdn.com/b/stevengu/archive/2015/04/02/announcing-the-mvp-virtual-conference.aspx">Steve Guggenheimer</a>, will be on hand to deliver the opening Key Note Address. <p>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! <p>Be sure to <a href="http://mvp.microsoft.com/en-us/virtualconference.aspx">register</a> quickly to hold your spot and tell your friends & colleagues. <p>The conference will be widely covered on social media, you can join the conversation by following <a href="https://twitter.com/MVPAward">@MVPAward</a> and using the hashtag #MVPvConf. <p>Register now and feel the power of community! <p><a href="http://mvp.microsoft.com/en-us/virtualconference.aspx" target="_blank"><img title="clip_image001" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="clip_image001" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixREqlPCVx_g6D7Xjt8CTlh5UI8OZlxlD0cm38TmCnsG-M-68PBdOy5rozQwRFBRKk-0xM2vOnEykjiW2iZuyyiZE9cUTHjDGQaSFb-a6IZ_ptoBWmJFeiw_TXvjY4wA26AM3vsuX40GA/?imgmax=800" width="192" height="84"></a> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-35919477528401150742014-11-17T00:55:00.001+00:002014-11-17T00:55:46.354+00:00Updated my Alternating Line Color Visual Studio Extension<p>I have just updated my <a href="https://visualstudiogallery.msdn.microsoft.com/5e0c81c8-4e71-450f-82aa-c9e8731b80f0" target="_blank">Alternating Line Visual Studio Extension</a> to support Visual Studio 2015 Preview. have fun <img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="Smile" src="http://lh4.ggpht.com/-MtcSPmTlHH0/VGlHjfYNwhI/AAAAAAAADWo/9ZK-xIVMtAg/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"></p> <p><a href="http://lh5.ggpht.com/-LXJB8HlleA8/VGlHj_zsGAI/AAAAAAAADWs/LUsOfaCZcBM/s1600-h/vsix_AlternatingLineColorTextAdornment_large%25255B3%25255D.png"><img title="vsix_AlternatingLineColorTextAdornment_large" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="vsix_AlternatingLineColorTextAdornment_large" src="http://lh3.ggpht.com/-hF-g0rtICiM/VGlHkXAMAcI/AAAAAAAADW0/Q9De6ufINs4/vsix_AlternatingLineColorTextAdornment_large_thumb%25255B1%25255D.png?imgmax=800" width="204" height="204"></a></p> <p>It does what is says on the time adds those alternating lines to the code editor.</p> <p>Coming soon adding custom color so you can customise it for the other themes.</p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-40849066012215371442014-10-09T22:36:00.001+01:002014-11-03T21:46:20.355+00:00Just Updated “NotAClue Bootstrap Friendly WebForms Controls”I have just updated my <a href="https://www.nuget.org/packages/NotAClue.Web.UI.BootstrapWebControls/" target="_blank">NotAClue Bootstrap Friendly WebForms Controls</a> to version 0.1.4 you can find the source code on <a href="http://github.com/" target="_blank">GitHub</a> here <a title="https://github.com/sjnaughton1961/bootstrap-web-controls" href="https://github.com/NotAClue/bootstrap-web-controls" target="_blank">Bootstrap Web Controls</a><br>I have added a <strong>Bootstrap Tabs</strong> control to enable the use of bootstrap tabs in a web forms application and support for Bootstrap 3.x<br><a href="http://lh3.ggpht.com/-uxLE1oXYMuo/VDb_vKNcdXI/AAAAAAAADV0/JdU3uKwOb3Y/s1600-h/bootstrap-tabs-in-action%25255B4%25255D.png"><img title="bootstrap-tabs-in-action" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="bootstrap-tabs-in-action" src="http://lh3.ggpht.com/-3emXCoNzbFk/VDb_v7kRYjI/AAAAAAAADV4/Tu2-v3vOc28/bootstrap-tabs-in-action_thumb%25255B2%25255D.png?imgmax=800" width="793" height="463"></a><br><strong>Figure 1 – note here there are two sets of Tabs and each remembers it’s own currently selected tab</strong><br>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.<br>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).<br> <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: purple; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #f0d0f0"><strong>Updated: </strong>version 0.1.5 now has a dependency on jQuery.cookie to remember the selected tab before postback</div> <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: purple; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #f0d0f0"><strong>Updated: </strong>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) </div>More posts to come around Bootstrap and Dynamic Data. Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-45872857090202214712014-01-31T08:10:00.001+00:002014-01-31T08:10:12.104+00:00Microsoft announce a Preview of Dynamic Data provider and EntityDataSource control for Entity Framework 6<p>See <a href="http://blogs.msdn.com/b/webdev/archive/2014/01/30/announcing-preview-of-dynamic-data-provider-and-entitydatasource-control-for-entity-framework-6.aspx">Announcing preview of Dynamic Data provider and EntityDataSource control for Entity Framework 6</a> for full details</p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-15264112012920378052014-01-09T14:45:00.001+00:002014-01-09T14:45:54.506+00:00Dynamic Data videos on ASP.Net Learn site<p>Hi all there are 17 videos on the <a href="http://www.asp.net" target="_blank">ASP.Net</a> site under the <a href="http://www.asp.net/web-forms/videos/how-do-i" target="_blank">How Do I?</a> Videos, A lot of them are a bit dated using VS2008 and .Net 3.51 but most of the principals are still good.</p> <p><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data">ASP.NET Dynamic Data</a></p> <ol> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/your-first-scaffold-and-what-is-dynamic-data" target="_blank">Your First Scaffold and What is Dynamic Data</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/how-do-i-enable-inline-gridview-editing" target="_blank">Enable Inline GridView Editing</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/how-do-i-change-how-my-fields-render" target="_blank">Change how my Fields render</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/how-do-i-handle-business-logic-exceptions" target="_blank">Handle Business Logic Exceptions</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/how-do-i-make-custom-pages" target="_blank">Make Custom Pages</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/how-do-i-display-unknown-datatypes" target="_blank">Display Unknown datatypes</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/how-do-i-use-a-dynamiccontrol-in-listview-and-detailsview-controls" target="_blank">Use a DynamicControl in ListView and DetailsView Controls</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/getting-started-with-dynamic-data" target="_blank">Getting Started with Dynamic Data</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/begin-editing-the-templates-in-aspnet-dynamic-data-applications" target="_blank">Begin Editing the Templates in ASP.NET Dynamic Data Applications</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/begin-modifying-dynamic-data-applications-with-url-routing" target="_blank">Begin Modifying Dynamic Data Applications with URL Routing</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/enable-in-line-editing-in-aspnet-dynamic-data-applications" target="_blank">Enable In-Line Editing in ASP.NET Dynamic Data Applications</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/how-to-enable-table-specific-routing-in-dynamic-data-applications" target="_blank">Enable Table Specific Routing in Dynamic Data Applications</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/how-to-use-attribute-validation-in-aspnet-dynamic-data-applications" target="_blank">Use Attribute Validation in ASP.NET Dynamic Data Applications</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/how-to-implement-custom-field-validation-with-imperative-logic-in-vb-or-c" target="_blank">Implement Custom Field Validation with Imperative Logic in VB or C#</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/how-to-remove-columns-from-your-dynamicdata-data-grids" target="_blank">Remove Columns From Your DynamicData Data Grids</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/how-to-create-table-specific-custom-forms-in-an-aspnet-dynamic-data-application" target="_blank">Create Table Specific Custom Forms in an ASP.NET Dynamic Data Application</a></li> <li><a href="http://www.asp.net/web-forms/videos/aspnet-dynamic-data/aspnet-dynamic-data-custom-form-formatting" target="_blank">ASP.NET Dynamic Data Custom Form Formatting</a></li></ol> <p>Enjoy <img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="Smile" src="http://lh5.ggpht.com/-3LyXxUdm_jo/Us62H08jQiI/AAAAAAAADTA/cgegM7h-5BE/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"></p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com1tag:blogger.com,1999:blog-6907873803403737979.post-71470340613630196882013-12-30T19:28:00.001+00:002013-12-30T19:28:20.276+00:00Bootstrap Friendly Dynamic Data Project Template Goes Live<p>Today I finished my Bootstrap Friendly Dynamic Data Project Template you can find the source up on <a href="https://github.com/" target="_blank">GitHub</a> and the Project Template on <a href="http://visualstudiogallery.msdn.microsoft.com" target="_blank">Visual Studio Gallery</a> </p> <ul> <li>On the Gallery <a href="http://visualstudiogallery.msdn.microsoft.com/a89704a4-85e5-4cf2-ad27-c06770d00e59" target="_blank">Bootstrap Friendly Dynamic Data Project Template</a></li> <li>On GitHub <a href="https://github.com/sjnaughton/bootstrap-friendly-dynamic-data" target="_blank">Bootstrap Friendly Dynamic Data</a></li></ul> <p>There will be more to come with many addition already on <a href="http://NuGet.org" target="_blank">NuGet</a> that just need minor tweaks to make them Bootstrap compatible and much much more.</p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com7tag:blogger.com,1999:blog-6907873803403737979.post-50114693988767846212013-12-22T16:43:00.001+00:002013-12-22T16:43:24.838+00:00Moving My Source Code to GitHub<p>This is just a note to let fans know I am moving my source code to <a href="https://github.com/" target="_blank">GitHub</a> this is not because I don’t love <a href="http://www.codeplex.com/" target="_blank">Codeplex</a> 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.</p> <p>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.</p> <p>See you there.</p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-37374744417148245252013-08-29T17:25:00.001+01:002013-08-29T21:31:08.764+01:00CheckBox and CheckboxList that look like Bootstrap buttons-checkbox<p>I really Like Bootstrap and I had the need for the <a href="http://getbootstrap.com" target="_blank">Bootstrap</a> <a href="http://getbootstrap.com/2.3.2/javascript.html#buttons" target="_blank">buttons-checkbox</a> see <strong>Figure 1</strong> below but not being a client side genius <img class="wlEmoticon wlEmoticon-smilewithtongueout" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="Smile with tongue out" src="http://lh6.ggpht.com/-s8SmOpHoFc8/Uh92AzODKxI/AAAAAAAADPQ/QxnETbS5Lq4/wlEmoticon-smilewithtongueout%25255B2%25255D.png?imgmax=800"> 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. <strong>Checkbox</strong> for Checkbox and <strong>Radio button</strong> for Radio button) So I looked around and found this article here <a href="http://css-tricks.com/the-checkbox-hack/" target="_blank">Stuff you can do with the “Checkbox Hack”</a> and I thought I can make that work for me <img class="wlEmoticon wlEmoticon-ninja" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="Ninja" src="http://lh3.ggpht.com/-RjqjueUjRwc/Uh92Bdz2iHI/AAAAAAAADPY/9a1FZgJKvF8/wlEmoticon-ninja%25255B2%25255D.png?imgmax=800"></p> <p><img title="Bootstrap buttons-checkbox" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Bootstrap buttons-checkbox" src="http://lh6.ggpht.com/-fbRgq_M-Y5k/Uh92COdeQKI/AAAAAAAADPg/CCTyey8Cfvo/bootstrap-buttons-checkbox%25255B4%25255D.png?imgmax=800" width="222" height="80"></p> <p><strong>Figure 1 – Bootstrap buttons-checkbox</strong></p> <p>So I made my own CSS (in LESS of course until I can get SASS) so here is the LESS source</p><pre class="brush: css;">// checkbox and rtadio button styles<br>.checkbox-buttons<br>{<br> // hide the checkbox/radio button<br> input[type=checkbox],<br> input[type=radio]<br> {<br> // hide checkbox<br> display: none;<br> }<br><br> // Default State<br> label<br> {<br> display: inline-block;<br> *display: inline;<br> padding: 6px 12px;<br> margin-bottom: 0;<br> *margin-left: .3em;<br> font-size: 14px;<br> line-height: 20px;<br> color: #7c7c7c;<br> text-align: center;<br> -webkit-text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);<br> text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);<br> vertical-align: middle;<br> cursor: pointer;<br> background-color: #f5f5f5;<br> *background-color: #e6e6e6;<br> background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);<br> background-repeat: repeat-x;<br> border: 1px solid #cccccc;<br> *border: 0;<br> border-color: #e6e6e6 #e6e6e6 #bfbfbf;<br> border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);<br> border-bottom-color: #b3b3b3;<br> -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);<br> box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);<br> font-weight: bolder;<br> }<br> // Toggled State<br> input[type=checkbox]:checked + label,<br> input[type=radio]:checked + label<br> {<br> color: #333333;<br> background: rgb(74, 238, 48);<br> *background-color: rgb(112, 255, 124);<br> //background: linear-gradient(top, #1e5799 0%, #7db9e8 100%);<br> //background: linear-gradient(to bottom, rgb(112, 255, 124), rgb(4, 212, 21));<br> -webkit-text-shadow: 0px 0px 6px rgba(255, 255, 255, 0.9);<br> text-shadow: 0px 0px 6px rgba(255, 255, 255, 0.9);<br> }<br> // Mouse over State<br> input[type=checkbox]:hover + label,<br> input[type=radio]:hover + label<br> {<br> -webkit-box-shadow: inset 2px 3px 2px #cccccc, 0 1px 6px rgba(255, 255, 255, 0.2);<br> box-shadow: inset 2px 3px 2px #cccccc, 0 1px 6px rgba(255, 255, 255, 0.2);<br> }<br>}<br><br>.with-border-radius<br>{<br> & > label:first-of-type<br> {<br> border-top-left-radius: 6px;<br> border-bottom-left-radius: 6px;<br> }<br><br> & > label:last-of-type<br> {<br> border-top-right-radius: 6px;<br> border-bottom-right-radius: 6px;<br> }<br>}<br><br>
</pre>
<p><strong>Listing 1 - checkbox-buttons and with-border-radius classes</strong></p>
<p>So I have put it on <a href="http://NuGey.org" target="_blank">NuGet</a> here</p>
<p><a href="http://www.nuget.org/packages/NotAClue.Checkbox.Css.Buttons/" target="_blank"><img title="Bootstrap buttons checkbox and radio buttons nuget package" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Bootstrap buttons checkbox and radio buttons nuget package" src="http://lh5.ggpht.com/-CqlyFdKdJgA/Uh92CtTfs4I/AAAAAAAADPk/EJPYqrIhNQc/bootstrap-buttons-checkbox-nuget-package%25255B7%25255D.png?imgmax=800" width="463" height="139"></a></p>
<p><strong>Bootstrap buttons checkbox and radio buttons <a href="http://nuget.org/" target="_blank">NuGet</a> package</strong></p>
<h4>Use</h4>
<p>Add the package to your project from NuGet</p>
<div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffffcc"><strong><font size="2" face="Arial">From the Package Manager Console type</font>: <br><font size="2" face="Courier New">Install-Package NotAClue.Checkbox.Css.Buttons</font></strong> </div>
<p>It will add a <strong>Content</strong> folder to your project if it’s not already there with the <strong>checkbox-buttons</strong> LESS and CSS files add a reference to the min.css file to your master page and then decorate you <strong>CheckBoxes,</strong> <strong>CheckBoxLists,</strong> <strong>RadioButtons and RadioButtonLists </strong>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:</p>
<p><a href="http://lh5.ggpht.com/-r3lcOZXI0sQ/Uh92DQ9oE2I/AAAAAAAADPw/_YcpJ1PMUxA/s1600-h/checkbox-buttons-in-action%25255B4%25255D.png"><img title="checkbox-buttons-in-action" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="checkbox-buttons-in-action" src="http://lh5.ggpht.com/-D6BXx8a7dcU/Uh92E0_iolI/AAAAAAAADP4/O2KDhJEeMm4/checkbox-buttons-in-action_thumb%25255B2%25255D.png?imgmax=800" width="548" height="367"></a></p>
<p><strong>Figure 3 – Checkbox Buttons in action</strong></p>
<p>In <strong>Figure 3</strong> 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.</p>
<h4>Download</h4>
<p>Everything you need is on <a href="http://nuget.org/" target="_blank">NuGet</a>.</p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com4tag:blogger.com,1999:blog-6907873803403737979.post-45580944324250513702013-08-28T12:10:00.001+01:002013-08-28T14:21:47.611+01:00Adding a simple BootstrapMenu to Dynamic Data With Bootstrap<p>We are going to add the new ASP.Net web <a href="http://getbootstrap.com/css/#forms" target="_blank">forms</a> BootstrapMenu control to a Dynamic Data project, I like to clean it up a little first.</p> <p><img title="clean project" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clean project" src="http://lh6.ggpht.com/-ku4tI-H5yDs/Uh3akjUeyfI/AAAAAAAADNY/Z5dZ4OOso2g/clean-project%25255B5%25255D.png?imgmax=800" width="287" height="258"></p> <p><strong>Figure 1 – Clean project</strong></p> <p>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.</p> <p><img title="open nuget" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="open nuget" src="http://lh4.ggpht.com/-1dBGrIMLqio/Uh3alHe-JnI/AAAAAAAADNg/b2CQd_ssGto/open-nuget%25255B5%25255D.png?imgmax=800" width="360" height="267"></p> <p><strong>Figure – 2 Open NuGet</strong></p> <p>Next we search for <strong>NotAClue</strong> packages and scroll down to the last package</p> <p><img title="get bootstrap menu control" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="get bootstrap menu control" src="http://lh6.ggpht.com/-rVPAmnL5P88/Uh3alrpidtI/AAAAAAAADNo/ij2_lrGZVsw/get-bootstrap-menu-control%25255B5%25255D.png?imgmax=800" width="941" height="492"></p> <p><strong>Figure 3 – Get bootstrap menu control</strong></p> <p>Click Install</p> <p><img title="installing bootstrap menu control" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="installing bootstrap menu control" src="http://lh6.ggpht.com/-sgEc-F9-3ws/Uh3amJc46II/AAAAAAAADNw/VMCo1sr3aQA/installing-bootstrap-menu-control%25255B5%25255D.png?imgmax=800" width="502" height="395"></p> <p><strong>Figure 4 – Installing bootstrap menu control</strong></p> <p><img title="bootstrap menu control installed" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="bootstrap menu control installed" src="http://lh6.ggpht.com/-0fkABkPi6dM/Uh3amv9eDhI/AAAAAAAADN4/hy8n6Br9e6s/installed-bootstrap-menu-control%25255B5%25255D.png?imgmax=800" width="437" height="103"></p> <p><strong>Figure 5 – Bootstrap menu control installed</strong></p> <p>Next we need to add the script and style sheet references.</p> <p><img title="adding the scripts and style sheets" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="adding the scripts and style sheets" src="http://lh5.ggpht.com/-hJ3Z7wf8QXc/Uh3anHrj0QI/AAAAAAAADOA/7xxaFJpr8lg/adding-the-scripts-and-style-sheets%25255B6%25255D.png?imgmax=800" width="628" height="580"></p> <p><strong>Figure 6 – Adding the scripts and style sheets</strong></p> <p>Lets clean out the Default.aspx and it’s code behind file</p> <p><a href="http://lh6.ggpht.com/-HGFhAmOFxRI/Uh3anoY2bEI/AAAAAAAADOI/TwT4tNLPdZU/s1600-h/default-aspx-file%25255B4%25255D.png"><img title="Default.aspx file" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Default.aspx file" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKuFFQ6CHNIUIm46LAZlAujTpe4ltqYC4LyZMkzmXTeyV3A9MFkzsJc0vUxBfw85DXoA_EDAd_4SK04fmxR7L6L8bTxBKlNg6pmdr2Fj0-3OZweTGoEBCVct0CIu-u5eq231prLUKZnjU/?imgmax=800" width="682" height="103"></a></p> <p><strong>Figure 7 – Default.aspx file</strong></p> <p><img title="Default.aspx.cs file" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Default.aspx.cs file" src="http://lh4.ggpht.com/-R_HO0yEBIQ8/Uh3aooBwTjI/AAAAAAAADOU/7d-4e2BjPDo/default-aspx-cs-file%25255B5%25255D.png?imgmax=800" width="433" height="85"></p> <p><strong>Figure 8 – Default.aspx.cs file</strong></p> <p>Now we add the menu to the Site.master</p> <p><a href="http://lh3.ggpht.com/-jTISkXT5hHo/Uh3apI5R7HI/AAAAAAAADOc/3awxAIKFYqU/s1600-h/adding-the-bootstrap-menu-mark-up%25255B6%25255D.png" target="_blank"><img title="Adding the bootstrap menu mark-up" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Adding the bootstrap menu mark-up" src="http://lh4.ggpht.com/-V29g3dIuz-w/Uh3apx8XPfI/AAAAAAAADOo/BaJL8S1OI6Q/adding-the-bootstrap-menu-mark-up_thumb%25255B4%25255D.png?imgmax=800" width="640" height="265"></a></p> <p><strong>Figure 9 – Adding the bootstrap menu mark-up</strong></p> <p><a href="http://lh3.ggpht.com/-DMj0Y2UjjME/Uh3aqTVsk7I/AAAAAAAADOw/jpCFIK8q3co/s1600-h/adding-the-bootstrap-menu-code-behind%25255B5%25255D.png" target="_blank"><img title="Adding the bootstrap menu code behind" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Adding the bootstrap menu code behind" src="http://lh5.ggpht.com/-fjsEi9Bll9g/Uh3arOgXx3I/AAAAAAAADO4/XUBYQmSL8kE/adding-the-bootstrap-menu-code-behind_thumb%25255B3%25255D.png?imgmax=800" width="640" height="221"></a></p> <p><strong>Figure 10 – Adding the bootstrap menu code behind</strong></p> <p>So after all that here it is the first part of our Bootstrap Dynamic Data Project Template</p> <p><img title="Working Bootstrap Menu Control" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Working Bootstrap Menu Control" src="http://lh3.ggpht.com/-DbEZsNzbTmo/Uh3arphfz4I/AAAAAAAADPA/CN1_LGExq10/working-bootstrap-menu-control%25255B6%25255D.png?imgmax=800" width="720" height="509"></p> <p><strong>Figure 11 – Working Bootstrap Menu Control</strong></p> <h4>Download</h4> <p>As usual you can get the code from the Project on <a href="https://bootstrapfriendlycontroladaptors.codeplex.com/">Bootstrap Friendly Control Adaptors</a> and on my <a href="https://skydrive.live.com/#cid=96845E7B0FAC1EED&id=96845E7B0FAC1EED%211723">SkyDrive</a> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com7tag:blogger.com,1999:blog-6907873803403737979.post-13607694451194376832013-08-27T14:35:00.001+01:002013-08-27T21:05:15.418+01:00Bootstrap Friendly Web Controls<p>A big project rename after discovering that the Menu does not play well with <a href="http://msdn.microsoft.com/EN-US/library/vstudio/system.web.ui.webcontrols.adapters.webcontroladapter%28v=vs.100%29.aspx" target="_blank">Control Adapters</a> and that this is not the way forward I have now renamed the project to <strong>Bootstrap Friendly Web Controls</strong> and I have added the first control which is the <strong>BootstrapMenu</strong></p> <p><a href="https://bootstrapfriendlywebcontrols.codeplex.com/"><img title="bootstrap-freindly-logo" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="bootstrap-freindly-logo" src="http://lh4.ggpht.com/-JtgumSdvp9I/UhyrOKnTfbI/AAAAAAAADM4/E_iBAoEQCJQ/bootstrap-freindly-logo%25255B5%25255D.png?imgmax=800" width="508" height="100"></a></p> <p>Bootstrap Friendly Web Controls is now Live on <a href="https://bootstrapfriendlywebcontrols.codeplex.com/" target="_blank">Codeplex</a> and <a href="http://www.nuget.org/packages/NotAClue.Web.UI.BootstrapWebControls/" target="_blank">NuGet</a></p> <p><img title="BootstrapMenu" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="BootstrapMenu" src="http://lh3.ggpht.com/-ss7wcG3SW5c/Uh0GeQS42pI/AAAAAAAADNI/CbP2aZafeSI/BootstrapMenu%25255B5%25255D.png?imgmax=800" width="529" height="378"></p> <p>Next I will create tutorial on using the BootstrapMenu control.</p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-27819698044566746382013-08-21T07:56:00.001+01:002013-08-21T08:02:09.563+01:00GridView Bootstrap Update<p>It would appear that issue that pushed me towards using <a href="http://msdn.microsoft.com/EN-US/library/vstudio/system.web.ui.webcontrols.adapters.webcontroladapter%28v=vs.100%29.aspx" target="_blank">Control Adapters</a> 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. <a href="http://blogs.msdn.com/b/scothu" target="_blank">Scott Hunter</a> has a post here <a href="http://blogs.msdn.com/b/scothu/archive/2008/03/26/cleaning-up-default-gridview-markup.aspx" target="_blank">Cleaning up Default GridView Mark-up</a> this showed me we can clean the mark-up up fully without resorting to <a href="http://msdn.microsoft.com/EN-US/library/vstudio/system.web.ui.webcontrols.adapters.webcontroladapter%28v=vs.100%29.aspx" target="_blank">Control Adapters</a>.</p> <p><img title="Default GridView Mark-Up For Dynamic Data" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="Default GridView Mark-Up For Dynamic Data" src="http://lh3.ggpht.com/-eWek_shCeO0/UhRkhnWQnpI/AAAAAAAADL0/i2d2xuO6rTc/DefaultGridViewMarkUpForDD%25255B5%25255D.png?imgmax=800" width="301" height="228"></p> <p><strong>Figure 1 – Default GridView Mark-Up For Dynamic Data</strong></p> <p>Going back to my original post <a href="http://csharpbits.notaclue.net/2013/07/bootstrap-friendly-dynamic-data.html" target="_blank">Bootstrap Friendly Dynamic Data</a> I showed the mark-up in <strong>Figure 2</strong> and demonstrated this caused issues with Bootstrap and other CSS styles applied to the grid.</p> <p><img title="table-mark-up-Issues" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="table mark-up Issues" src="http://lh4.ggpht.com/-hXz5W5ZFQ8k/UhRkiJ4_NjI/AAAAAAAADL4/lJiWEpVJfeY/table-mark-up-Issues%25255B5%25255D.png?imgmax=800" width="534" height="91"></p> <p><strong>Figure 2- Table mark-up issues</strong></p> <p>So we change the mark-up to that in <strong>Figure 3</strong> and then we get this nicely cleaned mark-up in <strong>Figure 4</strong> </p> <p><img title="Updated GridView Mark-Up For Dynamic Data" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="Updated GridView Mark-Up For Dynamic Data" src="http://lh5.ggpht.com/-NL3ArauME0E/UhRkilMiT6I/AAAAAAAADME/bH_OroBGxQ4/UpdatedGridViewMarkUpForDD%25255B5%25255D.png?imgmax=800" width="491" height="220"></p> <p><strong>Figure 3 – Updated GridView Mark-Up For Dynamic Data</strong></p> <p><img title="table mark-up fixed" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="table mark-up fixed" src="http://lh6.ggpht.com/-DO0V0Gy5bV4/UhRki8bKFjI/AAAAAAAADMM/a5FkixLQh2Q/table-mark-up-fixed%25255B5%25255D.png?imgmax=800" width="441" height="67"></p> <p><strong>Figure 4 – table mark-up fixed</strong></p> <p><a href="http://lh3.ggpht.com/-SWOingr_5Ys/UhRl7XrBqzI/AAAAAAAADMY/hr_A8lVwdGc/s1600-h/GridView-output-with-bootstrap%25255B5%25255D.png" target="_blank"><img title="GridView output with Bootstrap" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="GridView output with Bootstrap" src="http://lh4.ggpht.com/-6iZLEPMJxLA/UhRl7y9QvcI/AAAAAAAADMg/kkjLpW2t-R8/GridView-output-with-bootstrap_thumb%25255B3%25255D.png?imgmax=800" width="640" height="296"></a></p> <p><strong>Figure 5 – GridView output with Bootstrap</strong></p> <p>Hope that helps</p> <h4>Download</h4> <p>As usual you can get the code from the Project on <a href="https://bootstrapfriendlycontroladaptors.codeplex.com/">Bootstrap Friendly Control Adaptors</a> and on my <a href="https://skydrive.live.com/#cid=96845E7B0FAC1EED&id=96845E7B0FAC1EED%211723">SkyDrive</a></p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-6618239466419010992013-08-18T19:03:00.001+01:002013-08-18T19:09:20.440+01:00Adding Validation Using Bootstrap Popover<p>I noticed an article by <a href="http://damianedwards.wordpress.com" target="_blank">Damien Edwards</a> called <a href="http://damianedwards.wordpress.com/2009/01/31/updating-the-aspnet-validator-controls-to-change-invalid-controls-css-class-on-non-javascript-clients/">Updating the ASP.NET validator controls to change invalid control’s CSS class on non-JavaScript clients</a> 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, <strong>Figure 1</strong> is what I came up with.</p> <p><img title="Bootstrap Tooltip in action" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Bootstrap Tooltip in action" src="http://lh3.ggpht.com/-r76WgTQnxGU/UhEMUdv0M8I/AAAAAAAADLg/A2i9oKwvqg0/Bootstrap-Tooltip-in-action6.png?imgmax=800" width="669" height="228"></p> <p><strong>Figure 1- Bootstrap Popover in action</strong></p> <p>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.</p><pre class="brush: csharp;">protected override void OnPreRender(EventArgs e)<br>{<br> base.OnPreRender(e);<br><br> var validator = Control as BaseValidator;<br> var controlType = Control.GetType().ToString();<br> var stringType = controlType.Substring(controlType.LastIndexOf(".") + 1, controlType.Length - controlType.LastIndexOf(".") - 1);<br><br> // build unique CCS class per validator type<br> var validatorError = String.Format("{0}-{1}", stringType, ERROR_CLASS);<br> var controlToValidate = Control.NamingContainer.FindControl(validator.ControlToValidate) as WebControl;<br> if (controlToValidate != null)<br> {<br> if (validator.IsValid)<br> {<br> // remove validator class<br> var className = String.Join(" ", controlToValidate.CssClass.Split(' ').Where(c => !c.Equals(validatorError)).ToArray());<br> controlToValidate.CssClass = className;<br> }<br> else<br> {<br> // add validator class<br> if (controlToValidate.CssClass.Split(' ').FirstOrDefault(c => c.Equals(validatorError)) == null)<br> controlToValidate.CssClass = String.IsNullOrEmpty(controlToValidate.CssClass)<br> ? validatorError<br> : String.Format("{0} {1}", controlToValidate.CssClass, validatorError);<br><br> // add tooltip<br> controlToValidate.Attributes.Add("data-placement", "right");<br> controlToValidate.Attributes.Add("data-toggle", "popover");<br> controlToValidate.Attributes.Add("data-trigger", "hover");<br> controlToValidate.Attributes.Add("data-delay", "500");<br><br> // add title<br> controlToValidate.Attributes.Add("data-original-title", "Error!");<br> //TODO: add append errors to tooltip<br> controlToValidate.Attributes.Add("data-content", validator.ErrorMessage);<br><br> //$(document).ready(function () { $("#test").tooltip(); });<br> var datePickerScript = String.Format("$(document).ready(function () {{ $('#{0}').popover(); }});\n", controlToValidate.ClientID);<br> Control.Page.AddStartupClientScript(controlToValidate.ClientID, datePickerScript);<br> }<br> }<br>}
</pre>
<p><strong>Listing 1 – Control Adapter OnPreRender</strong></p>
<p>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.</p><pre class="brush: css;">.inner-glow (@radius: 3px, @color: #f3ffa7)<br>{<br> -webkit-box-shadow: 0 0 @radius @radius @color inset !important;<br> box-shadow: 0 0 @radius @radius @color inset !important;<br>}<br><br>.required<br>{<br> .inner-glow;<br>}<br><br>.RequiredFieldValidator-validation-error,<br>.RegularExpressionValidator-validation-error,<br>.CompareValidator-validation-error,<br>.CustomValidator-validation-error,<br>.RangeValidator-validation-error,<br>.DynamicValidator-validation-error<br>{<br> .inner-glow(2px, fadeout(#ff0000, 50%));<br> border: 1px solid fadeout(#ff0000, 40%) !important;<br>}
</pre>
<p><strong>Listing 2 – LESS Classes</strong></p>
<p>I did the the styling using LESS as it’s available readily now with <a href="http://madskristensen.net" target="_blank">Mads Kristensen</a>’s <a href="http://vswebessentials.com/" target="_blank">Web Essentials</a> for Visual Studios 2012 and 2013.
<div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffffcc"><strong>Note: </strong>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.</div></p>
<h4>Download</h4>
<p>As usual you can get the code from the Project on <a href="https://bootstrapfriendlycontroladaptors.codeplex.com/">Bootstrap Friendly Control Adaptors</a> and on my <a href="https://skydrive.live.com/#cid=96845E7B0FAC1EED&id=96845E7B0FAC1EED%211723">SkyDrive</a></p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-29121999393288879122013-08-11T21:12:00.001+01:002013-08-13T23:58:41.157+01:00Adding Some More Bootstrap Love to the Dynamic Data Project Template<p>In this article I want to add some of the nice features of Bootstrap to Dynamic Data</p> <ul> <li>Bootstrap Navbar <li>Bootstrap Date Picker</li></ul> <h4>Navbar</h4> <p>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.</p> <p><img title="Navbar" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Navbar" src="http://lh4.ggpht.com/-r63GpybqplI/UgfwHdc37zI/AAAAAAAADLA/rInUOP1_XP8/Navbar%25255B6%25255D.png?imgmax=800" width="608" height="708"></p> <p><strong>Figure 1 – the Navbar</strong></p> <p>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:</p><pre class="brush: xml;"><div class="navbar"><br> <div class="navbar-inner"><br> <a class="brand" href="#">Dynamic Data</a><br> <ul class="nav"><br> <li><br> <asp:LinkButton ID="LinkButton1" runat="server" PostBackUrl="~/Default.aspx">Home</asp:LinkButton><br> </li><br> <asp:ListView ID="Menu1" runat="server"><br> <LayoutTemplate><br> <li class="dropdown"><br> <a class="dropdown-toggle" data-toggle="dropdown" href="#">Tables&nbsp;<b class="caret"></b></a><br> <ul class="dropdown-menu"><br> <li runat="server" id="itemPlaceholder"></li><br> </ul><br> </li><br> </LayoutTemplate><br> <ItemTemplate><br> <li runat="server"><br> <asp:DynamicHyperLink ID="HyperLink1" runat="server"><%# Eval("DisplayName") %></asp:DynamicHyperLink><br> </li><br> </ItemTemplate><br> </asp:ListView><br> </ul><br> </div><br></div>
</pre>
<p><strong>Listing 1 – the Menu mark-up</strong></p><pre class="brush: csharp;">protected void Page_Load(object sender, EventArgs e)<br>{<br> System.Collections.IList visibleTables = Global.DefaultModel.VisibleTables;<br> if (visibleTables.Count == 0)<br> {<br> throw new InvalidOperationException("There are no accessible tables...");<br> }<br> Menu1.DataSource = visibleTables;<br> Menu1.DataBind();<br>}
</pre>
<p><strong>Listing 2 – the Page_Load moved to Site.master</strong></p>
<h4>Date Picker</h4>
<p>Add the <a href="https://github.com/eternicode/bootstrap-datepicker" target="_blank">Bootstrap Date Picker</a> using NuGet</p>
<p><img title="Bootstrap Date Picker" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Bootstrap Date Picker" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh33Kgwl-tWuEn0ZVzDMEy1M_h50Mg1RSN-RKPvznUTg9Z5Knrh-PW0a0D0qwBZBOnQdkgFQgsJYgV1UBzoUBnKNaOThS-vsP6Du7MorsPRZ_VpCqu5KHH73WeFiHuJgdpTv430Q26t2xQ/?imgmax=800" width="397" height="68"></p>
<p><strong>Figure 2 – Bootstrap Date Picker</strong></p>
<p>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.</p><pre class="brush: xml;"><div class="controls"><br> <div class="input-append date" id="DivDate" runat="server"><br> <div class="input-append"><br> <asp:TextBox<br> ID="TextBox1"<br> runat="server"<br> CssClass="input-small" /><br> <span class="add-on"><i class="icon-calendar"></i></span><br> </div><br> <asp:RequiredFieldValidator <br> runat="server" <br> ID="RequiredFieldValidator1" <br> CssClass="" <br> ControlToValidate="TextBox1" <br> Display="Static" <br> Enabled="false"/><br> <asp:RegularExpressionValidator <br> runat="server" <br> ID="RegularExpressionValidator1" <br> CssClass="" <br> ControlToValidate="TextBox1" <br> Display="Static" <br> Enabled="false"/><br> <asp:DynamicValidator <br> runat="server" <br> ID="DynamicValidator1" <br> CssClass="" <br> ControlToValidate="TextBox1" <br> Display="Static"/><br> <asp:CustomValidator <br> runat="server" <br> ID="DateValidator" <br> CssClass="" <br> ControlToValidate="TextBox1" <br> Display="Static" <br> EnableClientScript="false" <br> Enabled="false" <br> OnServerValidate="DateValidator_ServerValidate"/><br> </div><br></div>
</pre>
<p><strong>Listing 3 – Date_Edit.ascs mark-up</strong></p><pre class="brush: csharp;">// get default display format<br>var dateFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;<br><br>// create script<br>var datePickerScript = String.Format("$('#{0}').datepicker();", DivDate.ClientID);<br>Page.AddStartupClientScript(String.Format("{0}{1}BootstrapDatePicker", Table.Name, Column.Name), datePickerScript);<br><br>DivDate.Attributes.Add("data-date-format", dateFormat.ToLower());<br>TextBox1.Attributes.Add("placeholder", dateFormat);<br>TextBox1.ToolTip = Column.Description;<br><br>TextBox1.Columns = DateTime.Now.ToString(dateFormat).Length;
</pre>
<p><strong>Listing 3 – Date_Edit.ascx.cs</strong></p>
<p><strong>Listings 2 & 3</strong> show the necessary code to create the Date Field Templates</p>
<p><img title="Bootstrap Date Picker in Action" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Bootstrap Date Picker in Action" src="http://lh3.ggpht.com/-nJr85y2sytg/UgfwIfqSqJI/AAAAAAAADLQ/E2vNGz3CZ1w/BootstrapDatePickerInAction%25255B5%25255D.png?imgmax=800" width="357" height="317"></p>
<p><strong>Figure 3 – Bootstrap Date Picker in Action</strong></p>
<p>The Project is on <a href="https://bootstrapfriendlycontroladaptors.codeplex.com/">Bootstrap Friendly Control Adaptors</a> and on my <a href="https://skydrive.live.com/#cid=96845E7B0FAC1EED&id=96845E7B0FAC1EED%211723">SkyDrive</a></p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-21898252658855138282013-08-11T16:06:00.001+01:002013-08-11T16:31:57.508+01:00Converting the Dynamic Data Project Template to Bootstrap<p>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.</p> <ul> <li>Page & Entity Templates (Details, Edit & Insert) <li>Field Templates <li>Filters <li>Validation</li></ul> <h4>Page and Entity Templates</h4> <p>If we look at the Edit page <strong>Figure 1</strong> rendered you can see it has been rendered using a table</p> <p><img title="EditTemplate" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="EditTemplate" src="http://lh5.ggpht.com/-NMrENSqAFvo/UgeqzBT9E0I/AAAAAAAADIg/BdC3mWRDajM/EditTemplate%25255B1%25255D.png?imgmax=800" width="527" height="368"></p> <p><strong>Figure 1 – Edit Template (with border turned on)</strong></p> <p>If we look at the mark-up we can see what we have to deal with, the FormView Edit template (<strong>Figure 2</strong>) it contains a Table with some <em>cell padding</em> next look at the Entity Template mark-up (<strong>Figure 3</strong>) we see each item will be rendered as a table row with the first cell having the label and the second having the field.</p> <p><img title="Edit Template mark-up" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Edit Template mark-up" src="http://lh6.ggpht.com/-EfXOQbteYZ4/UgeoVXqN7GI/AAAAAAAADIo/ZQ3TVKdNMWw/EditTemplateMarkUp%25255B2%25255D.png?imgmax=800" width="832" height="402"></p> <p><strong>Figure 2 - Edit Template mark-up</strong></p> <p><img title="Edit Entity Template mark-up" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Edit Entity Template mark-up" src="http://lh3.ggpht.com/-cf2ZIVNsQOA/UgeoXNab3HI/AAAAAAAADIw/ixMAKwpDIok/EditEntityTemplateMarkUp%25255B1%25255D.png?imgmax=800" width="464" height="333"></p> <p><strong>Figure 3 – Edit Entity Template mark-up</strong></p> <p>If we look at the Bootstrap <a href="http://getbootstrap.com/css/#forms" target="_blank">Forms</a> we see that forms have a layout that looks like similar to the output of the default templates the <a href="http://getbootstrap.com/css/#forms-horizontal" target="_blank">Horizontal Form</a> this is what we will go for.</p> <p><img title="Edit Template mark-up Bootstrappified" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Edit Template mark-up Bootstrappified" src="http://lh4.ggpht.com/-hYqdnD3siGY/UgeoXk6inmI/AAAAAAAADI4/n95cMJZa8jc/EditTemplateMarkUpBootstrappified%25255B1%25255D.png?imgmax=800" width="458" height="544"></p> <p><strong>Figure 4 – Edit Template mark-up Bootstrapified</strong></p> <p><img title="Edit Entity Template mark-up Bootstrappified" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Edit Entity Template mark-up Bootstrappified" src="http://lh5.ggpht.com/-6Ywwpu8r5Ps/UgeoYr_7GUI/AAAAAAAADJA/hqYwdS8ue_s/EditEntityTemplateMarkUpBootstrappified.png?imgmax=800" width="426" height="318"></p> <p><strong>Figure 5 – Edit Entity Template mark-up Bootstrapified</strong></p> <p>If you look at <strong>Figures 4 & 5</strong> 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 <strong>Figure 6</strong> that it has made the edit template look a little more like the Bootstrap Form. <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffffcc"><strong>Note: </strong>you will need to do this in the Details, Edit and Insert Page Templates and in the three Default Entity Templates.</div> <p><img title="Edit Template Post Bootstrapifing" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Edit Template Post Bootstrapifing" src="http://lh4.ggpht.com/-IspYUCQucsU/UgeoZEf8fMI/AAAAAAAADJE/j_nWvbda6OM/EditTemplatePostBootstrapifing%25255B1%25255D.png?imgmax=800" width="521" height="359"></p> <p><strong>Figure 6 - Edit Template Post Bootstrapifing</strong></p> <p>To complete the transformation we will need to look at ALL the field templates.</p> <h4>Field Templates</h4> <p>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 (<strong>Figure 7</strong>) Text_Edit Field Template.</p> <p><img title="Text_Edit Field Template" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Text_Edit Field Template" src="http://lh6.ggpht.com/-4-ZU2e2zpeg/UgeoZ3zvgxI/AAAAAAAADJM/madz25luzQs/Text_EditFieldTemplate%25255B1%25255D.png?imgmax=800" width="313" height="450"></p> <p><strong>Figure 7 – Text_Edit Field Template</strong></p> <p>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 <em>span</em>s so they need to be encapsulated otherwise they will push the format around and mess it up.</p> <p><img title="Validators Presence In mark-up" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Validators Presence In mark-up" src="http://lh5.ggpht.com/-pWY_OXLqP0Y/UgeoaCbtIjI/AAAAAAAADJU/deZdmyXCZp0/ValidatorsPresenceInMarkUp%25255B1%25255D.png?imgmax=800" width="387" height="70"></p> <p><strong>Figure 8 – Validators Presence In mark-up</strong></p> <p><strong><img title="ValidatorsPresenceMarkUp" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="ValidatorsPresenceMarkUp" src="http://lh4.ggpht.com/-7BRUYSBWDug/Ugeobp-2veI/AAAAAAAADJc/rXMiNDsS5XI/ValidatorsPresenceMarkUp%25255B1%25255D.png?imgmax=800" width="429" height="456"></strong></p> <p><strong>Figure 9 – Validators Presence mark-up</strong></p> <p>As it turns out this is quite simple though long winded see <strong>Figure 10</strong> this excerpt from the <a href="http://getbootstrap.com/2.3.2/base-css.html#forms" target="_blank">Bootstrap Forms</a> (2.3.2) documentation.</p> <p><a title="Horizontal Form" href="http://getbootstrap.com/2.3.2/base-css.html#forms" target="_blank"><img title="Horizontal-Form" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Horizontal-Form" src="http://lh4.ggpht.com/-V8zRPRnh7Ns/UgeocqLuphI/AAAAAAAADHg/wRdljLIE-QE/Horizontal-Form%25255B7%25255D.png?imgmax=800" width="714" height="229"></a></p> <p><strong>Figure 10 – Horizontal Form</strong></p> <p><img title="Bootstrapified Edit Template With Field Templates" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Bootstrapified Edit Template With Field Templates" src="http://lh6.ggpht.com/-ptqF8c-1878/UgeodWodBWI/AAAAAAAADJk/yP-BJd4fwCQ/BootstrapifiedEditTemplateWithFieldTemplates.png?imgmax=800" width="497" height="620"></p> <p><strong>Figure 11 – Bootstrapified Edit Template with Field Templates</strong></p> <p>You can see from <strong>Figure 11</strong> that adding the DIV with the <em>controls</em> class sorts the layout out nicely.</p> <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #800080; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #f0d0f0"><strong>Updated: </strong>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. <table cellspacing="0" cellpadding="2" width="400" border="0"> <tbody> <tr> <td valign="top" width="200"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga04tAqjSOjvKdMSfNjbp9exMps_sVIhx1h43hTKWPKxp6qRuiKiOffuSw_zfI29RRyEsC-SFIAj1a-Op41Vfhf1FyAym7xAxtL3wNfQCUj5058rwz-pRqHarHBFr251a0Wq_BRMOiRKQ/s1600-h/ReadOnlyCssClass%25255B9%25255D.png"><img title="ReadOnlyCssClass" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="ReadOnlyCssClass" src="http://lh6.ggpht.com/-o8kjSBl9YWk/UgeuZ0DbmwI/AAAAAAAADKg/7la8AgVEoF8/ReadOnlyCssClass_thumb%25255B3%25255D.png?imgmax=800" width="189" height="103"></a></td> <td valign="top" width="200"><a href="http://lh5.ggpht.com/-tK80qXBXTRM/Ugeuab-gicI/AAAAAAAADKk/78MGS12FER0/s1600-h/ReadOnlyFields%25255B4%25255D.png"><img title="ReadOnlyFields" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="ReadOnlyFields" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhteQk4luWj_fkVPX9Ur63T_gDwdWBkq1hwt7FePfii9VDih-ZbKgNaChjdfRnSIgYtcUtbwxqf-ZRHOnkcE_MJ4IqT6zKQMnmlDzmzgZyOnSQ8mNww4r8ibRrLCbf6TN28PPPN7nmm8j4/?imgmax=800" width="600" height="83"></a></td></tr></tbody></table> </div> <h4>Filters & Validation</h4> <p>I will tackle Filters and Validation together.</p> <p><img title="Validation & Filters in List Page Template" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Validation & Filters in List Page Template" src="http://lh5.ggpht.com/-4FLXJzcDIw4/UgeofMgZb1I/AAAAAAAADJw/SxJqOT5hCHg/ValidationAndFiltersInListPageTemplate.png?imgmax=800" width="512" height="513"></p> <p><strong>Figure 12 – Validation & Filters in List Page Template</strong></p> <p>To make the Validation show well with Bootstrap we need to look at the <a title="Alters" href="http://getbootstrap.com/2.3.2/components.html#alerts" target="_blank">Alerts</a> in Bootstrap, we will replace “DDValidator” class with the “alert alert-error” in all pages see <strong>Figure 13</strong> </p> <p><img title="Replace DDValidator with alerts" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Replace DDValidator with alerts" src="http://lh4.ggpht.com/-KWn6ytvI0CY/UgeofldqDiI/AAAAAAAADJ4/8a7IdGT8UNs/ReplaceDDValidatorWithAlerts%25255B2%25255D.png?imgmax=800" width="353" height="514"></p> <p><strong>Figure 13 – Replace DDValidator with alerts</strong></p> <p>Then we remove the DIV from around the Validators and Filters see <strong>Figure 14</strong> for the details, this ends up looking like this:</p> <p><img title="UpdatedValidationAndFilters" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="UpdatedValidationAndFilters" src="http://lh6.ggpht.com/-SbER-Ibnlpc/UgeohIvSDAI/AAAAAAAADKA/vXHQvfqWIn0/UpdatedValidationAndFilters%25255B3%25255D.png?imgmax=800" width="764" height="230"></p> <p><strong>Figure 14 – Filters</strong></p> <p>And if we cause the validators to show, we now get a Bootstrap alert to show our errors.</p> <p><img title="ValidatorsShowing" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="ValidatorsShowing" src="http://lh5.ggpht.com/-mIsYmRYyHJs/UgeohztWASI/AAAAAAAADKI/yMNhOIFORgM/ValidatorsShowing%25255B1%25255D.png?imgmax=800" width="557" height="399"></p> <p><strong>Figure 15 – Validators showing</strong></p> <p>Next up adding a Menu and Navbar to the site.</p> <p>The Project is on <a href="https://bootstrapfriendlycontroladaptors.codeplex.com/">Bootstrap Friendly Control Adaptors</a> and on my <a href="https://skydrive.live.com/#cid=96845E7B0FAC1EED&id=96845E7B0FAC1EED!1723" target="_blank">SkyDrive</a></p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-23055733092167819872013-08-04T19:45:00.001+01:002013-08-04T19:45:56.157+01:00Adding the a Bootstrap Pagination to the GridView Adapter<p>See <a href="http://getbootstrap.com/components/#pagination" target="_blank">Bootstrap Pagination</a> </p> <p><img title="BootstrapPager#1" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="BootstrapPager#1" src="http://lh6.ggpht.com/-Vh4F6U6qus4/Uf6hSlrlxcI/AAAAAAAADEQ/Om5tXga-Mh0/BootstrapPager110.png?imgmax=800" width="280" height="75"></p> <p><img title="BootstrapPager#2" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="BootstrapPager#2" src="http://lh6.ggpht.com/-MAnkH6H8iSI/Uf6hTMZLfbI/AAAAAAAADEY/C9imOnDYxIQ/BootstrapPager212.png?imgmax=800" width="202" height="83"></p> <p><img title="BootstrapPager#3" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="BootstrapPager#3" src="http://lh6.ggpht.com/-ERW3EzAaHH4/Uf6hTqUZ5hI/AAAAAAAADEg/058vU3nIbKI/BootstrapPager310.png?imgmax=800" width="553" height="91"></p> <p><strong>Figure 1 – Bootstrap Pager Styles 1, 2 & 3 from Bootstrap</strong></p> <p>The GridView has some setting that determine how the none template GridView pager is rendered (see <strong>Figure 2</strong>) here we have the usual settings. Looking at the <strong>Pager Mode PagerTypes</strong> in <strong>Figure 3</strong> there are only four type we can select from these are shown in <strong>Figure 4,</strong> 2 – 4 1 is closer to what I like first previous next last with number in between and it’s this one I will use as my NumericFirstLast. Going back to <strong>Figure 2</strong> we can see three areas we can get other customisation information from.</p> <ol> <li>PageButtonCount – the number of numeric buttons to show <li>How the buttons will show i.e. the symbol or image for the first last next previous buttons, if there are no values here we will use the Glyphicons from Bootstrap. <li>Position – this will indicate the position of the pager</li></ol> <p><img title="Pager Settings In Visual Studio" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Pager Settings In Visual Studio" src="http://lh3.ggpht.com/-TIR3NCsvRzA/Uf6hUB8YnkI/AAAAAAAADEo/inPnXr6evb0/PagerSettingsInVisualStudio6.png?imgmax=800" width="289" height="393"></p> <p><strong>Figure 2 – Pager Settings In Visual Studio</strong></p> <p><img title="Pager Types" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Pager Types" src="http://lh6.ggpht.com/-aKSVqA8B3YQ/Uf6hUsul_9I/AAAAAAAADEw/e3G3c2tWyLY/PagerTypes5.png?imgmax=800" width="187" height="89">---</p> <p><strong>Figure 3 – Pager Mode PagerTypes</strong></p> <p><img title="My Bootstrap Pagers" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="My Bootstrap Pagers" src="http://lh5.ggpht.com/-hzGNZn18cZk/Uf6hVY1B0oI/AAAAAAAADE4/WrDMwMQiZqo/MyBootstrapPagers%25255B1%25255D.png?imgmax=800" width="475" height="209"></p> <p><strong>Figure – 4 My Bootstrap pager styles</strong></p> <p>If we look at what is currently rendered from the GridView Control adaptor we can learn what it’s doing</p> <p><img title="Default Pager Settings" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="Default Pager Settings" src="http://lh5.ggpht.com/-oiMTBXgrOg8/Uf6hV7gLg3I/AAAAAAAADFA/sEAZ1AIjSyY/DefaultPagerSettings%25255B5%25255D.png?imgmax=800" width="324" height="105"></p> <p><strong>Figure 5 – Default pager settings</strong></p> <p><img title="BootstrapPagerSettings" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="BootstrapPagerSettings" src="http://lh5.ggpht.com/-nvu34p64HZU/Uf6hWEf6fCI/AAAAAAAADFI/RTQQss8CZ1o/BootstrapPagerSettings%25255B5%25255D.png?imgmax=800" width="585" height="167"></p> <p><strong>Figure 6 – Bootstrap pager settings</strong></p> <p>In <strong>Figures 5 & 6</strong> I have changed to default pager setting to some custom setting for Bootstrap this should look something like <strong>Figure 4 pager #4</strong> if we look at what is rendered before we make changes to the control adaptor we see <strong>Figure 7</strong> which is a DIV with a series of anchor tags (<a></a>) and a span tag indicating the selected item for Numbers.</p> <p><img title="Default Pager Output From Control Adaptor" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="Default Pager Output From Control Adaptor" src="http://lh6.ggpht.com/-BBiyQdpzOsk/Uf6hWiZN7BI/AAAAAAAADFQ/zx0Ts-M96ig/DefaultPagerOutputFromControlAdaptor%25255B5%25255D.png?imgmax=800" width="600" height="424"></p> <p><strong>Figure 7 – Default Pager Output From Control Adaptor </strong></p> <p>So in <strong>Figure 8</strong> the default render code we see all it is doing is getting the series of controls inside the default pager which is inside an inner table the code just finds the innermost controls and renders them without the table.</p> <p><img title="Default Pager Render Code" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="Default Pager Render Code" src="http://lh6.ggpht.com/-w8QJy0MmEWo/Uf6hXTm60VI/AAAAAAAADFY/P_0nSa1aTHc/DefaultPagerRenderCode%25255B5%25255D.png?imgmax=800" width="738" height="806"></p> <p><strong>Figure 8 – Default Pager Render Code</strong></p> <p>So we need to add the unordered-list and surround each hyper-link with an list element (LI) and indicate which item is currently active (that will be the span) and add the “active” class to the item to get that working.</p> <p><img title="Updated Pager Render Code" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="Updated Pager Render Code" src="http://lh6.ggpht.com/-rMb-Kxvinqk/Uf6hX2I4cQI/AAAAAAAADFg/GR104nC3itM/UpdatedPagerRenderCode%25255B5%25255D.png?imgmax=800" width="421" height="657"></p> <p><strong>Figure 9 – Updated Pager Render Code</strong></p> <p>In <strong>Figure 9</strong> we have added the unordered-list wrapper and also wrapped each anchor/hyper-link with an LI tag and added the active class for when an item is selected. There is no PagerStyles.PagerItemSelectedCssClass se we will have to hard code that. In <strong>Figure 10</strong> we can see out finished Bootstrap pager.</p> <p><img title="Finished Pager" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="Finished Pager" src="http://lh3.ggpht.com/-v9V9EfUrozQ/Uf6hYpaq43I/AAAAAAAADFo/n50htPHUNbM/FinishedPager%25255B5%25255D.png?imgmax=800" width="765" height="371"></p> <p><strong>Figure 10 – Finished Pager</strong></p> <p> <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffffcc"><strong>Note: </strong>You can also create you own custom pagers any way you want look at the default one that come with Dynamic Data for ideas.</div> You can find the download code in the usual folder on my <a href="https://skydrive.live.com/#cid=96845E7B0FAC1EED&id=96845E7B0FAC1EED!1723" target="_blank">SkyDrive</a> and the source code is here <a href="https://bootstrapfriendlycontroladaptors.codeplex.com/" target="_blank">Bootstrap Friendly Control Adaptors</a></p> <p>Next I plan to finish up making this Dynamic Data Project Template ready for access via the <a href="http://visualstudiogallery.msdn.microsoft.com/" target="_blank">Visual Studio Gallery</a>.</p> <p> <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #ff0000; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffdddd"><strong>!Important: </strong>This is not only for Dynamic Data it will add Bootstrap love to any .Net 4.x Web Application</div></p> <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #800080; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #f0d0f0"><strong>Updated: </strong>Now On <a href="http://nuget.org/" target="_blank">NuGet.org</a> <a title="Bootstrap Friendly Control Adapters" href="https://www.nuget.org/packages/BootstrapFriendlyControlAdaptorsPackage/" target="_blank">Bootstrap Friendly Control Adapters</a> you will still need to change the CSS and Pagers etc. manually but as soon as I get the Project Template done you won’t need to.</div> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com6tag:blogger.com,1999:blog-6907873803403737979.post-15962034043114391652013-07-28T13:02:00.001+01:002013-08-03T16:19:58.198+01:00Tweaking the GridView Control Adaptor for Bootstrap<p>To create this project we are going to get a bit of a leg up, we are going to take as our starting point the GridVew Adaptor from the <a href="http://www.asp.net/cssadapters/">ASP.NET 2.0 CSS Friendly Control Adapters 1.0</a> source code here <a href="http://cssfriendly.codeplex.com/">CSS Friendly Control Adapters</a> now the last update was Mar 5, 2007 so it was <strong>not</strong> created for .Net 4, 4.5 or even 4.5.1 but since we know it works after a fashion from my previous blog post we know we can use the GirdView adaptor as least as a starting point. <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffffcc"><strong>Note: </strong>Just a note I will be giving credit to the original Control Adapters from ASP.Net 2.0 when i publish this project on <a href="http://codeplex.com" target="_blank">Codeplex</a> and <a href="http://nuget.org/" target="_blank">NuGet.org</a> </div> <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #800080; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #f0d0f0"><strong>Updated: </strong>As of the writing of this article Bootstrap 3 RC1 was released so I will be referencing that documentation and moving this project to that release moving forward it will be released via NuGet anyway. </div> <h4>Getting setup</h4> <p><a href="http://lh3.ggpht.com/-FJmX9mMNWcA/UfUIOUUU2XI/AAAAAAAADBY/zVlNN0H73ao/s1600-h/GetTheGridViewAdapter22.png" target="_blank"><img title="GetTheGridViewAdapter" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="GetTheGridViewAdapter" src="http://lh3.ggpht.com/-O6kKESoIMTs/UfUIPCG5-KI/AAAAAAAADBg/z3ozYrY7Ozc/GetTheGridViewAdapter_thumb14.png?imgmax=800" width="669" height="622"></a></p> <p><strong>Figure 1 – Get the GridViewAdapter and helper files and the JavaScript file</strong></p> <p>We will start with the project from the last post if you followed all we need to do is remove the references to the old <a href="http://cssfriendly.codeplex.com/">CSS Friendly Control Adapters</a> and add a reference to our BootstrapFriendlyControlAdapters give the application a run and here we are</p> <p><a href="http://lh4.ggpht.com/-7p5bwTi7f6I/UfUIP-Xr-9I/AAAAAAAADBo/RuNDAv-KkEU/s1600-h/TheDefaultGridViewAdapterInUse17.png" target="_blank"><img title="TheDefaultGridViewAdapterInUse" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="TheDefaultGridViewAdapterInUse" src="http://lh5.ggpht.com/-_OUiOb0gswc/UfUIQSeOm9I/AAAAAAAADBw/jGU3Vmk4yA4/TheDefaultGridViewAdapterInUse_thumb.png?imgmax=800" width="530" height="480"></a></p> <p><strong>Figure 2 – the default GridView Adapter in use</strong></p> <p>As you will see the pager is not displaying correctly so lets fix that. In <strong>Figure 3</strong> we can see the issues highlighted, so what I did was remove the outer DIV and change the class for each of the inner SPANs (see <strong>Figure 4</strong>) I have added the class <strong>form-inline</strong> to both spans and to the right span which we want to be pulled left I have added the <strong>pull-left</strong> class.</p> <p><a href="http://lh6.ggpht.com/-iesh8h1Wev0/UfUIRCoYI1I/AAAAAAAADB4/GIosZ8cKTSE/s1600-h/PagerWithIssues11.png" target="_blank"><img title="Pager With Issues" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Pager With Issues" src="http://lh3.ggpht.com/-w5qurE_gQLE/UfUIR9bWAhI/AAAAAAAADCA/-TfqtrD5eYQ/PagerWithIssues_thumb7.png?imgmax=800" width="840" height="443"></a></p> <p><strong>Figure 3 – pager with issues</strong></p> <p><a href="http://lh4.ggpht.com/-FfAe5mF3uSo/UfUISRtVVVI/AAAAAAAADCI/nzq1xzbOlJ4/s1600-h/PagerWithIssuesFixed11.png" target="_blank"><img title="Pager With Issues Fixed" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Pager With Issues Fixed" src="http://lh6.ggpht.com/-kuEY4BZ_J38/UfUIS585pLI/AAAAAAAADCQ/VTD0GIlJhdg/PagerWithIssuesFixed_thumb7.png?imgmax=800" width="820" height="411"></a></p> <p><strong>Figure 4 – pager with issues fixed</strong></p> <p>Next we need to re-write some of the <strong>WritePagerSection</strong> method <strong>Listing 1</strong>.</p><pre class="brush: csharp;">/// <remarks><br>/// Patch provided by Wizzard to support PagerTemplate (CodePlex issue #3368).<br>/// </remarks><br>private void WritePagerSection(HtmlTextWriter writer, PagerPosition pos)<br>{<br> GridView gridView = Control as GridView;<br> if ((gridView != null) &&<br> gridView.AllowPaging &&<br> gridView.PagerSettings.Visible &&<br> (gridView.PageCount > 1) &&<br> ((gridView.PagerSettings.Position == pos) || (gridView.PagerSettings.Position == PagerPosition.TopAndBottom)))<br> {<br> GridViewRow pagerRow = (pos == PagerPosition.Top) ? gridView.TopPagerRow : gridView.BottomPagerRow;<br> string className = GetRowClass(gridView, pagerRow);<br> className += " AspNet-GridView-" + (pos == PagerPosition.Top ? "Top " : "Bottom ");<br><br> //check for PagerTemplate<br> if (gridView.PagerTemplate != null)<br> {<br> if (gridView.PagerStyle != null)<br> {<br> className += gridView.PagerStyle.CssClass;<br> }<br> className = className.Trim();<br><br> writer.WriteLine();<br> writer.WriteBeginTag("div");<br> writer.WriteAttribute("class", className);<br> writer.Write(HtmlTextWriter.TagRightChar);<br> writer.Indent++;<br><br> if (pagerRow != null)<br> {<br> foreach (TableCell cell in pagerRow.Cells)<br> {<br> foreach (Control ctrl in cell.Controls)<br> {<br> ctrl.RenderControl(writer);<br> }<br> }<br> }<br><br> writer.Indent--;<br> writer.WriteEndTag("div");<br> }<br> else //if not a PagerTemplate <br> {<br> Table innerTable = null;<br> if ((pos == PagerPosition.Top) &&<br> (gridView.TopPagerRow != null) &&<br> (gridView.TopPagerRow.Cells.Count == 1) &&<br> (gridView.TopPagerRow.Cells[0].Controls.Count == 1) &&<br> typeof(Table).IsAssignableFrom(gridView.TopPagerRow.Cells[0].Controls[0].GetType()))<br> {<br> innerTable = gridView.TopPagerRow.Cells[0].Controls[0] as Table;<br> }<br> else if ((pos == PagerPosition.Bottom) &&<br> (gridView.BottomPagerRow != null) &&<br> (gridView.BottomPagerRow.Cells.Count == 1) &&<br> (gridView.BottomPagerRow.Cells[0].Controls.Count == 1) &&<br> typeof(Table).IsAssignableFrom(gridView.BottomPagerRow.Cells[0].Controls[0].GetType()))<br> {<br> innerTable = gridView.BottomPagerRow.Cells[0].Controls[0] as Table;<br> }<br><br> if ((innerTable != null) && (innerTable.Rows.Count == 1))<br> {<br> if (gridView.PagerStyle != null)<br> {<br> className += gridView.PagerStyle.CssClass;<br> }<br> className = className.Trim();<br><br> writer.WriteLine();<br> writer.WriteBeginTag("div");<br> writer.WriteAttribute("class", className);<br> writer.Write(HtmlTextWriter.TagRightChar);<br> writer.Indent++;<br><br> TableRow row = innerTable.Rows[0];<br> foreach (TableCell cell in row.Cells)<br> {<br> foreach (Control ctrl in cell.Controls)<br> {<br> writer.WriteLine();<br> ctrl.RenderControl(writer);<br> }<br> }<br><br> writer.Indent--;<br> writer.WriteLine();<br> writer.WriteEndTag("div");<br> }<br> }<br> }<br>}
</pre><strong>Listing 1 – WritePagerSection method<br></strong>
<p>One of the main issues and it’s to my shame <img class="wlEmoticon wlEmoticon-embarrassedsmile" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="Embarrassed smile" src="http://lh3.ggpht.com/-MQ5GHmJU0k4/UfUITaKQTEI/AAAAAAAADCU/8RkFACRqwCY/wlEmoticon-embarrassedsmile%25255B2%25255D.png?imgmax=800"> I originally wrote this section. So here is the issue I am surrounding the pagers with a DIV instead of the correct section this means that the </p><pre class="brush: csharp;"><table><br> <thead><br> ...<br> </thead><br> <tbody><br> ...<br> </tbody><br> <tfoot><br> <tr> --footer goes here-- </tr><br> </tfoot><br></table>
</pre>
<p><strong>Listing 2 - </strong></p>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5YSfOl173Ma_KZDxNKlABmejJ3e44KFgg8dJFOUV79Ki0yKxUHszipEVP95DB35j37c3FH90k0NpXRJiNiZU1YKZ5Y0tXo9XACHF_0H1sT7M58pgfJkDSm3v37CmvWfJXM0cdbHPNCA8/s1600-h/TheDefaultGridViewAdapterInUseIssueDivAndPositionIssue%25255B5%25255D.png" target="_blank"><img title="The Default GridView Adapter In Use Issue Div And Position Issue" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="The Default GridView Adapter In Use Issue Div And Position Issue" src="http://lh3.ggpht.com/-kmvI0m02g_U/UfUIUSFgGcI/AAAAAAAADCo/MKAom5kkzFM/TheDefaultGridViewAdapterInUseIssueDivAndPositionIssue_thumb%25255B3%25255D.png?imgmax=800" width="994" height="774"></a></p>
<p><strong>Figure 5 - The Default GridView Adapter In Use DIV and Position Issue </strong></p>
<p>There are two issues here the first is that the pager is positioned outside the table when its rendered and second it’s in a DIV as mentioned above so we need to modify this section to place the pager inside the table and in side a TFOOT section when at the bottom and a THEAD when at the top. </p>
<p><a href="http://lh3.ggpht.com/-DlJcI8IR1C0/UfUIVHn132I/AAAAAAAADCw/0iG7Tk5NRvk/s1600-h/MovePagerInsideTableHeader%25255B5%25255D.png" target="_blank"><img title="Move Header Pager Inside Table" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Move Header Pager Inside Table" src="http://lh6.ggpht.com/-kHlHpDlHCWE/UfUIVlrG5HI/AAAAAAAADC0/JwGhtkCekCs/MovePagerInsideTableHeader_thumb%25255B3%25255D.png?imgmax=800" width="560" height="432"></a></p>
<p><strong>Figure 6 – Move Header Pager Inside Table </strong></p>
<p><a href="http://lh6.ggpht.com/-7D4S5ggvgjg/UfUIWJRM7EI/AAAAAAAADDA/YtttasxBxVU/s1600-h/MovePagerInsideTableFooter%25255B6%25255D.png" target="_blank"><img title="Move Footer Pager Inside Table" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Move Footer Pager Inside Table" src="http://lh5.ggpht.com/-d7b2B1klWI0/UfUIWzhwN-I/AAAAAAAADDI/BJaiZLf3NHg/MovePagerInsideTableFooter_thumb%25255B4%25255D.png?imgmax=800" width="578" height="227"></a></p>
<p><strong>Figure 7 – Move Footer Pager Inside Table</strong></p><pre class="brush: csharp;">/// <remarks><br>/// Patch provided by Wizzard to support PagerTemplate (CodePlex issue #3368).<br>/// </remarks><br>private void WritePagerSection(HtmlTextWriter writer, PagerPosition pos)<br>{<br> GridView gridView = Control as GridView;<br> string tableHeaderFooter = pos == PagerPosition.Top ? "thead" : "tfoot";<br> string tableCell = pos == PagerPosition.Top ? "th" : "td";<br><br> if ((gridView != null) && gridView.AllowPaging && gridView.PagerSettings.Visible && (gridView.PageCount > 1) &&<br> ((gridView.PagerSettings.Position == pos) || (gridView.PagerSettings.Position == PagerPosition.TopAndBottom)))<br> {<br> GridViewRow pagerRow = (pos == PagerPosition.Top) ? gridView.TopPagerRow : gridView.BottomPagerRow;<br> string className = GetRowClass(gridView, pagerRow);<br> //className += " " + (pos == PagerPosition.Top ? "Top " : "Bottom ");<br><br> //check for PagerTemplate<br> if (gridView.PagerTemplate != null)<br> {<br> if (gridView.PagerStyle != null)<br> {<br> className += gridView.PagerStyle.CssClass;<br> }<br> className = className.Trim();<br><br> // get pager section type<br> writer.WriteLine();<br> writer.WriteBeginTag(tableHeaderFooter); // change div to tfoot<br> writer.WriteAttribute("class", className);<br> writer.Write(HtmlTextWriter.TagRightChar);<br> writer.Indent++;<br><br> // add opening row<br> writer.WriteBeginTag("tr");<br> writer.Write(HtmlTextWriter.TagRightChar);<br> writer.Indent++;<br><br> // add opening cell<br> writer.WriteBeginTag(tableCell);<br> // add colspan to cell<br> writer.WriteAttribute("colspan", gridView.HeaderRow.Cells.Count.ToString());<br> writer.Write(HtmlTextWriter.TagRightChar);<br> writer.Indent++;<br><br> if (pagerRow != null)<br> {<br> foreach (TableCell cell in pagerRow.Cells)<br> {<br> foreach (Control ctrl in cell.Controls)<br> {<br> ctrl.RenderControl(writer);<br> }<br> }<br> }<br><br> // add closing cell<br> writer.Indent--;<br> writer.WriteEndTag(tableCell);<br><br> // add closing row<br> writer.Indent--;<br> writer.WriteEndTag("tr");<br><br> writer.Indent--;<br> writer.WriteEndTag(tableHeaderFooter); // change div to tfoot<br> }<br> else //if not a PagerTemplate <br> {<br> Table innerTable = null;<br> if ((pos == PagerPosition.Top) &&<br> (gridView.TopPagerRow != null) &&<br> (gridView.TopPagerRow.Cells.Count == 1) &&<br> (gridView.TopPagerRow.Cells[0].Controls.Count == 1) &&<br> typeof(Table).IsAssignableFrom(gridView.TopPagerRow.Cells[0].Controls[0].GetType()))<br> {<br> innerTable = gridView.TopPagerRow.Cells[0].Controls[0] as Table;<br> }<br> else if ((pos == PagerPosition.Bottom) &&<br> (gridView.BottomPagerRow != null) &&<br> (gridView.BottomPagerRow.Cells.Count == 1) &&<br> (gridView.BottomPagerRow.Cells[0].Controls.Count == 1) &&<br> typeof(Table).IsAssignableFrom(gridView.BottomPagerRow.Cells[0].Controls[0].GetType()))<br> {<br> innerTable = gridView.BottomPagerRow.Cells[0].Controls[0] as Table;<br> }<br><br> if ((innerTable != null) && (innerTable.Rows.Count == 1))<br> {<br> if (gridView.PagerStyle != null)<br> {<br> className += gridView.PagerStyle.CssClass;<br> }<br> className = className.Trim();<br><br> writer.WriteLine();<br> writer.WriteBeginTag(tableHeaderFooter);<br> writer.WriteAttribute("class", className);<br> writer.Write(HtmlTextWriter.TagRightChar);<br> writer.Indent++;<br><br> TableRow row = innerTable.Rows[0];<br> foreach (TableCell cell in row.Cells)<br> {<br> foreach (Control ctrl in cell.Controls)<br> {<br> writer.WriteLine();<br> ctrl.RenderControl(writer);<br> }<br> }<br><br> writer.Indent--;<br> writer.WriteLine();<br> writer.WriteEndTag(tableHeaderFooter);<br> }<br> }<br> }<br>}
</pre>
<p><strong>Listing 3 – Updated WritePagerSection</strong></p>
<p> </p>
<p>The gives us </p>
<p><a href="http://lh3.ggpht.com/-ecg8vlfdV30/UfUIXWs4AoI/AAAAAAAADDQ/_g9RdI3pN_I/s1600-h/TheDefaultGridViewAdapterInUseWithPa.png" target="_blank"><img title="The Default GridViewAdapter In Use With Pager Fixed" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="The Default GridViewAdapter In Use With Pager Fixed" src="http://lh6.ggpht.com/-2ts5L9PknRc/UfUIYI6YA-I/AAAAAAAADDY/1_sxkBLI_G4/TheDefaultGridViewAdapterInUseWithPa%25255B2%25255D.png?imgmax=800" width="995" height="788"></a></p>
<p><strong>Figure 6 – The default GridViewAdapter in use with pager issue fixed</strong></p>
<h4>Adapting the GridView Adapter</h4>
<p>If we look through the code of the GridView Adapter we will see lots of CSS classes being added these are mostly surplus to our need so we will remove them, also there are attributes being added that we don’t want such as those seen in <strong>Figure 6</strong> section <strong>1</strong> has some attributes we do not want as we will control this via CSS and in <strong>2</strong> you can see one of the unwanted CSS classes being added, this style is for the caption which Bootstrap already styles.</p>
<p><a href="http://lh5.ggpht.com/--eyxaMcO9W4/UfUIYh9BPaI/AAAAAAAADDg/f3vFjIelJzs/s1600-h/SomeUnwantedCode5.png" target="_blank"><img title="Some Unwanted Code" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Some Unwanted Code" src="http://lh6.ggpht.com/-UfoX2HRIuw0/UfUIZaHLcmI/AAAAAAAADDo/R6e2irEZC0M/SomeUnwantedCode_thumb3.png?imgmax=800" width="662" height="605"></a></p>
<p><strong>Figure 7 – the creating the table tag</strong></p>
<p>
<div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffffcc"><strong>Note: </strong>The <table> <strong>cellpadding</strong> and <strong>cellspacing</strong> attributes are not supported in HTML5. </div><pre>writer.WriteAttribute("cellpadding", "0");
writer.WriteAttribute("cellspacing", "0");
</pre>
<p>For block (2) since there is no Caption.CssClass on the GridView we cannot revert to just showing this if you feel the need for an specific class for the Caption element then feel free to add one by changing the appropriate line.</p>
<p>So the one thing that we can’t get for free as it were from Bootstrap on table formatting is the selected row see the <a href="http://twitter.github.io/bootstrap/css/#tables-row-classes" target="_blank">Bootstrap Documentation</a> so we need to make sure the SelectedRowStyle.CssClass is used for that se we need to look at the GetRowClass private method in the GridViewAdaptor see <strong>Listing 4</strong> we need to make sure each property is only adding the specified CssClass. The main thing we do not need in <strong>Listing 4</strong> is the “AspNet-GridView-xxxx” classes we only want the classes we specify explicitly to be used.</p>
<p><pre class="brush: csharp;">/// <summary><br>/// Gets the row's CSS class.<br>/// </summary><br>/// <param name="gridView">The grid view.</param><br>/// <param name="row">The row.</param><br>/// <returns>The CSS class.</returns><br>/// <remarks><br>/// Modified 10/31/2007 by SelArom to create CSS classes for all different row types and states.<br>/// </remarks><br>private string GetRowClass(GridView gridView, GridViewRow row)<br>{<br> string className = row.CssClass;<br><br> switch (row.RowType)<br> {<br> case DataControlRowType.Header:<br> className += " AspNet-GridView-Header " + gridView.HeaderStyle.CssClass;<br> break;<br> case DataControlRowType.Footer:<br> className += " AspNet-GridView-Footer " + gridView.FooterStyle.CssClass;<br> break;<br> case DataControlRowType.EmptyDataRow:<br> className += " AspNet-GridView-Empty " + gridView.EmptyDataRowStyle.CssClass;<br> break;<br> case DataControlRowType.Separator:<br> className += " AspNet-GridView-Separator ";<br> break;<br> case DataControlRowType.Pager:<br> className += " AspNet-GridView-Pagination " + gridView.PagerStyle.CssClass;<br> break;<br> case DataControlRowType.DataRow:<br> switch (row.RowState)<br> {<br> case DataControlRowState.Normal:<br> className += " AspNet-GridView-Normal " + gridView.RowStyle.CssClass;<br> break;<br> case DataControlRowState.Alternate:<br> className += " AspNet-GridView-Alternate " + gridView.AlternatingRowStyle.CssClass;<br> break;<br> case DataControlRowState.Selected | DataControlRowState.Normal:<br> case DataControlRowState.Selected | DataControlRowState.Alternate:<br> className += " AspNet-GridView-Selected " + gridView.SelectedRowStyle.CssClass;<br> break;<br> case DataControlRowState.Edit | DataControlRowState.Normal:<br> case DataControlRowState.Edit | DataControlRowState.Alternate:<br> className += " AspNet-GridView-Edit " + gridView.EditRowStyle.CssClass;<br> break;<br> case DataControlRowState.Insert:<br> className += " AspNet-GridView-Insert ";<br> break;<br> }<br> break;<br> }<br><br> return className.Trim();<br>}
</pre><br>
<p><strong>Listing 4 – GetRowClass private method</strong></p>
<p> </p><pre class="brush: csharp;">/// <summary><br>/// Gets the row's CSS class.<br>/// </summary><br>/// <param name="gridView">The grid view.</param><br>/// <param name="row">The row.</param><br>/// <returns>The CSS class.</returns><br>/// <remarks><br>/// Modified 2013-07-27 by Stephen J Naughton to use default CSS classes for each row type.<br>/// </remarks><br>private string GetRowClass(GridView gridView, GridViewRow row)<br>{<br> string className = row.CssClass;<br><br> switch (row.RowType)<br> {<br> case DataControlRowType.Header:<br> className += gridView.HeaderStyle.CssClass;<br> break;<br> case DataControlRowType.Footer:<br> className += gridView.FooterStyle.CssClass;<br> break;<br> case DataControlRowType.EmptyDataRow:<br> className += gridView.EmptyDataRowStyle.CssClass;<br> break;<br> case DataControlRowType.Separator:<br> // we may want to indicate that there is a Separator here<br> className += " separator "; // need to check that this are not already in use in Bootstrap<br> break;<br> case DataControlRowType.Pager:<br> className += gridView.PagerStyle.CssClass;<br> break;<br> case DataControlRowType.DataRow:<br> switch (row.RowState)<br> {<br> case DataControlRowState.Normal:<br> className += gridView.RowStyle.CssClass;<br> break;<br> case DataControlRowState.Alternate:<br> className += gridView.AlternatingRowStyle.CssClass;<br> break;<br> case DataControlRowState.Selected | DataControlRowState.Normal:<br> case DataControlRowState.Selected | DataControlRowState.Alternate:<br> className += gridView.SelectedRowStyle.CssClass;<br> break;<br> case DataControlRowState.Edit | DataControlRowState.Normal:<br> case DataControlRowState.Edit | DataControlRowState.Alternate:<br> className += gridView.EditRowStyle.CssClass;<br> break;<br> case DataControlRowState.Insert:<br> // we may want to indicate that there is an insert here<br> className += " insert "; // need to check that this are not already in use in Bootstrap<br> break;<br> }<br> break;<br> }<br><br> return className.Trim();<br>}
</pre>
<p><strong>Listing 5 – Updated GetRowClass</strong></p>
<p><strong>Listing 5</strong> fixes up the GetRowClass so now we can specify our own CSS class for the parts of the grid we want to override.</p>
<h4>Adding a Bootstrap Pager to the GridView Adapter</h4>
<p>The last thing I want to do is add a <a href="http://twitter.github.io/bootstrap/components/#pagination" target="_blank">Bootstrap compatible pager</a> </p>
<p><a href="http://lh3.ggpht.com/-HEMa-PwpUDM/Uf0dJzme93I/AAAAAAAADD4/4qrb_edybE8/s1600-h/BootstrapPager5.png" target="_blank"><img title="Bootstrap Pager" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Bootstrap Pager" src="http://lh5.ggpht.com/-9sNUvgKam6k/Uf0dKQOOSfI/AAAAAAAADEA/mIax_AGQPJI/BootstrapPager_thumb3.png?imgmax=800" width="283" height="77"></a></p>
<p><strong>Figure 8 – Bootstrap Pager</strong></p>
<p>I will continue this post with the fancy pager next time.</p><a href="https://skydrive.live.com/?cid=96845E7B0FAC1EED&id=96845E7B0FAC1EED!1723">See my SkyDrive here for download details</a> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com2tag:blogger.com,1999:blog-6907873803403737979.post-85823143704315048652013-07-21T13:30:00.001+01:002013-07-21T18:16:32.834+01:00Bootstrap Friendly Dynamic Data<div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #ff0000; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffdddd"><strong>!Important: </strong>My first Blog Post since my heart attack <img class="wlEmoticon wlEmoticon-brokenheart" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="Broken heart" src="http://lh5.ggpht.com/-dCRwOge8luo/UewXbcNT_1I/AAAAAAAADBA/KTLXweVpLHE/wlEmoticon-brokenheart%25255B2%25255D.png?imgmax=800"> back on January 27th 2013 and then a triple heart bypass three weeks later, but I am back and feeling well <img class="wlEmoticon wlEmoticon-redheart" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="Red heart" src="http://lh5.ggpht.com/-766JluvEiRc/UewXb7gB4vI/AAAAAAAADBI/Hc4wRISRrcA/wlEmoticon-redheart%25255B2%25255D.png?imgmax=800">. </div> <p>Microsoft announced that Twitter-Bootstrap integration in the <a href="http://channel9.msdn.com/Events/Build/2013/1-002" target="_blank">Build 2013 Day 2 Keynote</a> (look at 15:00 index) this is cool (to be honest it had not been on my radar before this <img class="wlEmoticon wlEmoticon-embarrassedsmile" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="Embarrassed smile" src="http://lh4.ggpht.com/-kJCFdL8UOww/UewU9a1aOhI/AAAAAAAAC84/qwL2mxR0tfE/wlEmoticon-embarrassedsmile%25255B2%25255D.png?imgmax=800">) but unless Microsoft produce new Dynamic Data Bootstrap templates we will need to roll them ourselves.</p> <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffffcc"><strong>Note: </strong>I intend to integrate this and my own custom project templates into the new One ASP.Net thingy (at the moment it’s a bit of a Magic Unicorn until the extensibility is out for us to bolt onto).</div> <p><a href="http://twitter.github.io/bootstrap/" target="_blank"><img title="Bootstrap" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Bootstrap" src="http://lh3.ggpht.com/-DKjrXW5uHlI/UewU94OftuI/AAAAAAAAC9A/rka83XG2urE/Bootstrap%25255B4%25255D.png?imgmax=800" width="147" height="135"></a><a href="http://bootswatch.com/" target="_blank"><img title="Bootswatch" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Bootswatch" src="http://lh4.ggpht.com/-11qelm5PWbE/UewU-X9OSRI/AAAAAAAAC9I/-IoiGXBV_dM/Bootswatch%25255B4%25255D.png?imgmax=800" width="147" height="135"></a></p> <p><strong>Figure – 1 Bootstrap formerly Twitter-Bootstrap and the free themes site Bootswatch.com</strong></p> <p>For a great introduction to Bootstrap visit <a href="http://pluralsight.com/" target="_blank">Pluralsight.com</a> and watch the <a href="http://pluralsight.com/training/courses/TableOfContents?courseName=bootstrap-introduction&highlight=scott-allen_bootstrap-m1-introduction!scott-allen_bootstrap-m5-javascript!scott-allen_bootstrap-m4-components!scott-allen_bootstrap-m3-everyday!scott-allen_bootstrap-m2-layout#bootstrap-m1-introduction" target="_blank">Introduction to Bootstrap</a> course.</p> <p>So I tried to Bootstrapify (My new word <img class="wlEmoticon wlEmoticon-Inlove" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="In love" src="http://lh5.ggpht.com/-blU6q_ixDsc/UewU-6Bl_EI/AAAAAAAAC9Q/R3CaczxWpqs/wlEmoticon-Inlove%25255B2%25255D.png?imgmax=800">) the standard Dynamic Data project Template and the first issue I came across is seen in <strong>Figure 2</strong> which show the standard mark-up produced by <a href="http://www.asp.net/web-forms" target="_blank">ASP.Net Web Forms</a> (and it’s worth noting that as of the June 2013 Visual Studios 2013 Preview we still have the same issue) and out of the box I cannot seem to find a way of turning the unhelpful mark-up off.</p> <p><a href="http://lh5.ggpht.com/-S43CJTE_SDs/UewU_MUslYI/AAAAAAAAC9Y/BsRDsRJTTdM/s1600-h/table-mark-up-Issues%25255B4%25255D.png"><img title="table-mark-up-Issues" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="table-mark-up-Issues" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1vkZEby5ojRekFtYmCUfcpjZvaauc12IFad9rmod_Fiat7Mpu6d3HHHj3XiWIck0GiwBC_fF77UiXLAyNrfjwEaKkvg0M4YrPak3qBIeZWCutoTB7R5UKPc5DM2QMMSONj_HybDpzX7s/?imgmax=800" width="534" height="91"></a></p> <p><strong>Figure 2 – standard Table mark-up produced by .Net 4.5</strong></p> <p>So what is out next move well if you think back to the <a href="http://www.asp.net/cssadapters/" target="_blank">ASP.NET 2.0 CSS Friendly Control Adapters 1.0</a> (source here <a href="http://www.google.co.uk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CC8QFjAA&url=http%3A%2F%2Fcssfriendly.codeplex.com%2F&ei=X-jrUcWOI8mAhQeMsIGwCw&usg=AFQjCNGRDHZvsrj6eV-S91c1haEokWGqyg&sig2=86XK6NywBU7JtZkkJR-oiw&bvm=bv.49478099,d.ZG4&cad=rja" target="_blank">CSS Friendly Control Adapters</a><em></em>) from ASP.Net 2.0 there is a way around this.</p> <p>So step one was to download the source and get the project updated to VS2012 and fix up the GridView</p> <p> <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffffcc"><strong>Note:</strong> We are going to build our own Control adaptor as the we go but for now I just tested with the standard <a href="http://www.asp.net/cssadapters/">ASP.NET 2.0 <em>CSS Friendly Control Adapters</em> 1.0</a> to see what difference it made.</div> <h4>Add Bootstrap to the Dynamic Data Project</h4> <p>Add Bootstrap and jQuery (there appears to be no dependency on the Bootstrap package so you will need to add jQuery manually) to the Dynamic data application using <a href="http://www.nuget.org/" target="_blank">NuGet</a> </p> <p><a href="http://lh5.ggpht.com/-9Qg3L5jHFDg/UewVALA4QyI/AAAAAAAAC9o/R2GgtSuToaY/s1600-h/add-bootstrap-using-nuget%25255B3%25255D.png" target="_blank"><img title="add-bootstrap-using-nuget" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="add-bootstrap-using-nuget" src="http://lh6.ggpht.com/-MX-NuF08i9k/UewVAw4G49I/AAAAAAAAC9w/zbNLQaXtJas/add-bootstrap-using-nuget_thumb%25255B1%25255D.png?imgmax=800" width="244" height="164"></a></p> <p><strong>Figure 3 – Add Bootstrap</strong></p> <h4>Now we wire up the styles and scripts</h4> <p>In the templates supplied with Visual Studio 2012 you will note that the jQuery is wired up in the Global.asax.cs file (I am assuming Web Application Project here)</p> <p> <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffffcc"><strong>Note: </strong>I know we are no using JavaScript right now but we will later in the series so lets have it wired up now and be ready </div> <p><a href="http://lh3.ggpht.com/-LDy4PfuKxtA/UewVBSoZ2KI/AAAAAAAAC94/NdoYJCWqIGE/s1600-h/jQuery%25255B4%25255D.png"><img title="jQuery" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="jQuery" src="http://lh5.ggpht.com/-SHyIa4oc6ZE/UewVBznt_II/AAAAAAAAC98/ypPtoceLbm0/jQuery_thumb%25255B2%25255D.png?imgmax=800" width="686" height="222"></a></p> <p><strong>Figure 4 – jQuery 1.7.1</strong></p> <p>we need to update this to the latest version of jQuery (at the time of writing that was 2.0.3) see <strong>Figures 5 & 6</strong> for the updates to Global.asax.cs and Site.master files.</p> <p><a href="http://lh6.ggpht.com/-apoVG5j8qsk/UewVCSnojtI/AAAAAAAAC-I/TDIYqXKxGWw/s1600-h/jQuery-and-Bootstrap-scripts%25255B4%25255D.png"><img title="jQuery-and-Bootstrap-scripts" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="jQuery-and-Bootstrap-scripts" src="http://lh4.ggpht.com/-mw0RUhBXTzs/UewVC2-cFjI/AAAAAAAAC-Q/fff5HFWH4Zg/jQuery-and-Bootstrap-scripts_thumb%25255B2%25255D.png?imgmax=800" width="711" height="334"></a></p> <p><strong>Figure 5 – jQuery and Bootstrap scripts</strong></p> <p><a href="http://lh3.ggpht.com/-kT5pcy6RMK0/UewVDRmVkLI/AAAAAAAAC-U/H9gBG86hOEY/s1600-h/bootstrap-added-to-site.master%25255B4%25255D.png"><img title="bootstrap-added-to-site.master" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="bootstrap-added-to-site.master" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI8e5hwKSJNAucjgWmkTlU31KB6BD5W_ILoc4GmEfS4xzY7aWtXY2tp9XckSkglqiVQ79dLjybi51DpFfU9uYiYM8VTHAHKAR5wfCe4gCw1lC5NXqikX8iC11Pio0eu0o9u-znstAtmoE/?imgmax=800" width="596" height="150"></a></p> <p><strong>Figure 6 – add the script reference to the Site.master file mark-up</strong></p> <h4>Change the default CSS class for tables in out projects</h4> <p><a href="http://lh6.ggpht.com/-0qe6pFb0Nlk/UewVEZA8ZlI/AAAAAAAAC-o/WIOaIRc0dfg/s1600-h/css-styling%25255B9%25255D.png"><img title="css-styling" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="css-styling" src="http://lh6.ggpht.com/-W3sqf1dKKPM/UewVEwjuMbI/AAAAAAAAC-w/WZk2LnjP1zs/css-styling_thumb%25255B5%25255D.png?imgmax=800" width="729" height="517"></a></p> <p><strong>Figure 7 – Standard GridView mark-up</strong></p> <p>We will need to change all the CSS classes but for now we will simply replace the main CssClass on the GridView, change:</p><pre>CssClass="DDGridView"
</pre>
<p>to</p><pre>CssClass="table"
</pre>
<p>We will do a Replace in Files (Ctrl+Shift+H) gets us the dialog shown in <strong>Figure 8</strong> </p>
<p><a href="http://lh4.ggpht.com/-a_tlKl4Se_0/UewVFTz-76I/AAAAAAAAC-4/x-KJ74olUj8/s1600-h/replace-all-grid-view-css-classes%25255B9%25255D.png"><img title="replace-all-grid-view-css-classes" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="replace-all-grid-view-css-classes" src="http://lh3.ggpht.com/-xbhq9_piNO0/UewVGIO-VwI/AAAAAAAAC_A/w8GNBPy24ik/replace-all-grid-view-css-classes_thumb%25255B5%25255D.png?imgmax=800" width="390" height="549"></a></p>
<p><strong>Figure 8 – Replace in files</strong></p>
<h4>Replace the default CSS style sheet with the Bootstrap style sheet</h4>
<p>In the head of the Site.master file replace the default css style sheet with bootstrap’s style sheet. Make the changes shown between <strong>Figure 9</strong> and<strong> Figure 10</strong></p>
<p><a href="http://lh5.ggpht.com/-2nZvwTkhySU/UewVGgf2jMI/AAAAAAAAC_I/Hsp5AKffnnI/s1600-h/dynamic-data-default-style-sheet%25255B4%25255D.png"><img title="dynamic-data-default-style-sheet" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="dynamic-data-default-style-sheet" src="http://lh6.ggpht.com/-8RXDmLuw7NM/UewVHPG5CwI/AAAAAAAAC_Q/A5I1spkYLpM/dynamic-data-default-style-sheet_thumb%25255B2%25255D.png?imgmax=800" width="494" height="151"></a></p>
<p><strong>Figure 9 – the Default Dynamic Data style sheet</strong></p>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUwbADmgVgdINEkUx0QyOseZg7aC_3khBGQWcrQXLgEE8b_m0mjljipwEgvyPmqu0vHTtF2vjxX7JH2k4TxBxvceY0FzbRSD14nMa_FQuCn9sJFW6T759_G6A33EfJwYYe9kTR93YgM2I/s1600-h/bootstrap-style-sheets%25255B4%25255D.png"><img title="bootstrap-style-sheets" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="bootstrap-style-sheets" src="http://lh4.ggpht.com/-9U_i8iWhxHw/UewVIN6PNVI/AAAAAAAAC_g/1vHCgeQclx4/bootstrap-style-sheets_thumb%25255B2%25255D.png?imgmax=800" width="571" height="161"></a></p>
<p><strong>Figure 10 – Bootstraps style sheets</strong></p>
<h4>Now we are ready to run the site and test the GridViews mark-up</h4>
<p>As you can see if we view one of the data tables now we will see the issue in action <strong>Figure 11</strong> the mark-up is not helping us here.</p>
<p><a href="http://lh5.ggpht.com/-z7TLO_BIt30/UewVI3DFxrI/AAAAAAAAC_o/6kgtapR8EzE/s1600-h/webforms-gridview-before-fixing-its-output-mark-up%25255B4%25255D.png"><img title="webforms-gridview-before-fixing-its-output-mark-up" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="webforms-gridview-before-fixing-its-output-mark-up" src="http://lh3.ggpht.com/-orsBLZBd3GM/UewVJb0xCbI/AAAAAAAAC_w/PVuNEqThTq0/webforms-gridview-before-fixing-its-output-mark-up_thumb%25255B2%25255D.png?imgmax=800" width="586" height="443"></a></p>
<p><strong>Figure 11 – WebForms GridViewbefore fixing its output mark up</strong></p>
<h4>Adding the default <a href="http://www.asp.net/cssadapters/" target="_blank">ASP.NET 2.0 CSS Friendly Control Adapters</a> to our project </h4>
<p>Adding the default <a href="http://www.asp.net/cssadapters/" target="_blank">ASP.NET 2.0 CSS Friendly Control Adapters</a> to our project you can just download the <strong>dll</strong> and the <strong>.browser</strong> files and add a reference to the DLL and copy the .browser file to the an <strong>App_Browsers</strong> folder.</p>
<p><a href="http://lh4.ggpht.com/-UK1NT2EAdsM/UewVKLs3e5I/AAAAAAAAC_4/dbTb-x-fZRs/s1600-h/add-app-browsers-folder%25255B4%25255D.png"><img title="add-app-browsers-folder" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="add-app-browsers-folder" src="http://lh6.ggpht.com/-lDJNZ9U_jnI/UewVK5BmGuI/AAAAAAAADAA/93etxYsSfco/add-app-browsers-folder_thumb%25255B2%25255D.png?imgmax=800" width="631" height="285"></a></p>
<p><strong>Figure 12 – Add a App_Browsers folder</strong></p>
<p><a href="http://lh5.ggpht.com/-KIxq2qJxHq4/UewVLB-k1II/AAAAAAAADAI/Pl2oh2S1z4Y/s1600-h/add-reference-to-the-css-friendly-dll-and-add-a-copy-of-the-css-friendly-adapters-browser-file%25255B4%25255D.png"><img title="add-reference-to-the-css-friendly-dll-and-add-a-copy-of-the-css-friendly-adapters-browser-file" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="add-reference-to-the-css-friendly-dll-and-add-a-copy-of-the-css-friendly-adapters-browser-file" src="http://lh6.ggpht.com/-ZHLBmUYaYPA/UewVLlGrAZI/AAAAAAAADAQ/E9xX5fA0JEk/add-reference-to-the-css-friendly-dll-and-add-a-copy-of-the-css-friendly-adapters-browser-file_thumb%25255B2%25255D.png?imgmax=800" width="357" height="311"></a></p>
<p><strong>Figure 13 – add a reference to the DLL and copy the CSSFriendlyAdapters.browser file to the App_Browsers folder</strong></p>
<p><a href="http://lh6.ggpht.com/-38pEXMBwnkU/UewVMUjcsLI/AAAAAAAADAY/pbH2NZ_oDBA/s1600-h/gridview-with-the-mark-up-casihng-the-issue-removed-using-css-friendly-control-adapters%25255B4%25255D.png"><img title="gridview-with-the-mark-up-casihng-the-issue-removed-using-css-friendly-control-adapters" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="gridview-with-the-mark-up-casihng-the-issue-removed-using-css-friendly-control-adapters" src="http://lh6.ggpht.com/-Qlp-8dzJ1u4/UewVM6n6YeI/AAAAAAAADAg/Sa6Eu2NOoq8/gridview-with-the-mark-up-casihng-the-issue-removed-using-css-friendly-control-adapters_thumb%25255B2%25255D.png?imgmax=800" width="581" height="441"></a></p>
<p><strong>Figure 14 – GridView with the mark up causing the issue removed using CSS Friendly Control Adapters</strong></p>
<p><a href="http://lh5.ggpht.com/-Sm-vQof3Kvk/UewVNdhPkRI/AAAAAAAADAo/Ef7_ZUj0d90/s1600-h/finally-with-some-of-the-other-nice-table-classes%25255B4%25255D.png"><img title="finally-with-some-of-the-other-nice-table-classes" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="finally-with-some-of-the-other-nice-table-classes" src="http://lh5.ggpht.com/-FqluuCB5Hd4/UewVORFnWEI/AAAAAAAADAw/XtPlIziSnbE/finally-with-some-of-the-other-nice-table-classes_thumb%25255B2%25255D.png?imgmax=800" width="586" height="445"></a></p>
<p><strong>Figure 15 – Now with the following Bootstrap table classes table-bordered and table-striped added</strong></p>
<h4>Conclusion</h4>
<p>In this series we will build our own Control Adapter specifically for Bootstrap to cover:</p>
<ul>
<li>GridView
<li>Menu
<li>SiteMapPath
<li>Login</li></ul>
<p>We will also get the Edit and Details page templates working nicely with Bootstrap and of course all the FieldTemplates and Filters</p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com3tag:blogger.com,1999:blog-6907873803403737979.post-62143350394701729672013-01-16T18:15:00.001+00:002013-01-16T18:21:15.613+00:00Adding Multi Column Sort to Dynamic Data List Page<p>Well this is the first post of 2013 and has been brewing for a while, what we want is to be able to set the initial sort of the GridView on the List page or ListDetails page. <strong>Listing 1</strong> shows what we want to achieve.</p> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="OrderDate sorted Descending and ShipName sorted Ascending" border="0" alt="OrderDate sorted Descending and ShipName sorted Ascending" src="http://lh6.ggpht.com/-qyIWrnRSqQc/UPbuPzJA-TI/AAAAAAAAClM/RJF-Y6uZAZU/Sorted%25255B7%25255D.png?imgmax=800" width="608" height="478"></p> <p><strong>Figure 1 – OrderDate sorted Descending and ShipName sorted Ascending</strong></p> <h3>The Multi Column Sort Attribute</h3> <p><strong>Figure 2</strong> shows the first version of the attribute, I was using magic strings. But in <strong>Figure 3</strong> we have an enum from System.Web.UI.WebControls to help us out (I’m a bad speller and I tend to type too quickly) so I think that is better.</p> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Early Version Of Metadata" border="0" alt="Early Version Of Metadata" src="http://lh4.ggpht.com/-hrSzrIASpFk/UPbuQ5FawsI/AAAAAAAAClQ/oudAmKKseyY/EarlyVersionOfMetadata%25255B5%25255D.png?imgmax=800" width="482" height="97"></p> <p><strong>Figure 2 – Early Version Of Metadata</strong></p> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Example Metadata" border="0" alt="Example Metadata" src="http://lh4.ggpht.com/-UIYV1eXen9w/UPbuRjqjT8I/AAAAAAAAClc/hifHbOaSMrk/ExampleMetadata%25255B6%25255D.png?imgmax=800" width="699" height="100"></p> <p><strong>Figure 3 – Example Metadata</strong></p> <p><strong>Listing 1</strong> shows the MultiColumnSortAttribute I am using the params construct to get a list of values from the attribute and I am using the BuildColumnParametersDictionary method to convert the object array to a dictionary with a string key the column name and a value of the SortDirection.</p><pre class="brush: csharp; ruler: true;">[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]<br>public class MultiColumnSortAttribute : Attribute<br>{<br> private IDictionary<String, SortDirection> _columns;<br><br> public IDictionary<String, SortDirection> Columns<br> {<br> get { return this._columns; }<br> }<br><br> public MultiColumnSortAttribute(params object[] columnParameters)<br> {<br> _columns = BuildColumnParametersDictionary(columnParameters);<br> }<br><br> private IDictionary<String, SortDirection> BuildColumnParametersDictionary(object[] objArray)<br> {<br> var dictionary = new Dictionary<String, SortDirection>();<br> if ((objArray != null) && (objArray.Length != 0))<br> {<br> if ((objArray.Length % 2) != 0)<br> throw new InvalidOperationException(<br> String.Format("Need even number of control parameters.", <br> new object[0]));<br><br> for (int i = 0; i < objArray.Length; i += 2)<br> {<br> if (objArray[i] is String && objArray[i + 1] is SortDirection)<br> {<br> if (objArray[i] == null)<br> throw new InvalidOperationException(<br> String.Format("Column name [{0}] is null.", i));<br><br> // get column name from array<br> String columnName = objArray[i] as String;<br> if (columnName == null)<br> throw new InvalidOperationException(<br> String.Format("Column name '{0}' is not a String.", <br> objArray[i].ToString()));<br><br> // check for duplicate column names<br> if (dictionary.ContainsKey(columnName))<br> throw new InvalidOperationException(<br> String.Format("Column name '{0}' occurs more than once.", <br> columnName));<br><br> // get sort direction from array<br> if (objArray[i + 1] == null)<br> throw new InvalidOperationException(<br> String.Format("Sort direction '{0}' is not a of type SortDirection.", <br> objArray[i].ToString()));<br><br> SortDirection sortDirection = (SortDirection)objArray[i + 1];<br> dictionary[columnName] = sortDirection;<br> }<br> }<br> }<br> return dictionary;<br> }<br>}
</pre>
<p><strong>Listing 1 - MultiColumnSortAttribute</strong></p>
<h3>An Extension Method to Add Multi Column Sort to the Page</h3>
<p>This extension method in <strong>Listing 2</strong> is a little more complicated than it would need to be to handle just the Multi Column Sort, it also handles the DisplayColumn attribute to, this way we cover all bases. <div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"><strong>Note: </strong>The GetAttribute<T>() extension method is covered here <a href="http://csharpbits.notaclue.net/2009/01/writing-attribute-and-extension-methods.html" target="_blank">Writing Attributes and Extension Methods for Dynamic Data</a></div><pre class="brush: csharp; ruler: true;">/// <summary><br>/// Sets the initial sort order.<br>/// </summary><br>/// <param name="queryExtender">The query extender.</param><br>/// <param name="table">The table.</param><br>public static void SetInitialSortOrder(this QueryExtender queryExtender, MetaTable table)<br>{<br> var multiColumnSort = table.GetAttribute<MultiColumnSortAttribute>();<br> if (multiColumnSort != null)<br> {<br> var firstEntry = multiColumnSort.Columns.Keys.First();<br> var order = new OrderByExpression()<br> {<br> DataField = firstEntry,<br> Direction = multiColumnSort.Columns[firstEntry],<br> };<br><br> foreach (var item in multiColumnSort.Columns)<br> {<br> if (item.Key != firstEntry)<br> {<br> order.ThenByExpressions.Add(new ThenBy()<br> {<br> DataField = item.Key,<br> Direction = item.Value<br> });<br> }<br> }<br> queryExtender.Expressions.Add(order);<br> }<br> else if (table.SortColumn != null)<br> {<br> var order = new OrderByExpression()<br> {<br> DataField = table.SortColumn.Name,<br> Direction = table.SortDescending ? SortDirection.Descending : SortDirection.Ascending,<br> };<br> queryExtender.Expressions.Add(order);<br> }<br>}
</pre>
<p><strong>Listing 2 – SetInitialSortOrder Extension Method</strong></p>
<h3>Using in the List Page Template</h3>
<p>All we need to do in the List and ListDetails page templates is to add one line to the Page_Init method.</p><pre class="brush: csharp; ruler: true;">protected void Page_Init(object sender, EventArgs e)<br>{<br> table = DynamicDataRouteHandler.GetRequestMetaTable(Context);<br> GridView1.SetMetaTable(table, table.GetColumnValuesFromRoute(Context));<br> GridDataSource.EntityTypeFilter = table.EntityType.Name;<br><br> // set initial sort order<br> GridQueryExtender.SetInitialSortOrder(table);<br>}
</pre>
<p><strong>Listing 3 – adding the extension method to the Page Template</strong></p>
<h3>Download</h3><iframe height="120" src="https://skydrive.live.com/embed?cid=96845E7B0FAC1EED&resid=96845E7B0FAC1EED%21893&authkey=AMVv_Ebo2DeYzzs" frameborder="0" width="98" scrolling="no"></iframe>
<p>You may need to look through the list of files on my sky drive to find the one you want, it’s called <strong>MultiColumnSort.zip</strong></p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com4tag:blogger.com,1999:blog-6907873803403737979.post-76780661477910493542012-12-20T15:42:00.001+00:002013-01-11T00:32:40.142+00:00Turning you ASP.Net Hyperlinks into images buttons using CSS and jQuery<p>First of all I’m no big <a href="http://jquery.com/" target="_blank">jQuery</a> or CSS geek I know a little and I search the net <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh3.ggpht.com/-AgWDxBCT8v0/UNMx0k7dmnI/AAAAAAAACi4/NERhqUvRn1c/wlEmoticon-smile2.png?imgmax=800"></p> <p>I was building a site for a client who wanted Image buttons not text links and you should know me if you have read past posts I believe Dynamic Data is about changing as little as possible in the pages I like to do it all if possible using the Metadata, so I thought is there a way of doing this using pure CSS, there is sort of but you are still left with the text of the hyperlink, that is where jQuery came in, and then I thought I need to add a CSS class to each button and again jQuery came to my aid. so here we go.</p> <p> <div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"><strong>Note: </strong>I am using the latest <a href="http://visualstudiogallery.msdn.microsoft.com/07d54d12-7133-4e15-becb-6f451ea3bea6" target="_blank">Web Essentials</a> by <a title="Mads Kristensen" href="http://madskristensen.net/" target="_blank">Mads Kristensen</a> and using LESS for my style sheets, you are really missing out if you have VS2012 and are not using this experimental add-in for VS2012. </div> <p> <div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"><strong>Note: </strong>If you don't have VS2012 the you can use <a href="http://www.mindscapehq.com" target="_blank">Mindscape’s</a> <a href="http://visualstudiogallery.msdn.microsoft.com/2b96d16a-c986-4501-8f97-8008f9db141a?SRC=VSIDE" target="_blank">Web Workbench</a> which offers <a href="http://sass-lang.com/" target="_blank">SASS</a>, <a href="http://lesscss.org/" target="_blank">LESS</a> and <a href="http://coffeescript.org/" target="_blank">CoffeeScript</a></div> <p>So the first job is to somehow automatically add the CSS class to each of the buttons that we want to swap to image button. </p><pre class="brush: js; ruler: true;">function NAC_ReplaceHyperLinkWithImageButton() {<br> // array of button commands/names to affect<br> var toMatch = ["Details", "Edit", "Delete", "Update", "Cancel", "Insert", "Select", "New"];<br> // commands/names to replace<br> var toReplace = { "New": "Insert" };<br> $(document).ready(function () {<br> $("TABLE.DDDetailsTable a, TABLE.DDGridView a")<br> .each(function () {<br> // get the inner text<br> var innerText = $(this).text();<br> if ($.inArray(innerText, toMatch) > -1) {<br><br> // do replacement of commands to Replace<br> var found = toReplace[innerText];<br> // check there is a match in the lookup table<br> if (typeof found !== "undefined")<br> innerText = found;<br><br> // get the embedded text<br> $(this).addClass(innerText);<br><br> // add a tooltip<br> $(this).attr('Title', innerText);<br><br> // remove the hyperlinks text<br> $(this).text('');<br> }<br> });<br> });<br>}<br>// run script<br>NAC_ReplaceHyperLinkWithImageButton();<br>// bind script to AJAX bits<br>Sys.Application.add_load(NAC_ReplaceHyperLinkWithImageButton);
</pre>
<p><strong>Listing 1 – jQuery for the swap out</strong></p>
<p>So first of all we have an array this contains ALL the button names (the display text) that we want to affect, next we hook into the jQuery Read event then we are selecting command buttons List, Details, Edit and ListDetails pages using these two selectors:</p><pre>"TABLE.DDDetailsTable a, TABLE.DDGridView a"
</pre>
<p>after that I am using the jQuery <a href="http://api.jquery.com/jQuery.inArray/" target="_blank">inArray</a> function to check if the buttons text is one we want to affect. Then having gotten the innerText form the hyperlink we add the CSS class, then finally we remove the text so only the icon will show.</p>
<p>jQuery is so cool mixed with CSS.</p>
<p><a href="http://lh6.ggpht.com/-rn0owmUL-jc/UNMx1xwr1zI/AAAAAAAACjA/R90fnAtzzBY/s1600-h/ReplaceHyperlinkWithIcons%25255B6%25255D.png" target="_blank"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ReplaceHyperlinkWithIcons" border="0" alt="ReplaceHyperlinkWithIcons" src="http://lh4.ggpht.com/-AP0irAOhaNk/UNMx219xQKI/AAAAAAAACjI/t0a943p-ZhM/ReplaceHyperlinkWithIcons_thumb%25255B4%25255D.png?imgmax=800" width="577" height="360"></a></p>
<p><strong>Figure 1- hyperlinks replace with buttons</strong></p>
<p>Now people say LESS is more and in this case it is.</p><pre class="brush: css; ruler: true;">table.DDGridView a.Cancel,
table.DDDetailsTable a.Cancel
{
width: 20px;
height: 20px;
display: inline-block;
background-repeat: no-repeat;
background-position: center center;
background-image: url('../images/Cancel.png');
}
table.DDGridView a.Cancel:hover,
table.DDDetailsTable a.Cancel:hover
{
background-image: url('../images/Cancel-h.png');
}
table.DDGridView a.Cancel:hover:active,
table.DDDetailsTable a.Cancel:hover:active
{
background-image: url('../images/Cancel-a.png');
}
table.DDGridView a.Cancel.aspNetDisabled,
table.DDDetailsTable a.Cancel.aspNetDisabled,
table.DDGridView a.Cancel.aspNetDisabled:hover,
table.DDDetailsTable a.Cancel.aspNetDisabled:hover,
table.DDGridView a.Cancel.aspNetDisabled:active,
table.DDDetailsTable a.Cancel.aspNetDisabled:active
{
background-image: url('../images/Cancel-d.png');
}
</pre>
<p><strong>Listing 2 – the CSS</strong></p>
<p>above in <strong>Listing 2</strong> is the CSS for the Edit button as you can see we cover hyperlinks with a CSS class of “Edit” and we have three states normal hover and active that is when we click. Now for the LESS</p><pre class="brush: css; ruler: true;">/* ==== button mixin ==== */<br>.Button (@Name)<br>{<br> a.@{Name}<br> {<br> width: 20px;<br> height: 20px;<br> display: inline-block;<br> background-repeat: no-repeat;<br> background-position: center center;<br><br> background-image: url('../images/@{Name}.png');<br><br> &:hover<br> {<br> background-image: url('../images/@{Name}-h.png');<br><br> &:active<br> {<br> background-image: url('../images/@{Name}-a.png');<br> }<br> }<br> // link fix <br> &.aspNetDisabled,<br> &.aspNetDisabled:hover,<br> &.aspNetDisabled:active<br> {<br> background-image: url('../images/@{Name}-d.png');<br> }<br> // link fix <br> }<br>}<br><br>table.DDGridView,<br>table.DDDetailsTable<br>{<br> .Button(Cancel);<br> .Button(Delete);<br> .Button(Details);<br> .Button(Edit);<br> .Button(Update);<br> .Button(New);<br> .Button(Select);<br> .Button(Insert);<br>}
</pre>
<p><strong>Listing 3 – LESS</strong></p>
<p>In <strong>Listing 3</strong> we have a MIXIN called Button and we pass in the name of the button we want, no repeating the same code and if you need to add an extra button it’s easy.</p>
<p>The only thing left is for me to add this to <a href="http://nuget.org" target="_blank">NuGet</a> as a simple to apply package and you are away.</p>
<p>
<div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #f0d0f0; margin: 4px; padding-left: 4px; padding-right: 4px; color: #800080; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"><strong>Updated: </strong>Package now available from <a href="https://nuget.org" target="_blank">NuGet</a> here <a href="https://nuget.org/packages/ReplaceHyperlinkWithImageButton" target="_blank">Replace ASP.Net Hyperlink With Image Button</a> You will need to add a reference in you master page to the CSS and the JavaScript files which will be added to the Style and Scripts folder respectively. </div>
<h3>Adding the NuGet package to an existing Dynamic Data site</h3>
<p>Right Click the “References” node of the Web Application Project</p>
<p><a href="http://lh6.ggpht.com/-CJl0qLmdnE4/UNNWUNlW2VI/AAAAAAAACjY/AFIZn4pSCo0/s1600-h/Adding%252520NuGet%252520Package%25255B5%25255D.png" target="_blank"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Adding NuGet Package" border="0" alt="Adding NuGet Package" src="http://lh3.ggpht.com/-6rvFpBaAvGA/UNNWVQziPII/AAAAAAAACjg/K6HKSAZ21sY/Adding%252520NuGet%252520Package_thumb%25255B3%25255D.png?imgmax=800" width="336" height="224"></a></p>
<p><strong>Figure 1 – Adding NuGet Package to Project</strong></p>
<p><a href="http://lh5.ggpht.com/-A57iwLvlvpw/UNNWWn4fzAI/AAAAAAAACjo/GpOHaI2kkjY/s1600-h/NuGetPackageReplaceHyperlinkWithImageButton%25255B4%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Find the “Replace Hyperlink With Image Button” NuGet Package" border="0" alt="Find the “Replace Hyperlink With Image Button” NuGet Package" src="http://lh3.ggpht.com/-7D5XRADvQaM/UNNWYV5ql2I/AAAAAAAACjw/zPVH4aSYQ10/NuGetPackageReplaceHyperlinkWithImageButton_thumb%25255B2%25255D.png?imgmax=800" width="929" height="310"></a></p>
<p><strong>Figure 2 – Find the “Replace Hyperlink With Image Button” NuGet Package</strong></p>
<p><a href="http://lh3.ggpht.com/-u29-pzr3ATs/UNNWZFsHt3I/AAAAAAAACj4/7y7cABqoMlM/s1600-h/AddingScriptToHead%25255B4%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="AddingScriptToHead" border="0" alt="AddingScriptToHead" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIPM4gJqSiXkbfhTiUA3nIgxktEOaPNIbJQOzXdCJ5bE0KcycrxytJmBGLTI_YsvtiANJrawoQE-1juYKWI9jsU_eetvw_uME43oKJRbOrVgctvAC77QqY9WNQJ2SPzAlemvg_2FCaYBg/?imgmax=800" width="617" height="191"></a></p>
<p><strong>Figure 3 – Add the Style sheet and jQuery references to the head of the Master page</strong> </p>
<p>
<div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"><strong>Note: </strong>the highlighted sections, you will need to add a ~/ and ../ to the start od the CSS and Script links.</div>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0byK9RQ_mE7xyi3TSSaFHiGhnZT0bYz6BGJwmRzJqx7T2o-E5lWBob5lt6FUzoULXq5Z3lhemEmrNuaUa80tTuaIscTjLE2GQz_N06pyRKEKr4XUEHAEGrIfvwGvyLdlY_t18XsZG1ww/s1600-h/AddScriptToEndOfMasterPage%25255B4%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="AddScriptToEndOfMasterPage" border="0" alt="AddScriptToEndOfMasterPage" src="http://lh3.ggpht.com/-7vGrzmo1Bho/UNNWcV0KvII/AAAAAAAACkQ/iCBnzoxvs2Y/AddScriptToEndOfMasterPage_thumb%25255B2%25255D.png?imgmax=800" width="607" height="89"></a></p>
<p><strong>Figure 4 – Add a script tag just before the end of the BODY tag</strong></p>
<p>
<div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"><strong>Note: you </strong>can add your scripts and Style sheets your own way with bundling and minifying this is just an example. </div>
<p>Happy coding.</p>
<p><strong>V1.0.4</strong> now on NuGet you disabled icons if a link’s Enabled property is set to “false”;</p>
<p><a href="http://lh6.ggpht.com/-WZB7kwxpZcc/UN2QoKDkAiI/AAAAAAAACkk/I0j5QdJ4NDI/s1600-h/ReplaceHyperlinkWithIconsDisabledIcons%25255B9%25255D.png" target="_blank"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ReplaceHyperlinkWithDisabledIcons" border="0" alt="Replace Hyperlink With Disabled Icons" src="http://lh5.ggpht.com/-cGRSbuPvxfM/UN2Qo8cUpkI/AAAAAAAACko/to6QqQOVGxY/ReplaceHyperlinkWithIconsDisabledIcons_thumb%25255B5%25255D.png?imgmax=800" width="135" height="133"></a></p>
<p>Hopefully no more changes now.</p>
<div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: red; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"><strong>Warning another change: </strong> v1.0.8 now has better icons and supports disabled buttons including removing the onclick event of the Delete button.</div> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com7tag:blogger.com,1999:blog-6907873803403737979.post-16442083329861113232012-12-14T12:01:00.001+00:002012-12-20T14:58:45.446+00:00ASP.NET and Web Tools 2012.2 (Release Candidate)<p> </p> <p>Scott Hanselman announced <a title="ASP.NET and Web Tools 2012.2 (Release Candidate)" href="http://www.hanselman.com/blog/ASPNETAndWebTools20122ReleaseCandidate.aspx" target="_blank">ASP.NET and Web Tools 2012.2 (Release Candidate)</a> today and it’s great for the first time it’s easy to deploy a DD Web Application Project (WAP) site precompiled and un-editable it’s just a check box now. </p> <p>So install the new tools (get them from here <a href="http://www.microsoft.com/en-us/download/details.aspx?id=36053">Download Page</a> and <a href="http://go.microsoft.com/fwlink/?LinkID=275132">Release notes</a>) <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: #666666; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffffcc"><strong>Note: </strong>If you already have publish settings then VS2012 will import them but they need to be in the root of your site.</div> <p><a href="http://lh6.ggpht.com/-w6SmDFpqTL0/UMsU9zkDoNI/AAAAAAAACh4/GDGGHmkGn-M/s1600-h/New%252520Publish%252520Wizard%25255B4%25255D.png"><img title="New Publish Wizard" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="New Publish Wizard" src="http://lh5.ggpht.com/-4qP6ZjYTTak/UMsU_RIosCI/AAAAAAAACiA/_0Occ3Zk66I/New%252520Publish%252520Wizard_thumb%25255B2%25255D.png?imgmax=800" width="610" height="480"></a></p> <p><strong>Figure 1 - New Publish Wizard</strong></p> <p>Navigate to the Settings Tab and check the “Precompile during publishing” checkbox and then click “Configure”</p> <p><a href="http://lh5.ggpht.com/-gOsaFYZ9wr0/UMsVAdZE0gI/AAAAAAAACiE/lHPykY9ybLA/s1600-h/Disabled%252520Editable%252520markup.%25255B5%25255D.png" target="_blank"><img title="Disabled Editable markup." style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Disabled Editable markup." src="http://lh6.ggpht.com/-v2Nf9Q6eHOQ/UMsVB6CDBSI/AAAAAAAACiQ/yYVa7XQGf_s/Disabled%252520Editable%252520markup._thumb%25255B3%25255D.png?imgmax=800" width="411" height="480"></a></p> <p><strong>Figure 2 - Disabled Editable markup.</strong></p> <p>un-check the “Allow precompiled site to be updatable” checkbox and your pages will no look like this <strong>Figure 3</strong> if someone tries to edit them <img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none" alt="Smile" src="http://lh4.ggpht.com/-E6sQw1dE79s/UMsVC2fNcnI/AAAAAAAACiY/sRS-5CSS7ts/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"></p> <p><a href="http://lh6.ggpht.com/-JOZqzYxNkw0/UMsVEPfSDzI/AAAAAAAACig/iq-GfNhhQsw/s1600-h/Precompiled%252520aspx%252520page%252520no%252520uneditable%25255B5%25255D.png" target="_blank"><img title="Precompiled aspx page no uneditable" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Precompiled aspx page no uneditable" src="http://lh3.ggpht.com/-KfNeEEj4R6I/UMsVFD3PDYI/AAAAAAAACik/31xqW0WfC0Q/Precompiled%252520aspx%252520page%252520no%252520uneditable_thumb%25255B3%25255D.png?imgmax=800" width="640" height="140"></a></p> <p><strong>Figure 3 - Precompiled aspx page no un-editable</strong></p> <p>And finally in VS2012 you can set the build configuration in each Publish profile, this works without having to change the build configuration in you project.</p> <p> <div style="border-top: gray 1px dotted; border-right: gray 1px dotted; border-bottom: gray 1px dotted; color: red; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; margin: 4px; border-left: gray 1px dotted; padding-right: 4px; background-color: #ffffcc"><strong>Warning: </strong>This sadly does not work for Dynamic Data yet it testes OK you already deployed to a site as it uses the place holders, I’m looking into it hopefully there will be a simple fix.</div></p> Stephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0tag:blogger.com,1999:blog-6907873803403737979.post-85963269514626100712012-08-30T12:04:00.001+01:002012-09-25T16:01:57.225+01:00O2 has major fail<strike>O2 have just blocked external access to smtp.o2.co.uk this means you cannot send e-mail from your mobile if you are no connected to an O2 network and if you are abroad you will only be able to send email via your data account. <br />
<br />
For me this is a major fail I havrelayeded on this from O2 for as long as I have been with them. I will be moving from O2 and finding a solution to sending e-mail that no ISP or Mobile provider will be able to block.<br />
<br />
RIP O2<br />
<br />
Steve<br />
<br />
</strike><br />
<br />
Well news is O2 don't seem to know what the issue is I just got told by first level support that it was not accessable from outside O2's network? but it is again I suspect I was being given a line...<br />
<br />
SteveStephen J. Naughtonhttp://www.blogger.com/profile/17435527974910745156noreply@blogger.com0