Helper MVC pour panel Bootstrap utilisable dans un block using
Date of publication
1/24/2017
No comments
Utiliser le panel de Bootstrap n’est pas forcément ce qu’il y a de plus trivial. Surtout, s’il faut le reproduire à plusieurs reprises dans une même page :
<div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">My title</h3> </div> <div class="panel-body"> ... </div> </div>
En .net MVC, heureusement il est possible d’écrire des Helpers pour cela. Certain auront peut-être la tentation de créer deux méthode façon script PHP :
@Html.BeginPanel("My title") … @Html.EndPanel()
Heureusement, un Helper peut être incrusté dans un block using. Ce qui rend son usage plus trivial :
@using(Html.BeginPanel("My title")) { … }
Pour arriver à cela, on ne doit maitriser quelques concepts simples :
- Le block using a besoin d’une instance d’une classe implémentant l’interface IDisposable
- Le constructeur de cette classe va écrire le début du code HTML utile.
- La méthode Dispose de cette classe doit écrire les balises HTML fermantes utiles.
- Pour écrire directement sur la vue MVC, il faut utiliser la méthode Write du contexte de la vue : htmlHelper.ViewContext.Writer.Write("…").
La première étape consiste donc à créer une classe disposable :
- L’appel du constructeur va écrire le début du panel Bootstrap.
- L’instance appelante de HtmlHelper est conservée pour permettre son usage dans le Dispose.
- L’appel du Dispose va écrire les deux balises fermantes des Div ouvertes dans le constructeur.
/// <summary>
/// Panel bootstrap pouvant être utilisé dans un block using d'un vue MVC
/// </summary>
public sealed class MvcPanel : IDisposable
{
private readonly HtmlHelper _htmlHelper;
/// <summary>
/// Constructeur
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="title">Titre du panel</param>
public MvcPanel(HtmlHelper htmlHelper, string title)
{
_htmlHelper = htmlHelper;
// Création du container
var container = new TagBuilder("div");
container.AddCssClass("panel");
container.AddCssClass("panel-default");
// Création du container du header
var headerContainer = new TagBuilder("div");
headerContainer.AddCssClass("panel-heading");
// Création du header
var header = new TagBuilder("h3");
header.AddCssClass("panel-title");
header.InnerHtml = title;
// Ajout du header à son container
headerContainer.InnerHtml = header.ToString();
// Création du container du body
var bodyContainer = new TagBuilder("div");
bodyContainer.AddCssClass("panel-body");
_htmlHelper.ViewContext.Writer.Write(
String.Concat(
container.ToString(TagRenderMode.StartTag),
headerContainer.ToString(),
bodyContainer.ToString(TagRenderMode.StartTag)));
}
/// <summary>
/// Dispose, met fin au block
/// </summary>
public void Dispose()
{
_htmlHelper.ViewContext.Writer.Write("</div></div>");
}
}
Après cela, l’écriture du Helper est triviale. Celui-ci a uniquement pour vocation de retourner une instance de la classe MvcPanel :
public static class PanelExtensions
{
/// <summary>
/// Création d'une Panel bootstrap à utiliser dans un block using
/// </summary>
/// <param name="htmlHelper">Helper</param>
/// <param name="title">titre affiché sur le panel</param>
/// <returns></returns>
public static MvcPanel BeginPanel(this HtmlHelper htmlHelper, string title)
{
return new Html.MvcPanel(htmlHelper, title);
}
}
Simple et trivial ;)