Cours CSS3

Enfin, je mets en ligne mon cours CSS3 avec les exemples. Exemples Mode en ligne et mode bloc (Inline-Block.html)  Syntaxe (Syntax.html) Fichier CSS externe (external-css.html) Sélecteurs (selectors.html) Sélecteurs avancés (AdvancedSelectors.html) Styles en cascade (cascade.html) Couleurs (couleurs.html) Polices de Caractères (fontfamily.html) Taille de Caractères (fontsize.html) Polices personnalisées (fontface.html) Texte avec ombr (textshadow.html)  Hauteur et Largeur (WidthHeight.html) Marges intérieure et extérieure (BorderMarginPadding.html) Affichage et visibilité (DisplayVisibility.html) Nouvelles bordures (NewBorders.html) Tableaux (Tableaux.html) Formulaires (Formulaire.html) Positionnements dans CSS (Position.html) éléments flottants (floats.html) Dispositions (dispositions.html) Album (album.html) Disposition flex (flex.html) Images et dégradés (Images.html) Transitions (transitions.html) Transformations (transformations.html) Animations (Animations.html)

ASP.NET GridView Multi Select Using CheckBoxes and JQuery

Hi, In this tutorial, I will show you how to implement a multiselect grid view using checkboxes and JQuery. The GridView is a fantastic component but lacks a very useful feature that allows the multiple row selection. Using JQuery, we’ll put a workaround to extend the grid. First, let’s create an empty ASP.NET Web Application Project and install the JQuery package using the package manager console. Then, let’s create a new webform called “Default.aspx”. Let’s create a business class called “Check” and that represents a bank check : public class Check {   public DateTime IssueDate { get; set; }  public string CheckNumber { get; set; } } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Now, let’s add a minimalistic repository class : public class CheckRepository { public IEnumerable<Check> GetList() { var list = new List<Check>(); for (int i = 0; i < 20; i++) { var cheque = new Check() { CheckNumber = string.Format("{0:00000000}", i + 1), IssueDate = DateTime.Now }; list.Add(cheque); } return list; } } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } In the default.aspx form, let’s add an object data source component and bind it to the “CheckRepository” class with the “GetList” method. Let’s add a GridView bound to the object data source having two bound columns : “CheckNumber” and obviously “IssueDate”. Our work starts here, we need an additional column that contains the selection checkbox. For this, let’s exploit the magic of template fields. The three gridview columns will look like this : <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1"> <Columns> <asp:TemplateField> <HeaderTemplate> <input type="checkbox" id="cbSelectAll" /> </HeaderTemplate> <ItemTemplate> <input type="checkbox" name="ChequeSelected" class="cbSelectRow" value="<%# Eval("CheckNumber") %>" ></input> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="CheckNumber" HeaderText="Number" SortExpression="NumeroCheque" /> <asp:BoundField DataField="IssueDate" HeaderText="Issue Date" SortExpression="DateEmission" /> </Columns> </asp:GridView> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } The checkbox that will select all rows is called “cbSelectAll” and the select row check box will have the css class “cbSelectRow”. The first thing to notice is that for the row checkbox, I have used the “value” attribute that will save the check id in the row checkbox. The idea is very simple, whenever a postback is triggered,, all the checkbox content will be sent with the form content. We’ll use the checkbox value to know which check have been selected by the user. Precisely, to trigger the postback, let’s add a simple asp.net button to the web form. I’ll add a very simple effect : the selected rows will be colored in green. To accomplish this, let’s create the lightGreen css class : <style type="text/css"> .lightGreen { background-color: lightgreen; } </style> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } A little jquery right now: a simple script to transform the containing row of the checked checkbox in green and another one the the “select all checkbox” that will allow to check (or uncheck) the checkboxes : $(function () { $('.cbSelectRow').change(function () { // detect if the checkbox is checked var checked = $(this).prop('checked'); // gets the table row indiect parent var trParent = $(this).parents('tr'); // add or remove the css class according to the check state if (checked == true) trParent.addClass('lightGreen') else trParent.removeClass('lightGreen'); }); // select all click $("#cbSelectAll").change(function () { var checked = $(this).prop('checked'); $('.cbSelectRow').prop('checked', checked).trigger('change'); });  }); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } The last thing to do is to intercept the postback in the web form and to display the selected checks by browsing the form data, quite simple, let’s modify the “Page_Load” method like this : if (IsPostBack) { // create a string builder to create the displayed string var builder = new StringBuilder(); builder.Append("Vous have selected the following checks :<br/>"); // get the selected checkboxes from the form data var checkString = Request.Form["ChequeSelected"]; if(checkString == null) return; // we'll need a split to get the individual ids var values = checkString.Split(','); foreach(var value in values) { builder.Append("<br/>"); builder.Append(value);  } Response.Write(builder.ToString()); } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Let’s test and you’ll see it, it works ! The “Reponse”  line displays all the selected checks. But we still have an issue, when a postback is performed, we lose the selected checkboxes in the grid because it have been redrawn and plain HTML string do not support view state. To get through this problem, the solution is simple too. We’ll save the checked ids in a list called “checkedIds” : /// <summary> /// this lists stores the ids that have been selected /// </summary> private List<string> checkedIds = new List<string>(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Let’s change the “Page_Load” method to fill the list : protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { // create a string builder to create the displayed string var builder = new StringBuilder(); builder.Append("Vous have selected the following checks :<br/>"); // get the selected checkboxes from the form data var checkString = Request.Form["ChequeSelected"]; if(checkString == null) return; // we'll need a split to get the individual ids var values = checkString.Split(','); foreach(var value in values) { builder.Append("<br/>"); builder.Append(value); checkedIds.Add(value); } Response.Write(builder.ToString()); GridView1.DataBind(); } } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } The last line forces the gridview to “redraw”. This manipulation is still not sufficient to restore the display, we have to change the checkbox in order to reflect (or not) a previous selection : <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1"> <Columns> <asp:TemplateField> <HeaderTemplate> <input type="checkbox" id="cbSelectAll" /> </HeaderTemplate> <ItemTemplate>  <input type="checkbox" name="ChequeSelected" class="cbSelectRow" value="<%# Eval("CheckNumber") %>" <%# NumeroChequeInclus(Eval("CheckNumber").ToString()) %>></input> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="CheckNumber" HeaderText="Number" SortExpression="NumeroCheque" /> <asp:BoundField DataField="IssueDate" HeaderText="Issue Date" SortExpression="DateEmission" /> </Columns>  </asp:GridView> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Notice that the checkbox will render something that the method “CheckNumber” returns by passing the current check number as argument. The method “CheckNumber” have to generate “"the “checked” attribute if the passed id is contained in the “checkedIds” list or an empty string otherwise. /// <summary> /// renders or not the checked attribute /// </summary> /// <param name="numero"></param> /// <returns></returns> public string NumeroChequeInclus(string numero) { if (checkedIds.Contains(numero)) return "checked"; return string.Empty; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } The last thing to do is to modify the jquery script to restore the green background after a postback, the full script would be like this : $(function () { $('.cbSelectRow').change(function () { // detect if the checkbox is checked var checked = $(this).prop('checked'); // gets the table row indiect parent var trParent = $(this).parents('tr'); // add or remove the css class according to the check state if (checked == true) trParent.addClass('lightGreen') else trParent.removeClass('lightGreen'); }) // the each is used when postback is triggered with checked rows .each(function (index, element) { var checked = $(element).prop('checked'); if (checked == true) $(element).parents('tr').addClass('lightGreen'); }); // select all click $("#cbSelectAll").change(function () { var checked = $(this).prop('checked'); $('.cbSelectRow').prop('checked', checked).trigger('change'); });  }); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }   A working version of the app would look like this : The full source code is available here Enjoy !

Creating an adaptive pager using ASP.NET MVC 4 HTML helpers and Twitter Bootstrap 3

Twitter released recently their brand new Bootstrap and they changed radically many things and notably the paging system. In this post, I will show how to create an ASP.NET MVC4 HTML Helper that renders an adaptive pager. The first thing I have to explain is what is an adaptive pager ? Imagine a collection of 1000 records, if the pager uses a page size of 20 records, the pager will renders 50 links which is not a very positive rendering manner according to the modern web page rules. Accordingly, an adaptive pager is constituted by three sections : the first section contains the three first pages, the last section contains the three last pages and the middle section contains either the current page (if the current page is neither in the first par nor the last part) or the middle pages. An adaptive pager style by bootstrap would look like this : To create the helper, we have to create a static class called “HtmlRenderExtensions”. In this class, we will create an extension method callded “RenderPager” like this : public static HtmlString RenderPager(this HtmlHelper html, string controllerName, string actionName, int recordNumber, int pageSize, int currentPage) { } Let’s calculate the number of pages with this simple formula: // calculate the number of pages var numberOfPages = recordNumber / pageSize; if (recordNumber % pageSize != 0) ++numberOfPages; Of course, if there not enough pages (at least 2) we don’t need pagination : if (numberOfPages < 2) return new HtmlString(string.Empty); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } The first thing to do is to create an URL helper to generate the links URLs : // create an URL helper to generate urls var urlHelper = new UrlHelper(html.ViewContext.RequestContext, html.RouteCollection); var link = urlHelper.Action(actionName, controllerName); After that, we need a string builder to generate the HTML markup: StringBuilder builder = new StringBuilder(); After that, the bootstrap, the pagination is built using an unordered list (with the class “pagination”), that’s why we’ll append with an opening “ul” tag : builder.Append("<ul class=\"pagination\">"); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }We need a method that generates the list item with the associated links, we’ll call this method “AppendPagerTag” and its code is as follow: private static void AppendPagerTag(StringBuilder builder, int targetPage, UrlHelper helper, string controllerName, string actionName, int currentPage, string tagText = null) { // the link markup string linkTag = ""; // the active css string activeCss = ""; // the page text if (tagText == null) tagText = targetPage.ToString(); // a positive value of targetPage points to a real page while a negative value points to a simple text (span) if (targetPage > 0) { // if the target page is the current page, then we'll add the "active" class to the item if (targetPage == currentPage) activeCss = "active"; var link = helper.Action(actionName, controllerName, new { page = targetPage }); // generate the link markup linkTag = string.Format("<a href=\"{1}\">{0}</a>", tagText, link); } else // generates the separator markup linkTag = string.Format("<span>{0}</span>", tagText); // embed the generated markup in a list item builder.AppendFormat("<li class=\"{1}\">{0}</li>", linkTag, activeCss); } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } When we pass negative value, this method will generate separators instead of links. Otherwise, it will generate a link with a different page parameter. The next thing to do in the extension method is to generate the “previous” link if the current page is higher than “1”. if (currentPage > 1) AppendPagerTag(builder, currentPage - 1, urlHelper, controllerName, actionName, currentPage, "&laquo;"); The pager is divided generally in three sections : the first that contains the first pages, the last that contains the last pages and the middle section that contains some calculated pages.Let’s set the first section : // the first section contains the first pages IEnumerable<int> section1 = new int[] { 1, 2, 3 }.ToList(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }Let’s now set the last section : // the last section contains the last pages IEnumerable<int> section3 = new int[] { numberOfPages - 2, numberOfPages - 1, numberOfPages }.ToList(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }Let’s now calculate the middle section which is a special section : // calculate the floating middle section. If the current page is in the middle, the floating section is a region that // contains the current page otherwise, it's the region that contains the middle pages int middleStart; if ((currentPage <= 2) || (currentPage >= numberOfPages - 1)) { middleStart = numberOfPages / 2; if (middleStart < 5) middleStart = 5; } else if ((currentPage >= 3) && (currentPage < 6) && (currentPage < numberOfPages - 2)) { middleStart = 5; } else middleStart = currentPage; var middle = new int[] { middleStart - 1, middleStart, middleStart + 1 }; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }Using the magic of Linq, we’ll constitute the full pages list that is composed of the three sections and eventually some separators if the current page do not belong to the first or the last section. // create the list of pages that are composed of the three sections and eventual separators that are represented by negative numbers (-99 and -98) IEnumerable<int> pages = section1; if (middle.First() > 4) pages = pages.Union(new int[] { -98 }); pages = pages.Union(middle); if (middle.Last() < numberOfPages - 3) pages = pages.Union(new int[] { -99 }); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Let’s browse the generated collection and eliminate the pages that are not coherent according to the collection : // filter the pages to take into account only the coherent pages by eliminating redundancies and illogical pages foreach (var page in pages.Where(e => (e <= numberOfPages && e > 0) || e == -99 || e == -98).Distinct()) { if (page > 0) AppendPagerTag(builder, page, urlHelper, controllerName, actionName, currentPage); else AppendPagerTag(builder, page, urlHelper, controllerName, actionName, currentPage, "..."); } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }If we are not in the last page, we need to generate the “next” page : // generate the next page if we are not in the last page if (currentPage < numberOfPages) AppendPagerTag(builder, currentPage + 1, urlHelper, controllerName, actionName, currentPage, "&raquo;"); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }Finally, let’s close the “ul” and stop the rendering process : // generate the next page if we are not in the last page if (currentPage < numberOfPages) AppendPagerTag(builder, currentPage + 1, urlHelper, controllerName, actionName, currentPage, "&raquo;"); builder.AppendFormat("</ul>"); return new HtmlString(builder.ToString()); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } The complete method code is as follow: public static HtmlString RenderPager(this HtmlHelper html, string controllerName, string actionName, int recordNumber, int pageSize, int currentPage) { // calculate the number of pages var numberOfPages = recordNumber / pageSize; if (recordNumber % pageSize != 0) ++numberOfPages; if (numberOfPages < 2) return new HtmlString(string.Empty); // create an URL helper to generate urls var urlHelper = new UrlHelper(html.ViewContext.RequestContext, html.RouteCollection); var link = urlHelper.Action(actionName, controllerName); // create a string builder to generate HTML StringBuilder builder = new StringBuilder(); builder.Append("<ul class=\"pagination\">"); // generate the previous "link" if (currentPage > 1) AppendPagerTag(builder, currentPage - 1, urlHelper, controllerName, actionName, currentPage, "&laquo;"); // the first section contains the first pages IEnumerable<int> section1 = new int[] { 1, 2, 3 }.ToList(); // the last section contains the last pages IEnumerable<int> section3 = new int[] { numberOfPages - 2, numberOfPages - 1, numberOfPages }.ToList(); // calculate the floating middle section. If the current page is in the middle, the floating section is a region that // contains the current page otherwise, it's the region that contains the middle pages int middleStart; if ((currentPage <= 2) || (currentPage >= numberOfPages - 1)) { middleStart = numberOfPages / 2; if (middleStart < 5) middleStart = 5; } else if ((currentPage >= 3) && (currentPage < 6) && (currentPage < numberOfPages - 2)) { middleStart = 5; } else middleStart = currentPage; var middle = new int[] { middleStart - 1, middleStart, middleStart + 1 }; // create the list of pages that are composed of the three sections and eventual separators that are represented by negative numbers (-99 and -98) IEnumerable<int> pages = section1; if (middle.First() > 4) pages = pages.Union(new int[] { -98 }); pages = pages.Union(middle); if (middle.Last() < numberOfPages - 3) pages = pages.Union(new int[] { -99 }); pages = pages.Union(section3); // filter the pages to take into account only the coherent pages by eliminating redundancies and illogical pages foreach (var page in pages.Where(e => (e <= numberOfPages && e > 0) || e == -99 || e == -98).Distinct()) { if (page > 0) AppendPagerTag(builder, page, urlHelper, controllerName, actionName, currentPage); else AppendPagerTag(builder, page, urlHelper, controllerName, actionName, currentPage, "..."); } // generate the next page if we are not in the last page if (currentPage < numberOfPages) AppendPagerTag(builder, currentPage + 1, urlHelper, controllerName, actionName, currentPage, "&raquo;"); builder.AppendFormat("</ul>"); return new HtmlString(builder.ToString()); } The pager would look like this : .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }   The source code is attached with the post The source code is available here Enjoy !

Création d’un site web statique avec Visual Studio 2012 (Tutoriel 1.1)

L’objectif de ce tutoriel est de créer un site web statique avec Visual Studio. Le site sera composé d’une page HTML, une feuille de style CSS et d’un fichier Javascript. Ce tutoriel est relatif au module “introduction à ASP.NET et Visual Studio 2012” Etape 1 – Lancer Visual Studio L’objectif de cette étape est de se familiariser avec la création de site web sous VS 2012. Lancer VS 2012 Choisir Fichier -> Nouveau -> Site Web Choisir le modèle « site web ASP.NET vide » Choisir l’emplacement du site (répertoire) Cliquez sur OK Etape 2 – Création d’une page web L’objectif de cette étape est de créer des pages HTML avec Visual Studio et d’y ajouter des balises HTML. Cliquez sur le menu « Fichierà Nouveau à Fichier » Dans les modèles, choisissez « Page HTML » Dans le nom entrez « index.html » Cliquez sur OK Dans l’éditeur, tapez le code suivant entre <body> et </body> <p>Bienvenue à la <span id="mot">formation</span> ASP.NET et de développement web</p> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } En utilisant la barre d’outils, glissez un « div » juste après la balise fermante </p> Dans la fenêtre de propriétés, entrez « footer» dans la zone « ID » <div id="footer"></div>   Etape 3 : Modification de la page en mode « Conception » L’objectif de cette étape est d’apprendre à modifier les pages HTML en utilisant le designer de Visual Studio. Basculez en mode conception de « Index.html » en appuyant sur le bouton « Conception » de l’éditeur Ajoutez les mots suivants : « et de développement web » à la fin du paragraphe   Etape 4 – Création de fichiers CSS et Javascript Cliquez sur Fichierà Nouveau à Fichier Dans les modèles, choisissez feuille de style Dans la zone nom, entrez « Site.css » Cliquez sur le bouton OK Entrez le code suivant dans le fichier CSS : body { }   span#mot { color : red; }   div#footer { margin 5; min-height : 40px; background-color : green; } Enregistrez le fichier Par un glisser-déposer, faites glisser le fichier CSS à partir de l’explorateur de solutions sur le fichier HTML et remarquez comment le style a été appliqué sur la page   Cliquez sur Fichier à Nouveau à Fichier Dans le modèle, choissez « Javascript » Dans la zone nom, entrez « MyScript.JS » Dans l’éditeur tapez le code suivant : function sayHello(me) { alert('hello ' + me); } Ouvrez le fichier « Index.html » en mode source Faites un glisser déposer du fichier « MyScript.js » vers « index.html » (entre les balises HEAD » Modifiez le code HTML comme suit : <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <link href="Site.css" rel="stylesheet" type="text/css" /> <script src="MyScript.js"></script> </head> <body> <p> Bienvenue à la <span id="mot" onclick="sayHello(‘Votre nom);">formation</span> ASP.NET et de développement web </p> <div id="footer"></div> </body> </html> Cliquez sur le bouton « Exécuter » Etape 5 : Débogage L’objecif de cette étape est d’utiliser les fonctions de débogage de Visual Studio afin de créer un point d’arrêt sur un script JavaScript et d’évaluer une variable dans une fonction JavaScript. Fermez la fenêtre du site Ouvrez MyScript.js Insérez un point d’arrêt sur l’instruction « alert » en double-cliquant sur la barre latérale   Exécutez le site en appuyant sur « F5 » Appuyez sur le texte « formation » Remarquez VS qui se met en mode « debogage » et renvoie sur le fichier « MyScript.js »   Faites passer la sourir sur la variable « me » Vérifiez que cette variable correspond à la valeur passée lors de l’appel Appuyez sur F5 pour continuer l’exécution Fermez la fenêtre du site Pour télécharger le code source, cliquez ici.

Adjust control widths using CSS

One of the most important issues when designing websites is to adjust the width of the different controls and especially text boxes and drop down lists. When using CSS rules that integrate a fixed width, there’s still a small width difference between text controls and drop down lists. The key is that selects and inputs use by default different box sizing mechanisms. Fortunately, CSS3 comes with the box-sizing rule that allows to apply the same box sizing mechanism to controls. And this property is handled correctly by most of the popular browsers. Here is the code snippet : input, select, textarea { box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }