tags:

views:

628

answers:

3

Hi

I been playing around with some custom html helpers and I now I am trying to make one that I can use for jquery AJAX UI Tabs.

So to do ajax tabs you need to have this format in your html code

<div id="example">
     <ul>
         <li><a href="ahah_1.html"><span>Content 1</span></a></li>
         <li><a href="ahah_2.html"><span>Content 2</span></a></li>
         <li><a href="ahah_3.html"><span>Content 3</span></a></li>
     </ul>
</div>

so I can't use ActionLink because I don't think I can add anyway the tag to the actionLink.

So I want to make my own html helper that has an actionLink with a span tag in it and possibly build it up later on to have an unordered listed tag with it.

So I am not sure how to use the ActionLink to my benefit. Like the ActionLink has 10 overloaded methods and I don't want to recreate all 10 of them since that just seems pointless. So is there away I can reference it or something like that?

I am using the way that allows my custom html helpers to show up when you do "Html." in intellisense.

for instance I would have:

public static string Button(this HtmlHelper helper, string id, string value)

So I am not sure how to make use of this HtmlHelper I am passing in.

I also don't understand this part of the line of code "this HtmlHelper helper".

What confuses me is the using the keyword "this" in the parameter. I am not sure what it is refering to and why you need it. I also don't understand how by passing this parameter but not using it somehow allows your customer Html helpers to be accesed by "Html.".

Thanks

+3  A: 

The this HtmlHelper helper means it is a C# 3.0 "extension method" on HtmlHelper, which is how it becomes available on the Html instance in your view (etc). An extension method is a static method that pretends (at compile time) to be an instance method available on the type nominated by this (in this case HtmlHelper). In reality, the compiler calls the static method (Html.Button({args})) as though you had typed:

MyStaticClass.Button(Html, {args});

It is not necessary to use the HtmlHelper that is passed in if you don't need it (inded, I don't use it here); it's main job (in this case) is to make the code convenient to consume (as an extension method); but it can be useful in some cases.

Marc Gravell
+1  A: 

You don't have to have a HtmlHelper to create links that work with jQuery AJAX UI Tabs.

jQuery tabs plugin accepts an argument named tabTemplate that you can set :

$("#example").tabs({ tabTemplate: "<li><a href=\"#{href}\">#{label}</a></li>" });

See the documentation.

çağdaş
So what I make just a list of divs and put "#" infront on all the herfs?I am not sure how the code should look like.I use HtmlHelpers since I find them alot cleaner and stop spagetti code thats why I am using them.I still would like to know how to call a made Html helper in a custom Html helper.
chobo2
From the documentation linked:tabTemplate: HTML template from which a new tab is created and added. The placeholders #{href} and #{label} are replaced with the url and tab label that are passed as arguments to the add method.
andymeadows
@chobo2 - andymeadows is right. Just create your tabs any way you like and use the tabTemplate option to get jQuery to match the links (or any other elements) you've created.
çağdaş
Sorry I still don't follow. I need a full example to see it. Thanks
chobo2
+4  A: 

Marc's answer is excellent. Just adding some code:

1) Create static class with your helper:

public static class MyHtmlHelpers
{
    public static string MySpecialActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues)
    {
        var innerTagBuilder = new TagBuilder("span") {
            InnerHtml = (!String.IsNullOrEmpty(linkText)) ? HttpUtility.HtmlEncode(linkText) : String.Empty
        };

        TagBuilder tagBuilder = new TagBuilder("a") {
            InnerHtml = innerTagBuilder.ToString(TagRenderMode.Normal);
        };

        var urlHelper = new UrlHelper(html.ViewContext.RequestContext);
        var url = urlHelper.Action(actionName, routeValues);
        tagBuilder.MergeAttribute("href", url);

        return tagBuilder.ToString(TagRenderMode.Normal);
    }
}

2) Add namespace of MyHtmlHelpers class to web.config:

<pages>
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Routing" />
    <add namespace="System.Linq" />
    <add namespace="System.Collections.Generic" />

    <add namespace="MyHtmlHelpers_Namespace" />
  </namespaces>
</pages>

3) Enjoy :) :

<div id="example">
    <ul>
        <li><%= Html.MySpecialActionLink("Content 1", "action1", null) %></li>
        <li><%= Html.MySpecialActionLink("Content 2", "action2", new { param2 = "value2" }) %></li>
        <li><%= Html.MySpecialActionLink("Content 3", "action3", new { param3 = "value3" }) %></li>
    </ul>
</div>
eu-ge-ne
I will try that out as soon as I can. So I guess there is no easy way to use ActionLink and it's 10 overloaded methods? I have to basically pic and choose what I need?Also what does this do?InnerHtml = (!String.IsNullOrEmpty(linkText)) ? HttpUtility.HtmlEncode(linkText) : String.EmptyLike why are you HtmlEncoding it? I can understand why your checking for empty but not sure why your encoding it.
chobo2
linkText must be HTML encoded for producing correct markup and security reasons. From MSDN: If characters such as blanks and punctuation are passed in an HTTP stream, they might be misinterpreted at the receiving end. HTML encoding converts characters that are not allowed in HTML into character-entity equivalents;
eu-ge-ne