12

I would like to create a html helper that would receive as a parameter content of the view, like this:

<% Html.MyTextArea("txt1", () => {%> 

content of the view
<%=Html.TextBox("Name") %>
...
<% }) %>
Cœur
  • 37,241
  • 25
  • 195
  • 267
Omu
  • 69,856
  • 92
  • 277
  • 407
  • 1
    Could you please clarify what you mean exactly when you are saying "that would receive as a parameter content of the view"? Thanks. – Kalman Speier Dec 30 '11 at 10:58
  • @KalmanSpeier it means that if you would had a helper between the `%> <%` it would render and you would get a string parameter of the generated html – Omu Dec 31 '11 at 08:12
  • Could you show an example of what your input and expected output is? – petebowden Jan 03 '12 at 21:10
  • @Rastapopulous basically you would get the html that would be in the output stream in a parameter as a string so that you could put it where you want to render it – Omu Jan 04 '12 at 18:38
  • I am not sure how it can be done in Web Forms View Engine but check this blog post out: [Templated Razor Delegates](http://haacked.com/archive/2011/02/27/templated-razor-delegates.aspx) – tugberk Dec 18 '11 at 09:50
  • Phil Haack is excellent. David Fowler too. – one.beat.consumer Jan 02 '12 at 05:24

3 Answers3

3

Since you've tagged it as MVC, I'm going to propose you could do something like I posted on my blog as a way to get syntax highlighting for templates as the solution would be very similar, IF you don't need to manipulate the inner content and are simply interested in 'wrapping' it in some way (like in a containing element that requires some extra logic).

Using the technique, the HtmlHelper method receives the context of the block. The syntax is slightly different from your suggested technique though.

For example, you could have something like:

@using(Html.MyTextArea("txt1")) 
{
  <some HTML content here>
}

The context is passed to an IDisposable object which includes a Writer (for writing to the current output stream). There, it can output multiple elements or do other manipulation as needed. The Dispose is used to write a close element (if needed).

So, you could end up with something like this:

<textarea><some HTML content here></textarea>

However, as I mentioned this does not provide the inner content to the function itself.

As Razor pages render inside out, there's not an effective method to grab the output in the way you're wanting. There are some posts around about caching the output of a Partial to a string (which would mean the inner content in your example would be in another file, an .ascx file), so you might want to look at those.

Community
  • 1
  • 1
WiredPrairie
  • 58,954
  • 17
  • 116
  • 143
3

One approach is,

    public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, Action<TextWriter> action)
    {
        var writer = new StringWriter();
        action(writer);
        // here writer contains the html
        return htmlHelper.TextArea(name);
    }

    <%:Html.TextArea("txt1",(writer) => {
        writer.Write("content of the view");
        writer.Write(HttpUtility.HtmlEncode(Html.TextBox("Name")));
    }) %>
imran_ku07
  • 1,404
  • 12
  • 13
3

Do you mean something like this?

namespace System.Web.Mvc {
    public static class HtmlHelperExtensions {
        public static MvcHtmlString MyTextArea(this HtmlHelper htmlHelper, string id, Func<MvcHtmlString> helperFunc) {
            return new MvcHtmlString(string.Format("<div id=\"{0}\">{1}</div>", id, helperFunc()));
        }
    }
}

You can use this way:

<%: Html.MyTextArea("txt1", () => Html.TextBox("Name", "abc")) %>
Kalman Speier
  • 1,937
  • 13
  • 18