2

I'm trying to create a reusable fragment of HTML that I'd like to be able to accept additional HTML as some sort of parameter.

My reusable code is

<div class="dialog" id="@Model.HtmlId">

  <!-- My reusable code needs to go here -->
</div>

Creating a partial view is easy, but the problem is that partial views accept a Model as a parameter.

My current solution is ugly.

@Html.Partial("_startDialog", new { HtmlId="someIdGoesHere" });

<form>
  <!-- Some form elements go here -->
</form>

@Html.Partial("_endDialog");

This renders

<div class="dialog" id="@Model.HtmlId">

  <form>
    <!-- Some form elements go here -->
  </form>
</div>

How can I stream line this. Elegance would be nice :-)

Razor
  • 17,271
  • 25
  • 91
  • 138

1 Answers1

3

This should do the trick:

public class MvcDialog : IDisposable
{
    public MvcDialog(ViewContext context, IDictionary<string, object> htmlAttributes)
    {
        this.context = context;
        this.htmlAttributes = htmlAttributes;

        Begin();
    }

    private ViewContext context;
    private IDictionary<string, object> htmlAttributes;
    private TagBuilder tag;
    private bool disposed;

    protected virtual void Begin()
    {
        tag = new TagBuilder("div");
        tag.MergeAttributes(htmlAttributes);
        tag.AddCssClass("dialog");

        context.Writer.Write(tag.ToString(TagRenderMode.StartTag));
    }

    public virtual void End()
    {
        Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            disposed = true;
            context.Writer.Write(tag.ToString(TagRenderMode.EndTag));
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

public static class MvcDialogExtensions
{
    public static MvcDialog Dialog(this HtmlHelper self)
    {
        return Dialog(self, new RouteValueDictionary());
    }
    public static MvcDialog Dialog(this HtmlHelper self, object htmlAttributes)
    {
        return Dialog(self, new RouteValueDictionary(htmlAttributes));
    }
    public static MvcDialog Dialog(this HtmlHelper self, IDictionary<string, object> htmlAttributes)
    {
        return new MvcDialog(self.ViewContext, htmlAttributes);
    }
}

Usage:

@using (Html.Dialog(new { id = "mightyDialog" }))
{
    <text>awesome content</text>
}
Lukáš Novotný
  • 9,012
  • 3
  • 38
  • 46
  • Hi Lukas, that solution works great for plain text, but if you try
    instead of , then it stops working :-( Excellent answer though.
    – Razor Mar 23 '11 at 05:18
  • 1
    You don't need `` when your content starts with html tag. However it should (and it does for me) work anyway, could you post exact behavior you're getting? – Lukáš Novotný Mar 23 '11 at 07:39