Skip to main content

Helper MVC pour panel Bootstrap utilisable dans un block using

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 ;)

Jérémy Jeanson

Comments

You have to be logged in to comment this post.

Cookies Cookie Policy

This website uses cookies to allow us to enhance your browsing experience (accessibility settings). If you continue to use this website you agree to our use of cookies.