I’m continuing the series of blog posts on my Nucleo control suite available at http://www.codeplex.com/nucleo.  This post is on the way that tags can be rendered.  ASP.NET MVC has a TagBuilder class for creating a class to generate markup and render that markup to the brower.  If you have used any of the HTML extensions for rendering controls like Html.TextBox, you have used the TagBuilder class.  Noting that the TagBuilder class was built for MVC and is not available in 2.0 web sites or 3.5 web sites that don’t reference the System.web.MVC dll, I created my own tag-building system, which comprises of a TagElement class, and a TagElementBuilder class that creates these custom tag controls.  I like using the tag approach over using the previous approach of writing HTML markup using the HtmlTextWriter.  For instance, compare this:

TagElement tag = TagElementBuilder.Create(“INPUT”);
CommonTagSettings.SetIdentifiers(tag, this.Component, this.Component.ClientID);

tag.Attributes
 .AppendAttribute(“type”, “text”)
 .AppendAttribute(“value”, this.Component.Text ?? “”)
 .AppendAttribute(“class”, “DropDownInput”)
 .AppendAttribute(“disabled”, this.Component.Enabled ? “” : “disabled”); 

//To render this tag, use tag.ToHtmlString();

 To the alternative approach:

writer.AddAttribute(HtmlTextWriterAttribute.Id, this.Component.ClientID); //using attributes
writer.AddAttribute(“name”, this.Component.ClientID); //or using string names
writer.AddAttribute(“type”, “text”);
writer.AddAttribute(“value”, this.Component.Text ?? “”);
writer.AddAttribute(“class”, “DropDownInput”);
writer.AddAttribute(“disabled”, this.Component.Enabled ? “” : “disabled”);
writer.RenderBeginTag(“input”);
writer.RenderEndTag(); //input

Notice while the two are very similar, the first approach is a little more readable, and the fluent API helps aid the bulk adding of attributes.  While the syntax is a little verbose, I am working on an add-on to making this process a little easier (I’m still considering options).  I could have made this even easier by doing the following:

TagElement tag = TagElementBuilder.Create(“INPUT”, new { type = “text”, value = this.Component.Text ?? “”, @class = “DropDownInput”, disabled = “disabled” });
CommonTagSettings.SetIdentifiers(tag, this.Component, this.Component.ClientID);

This is a feature that you saw added to the ASP.NET MVC framework, the ability to read anonymous types and use their values for the underlying control.  Now, through this system, it is available in 2.0 – 4.0 web forms as well.  Other properties are available; for instance, TagElement also has a Styles collection that uses the same attribute approach as you see above to create a string of styles for a control.  Styles can be added and the final result is rendered as the styles=”” attribute for the HTML tag.

Once you have set all of your attributes, the ToHtmlString() creates a string statement for your HTML tag.  Our above tag would render the following.

<input type=”text” value=”Some Text” class=”DropDownInput” disabled=”” ..></input>

This can then be written out in the Render method using the HtmlTextWriter if you like, or you can use Nucleo’s rendering approach; there are a couple of different rendering options that I’ll post about soon, if you would like to use Nucleo to create custom AJAX controls or extenders.

There are other features that I am still perfecting, like the ability to create a TagElementGroup and supply bulk settings at once.  This makes it easier to create and work with a bulk range of objects.  It’s not finished, but I do have some of it’s features implemented.  There are two ways to create a group, supply the names of the tags, or to supply the name of a single tag, the number of items to create, and common attributes shared across all.

var tagList = TagElementBuilder.CreateGroup(new string[] { “A”, “STRONG”, “SPAN”, “DIV” });
var tagList = TagElementBuilder.CreateGroup(“A”, 5,
 new { Href = “http://www.yahoo.com“, Target = “_blank” });

In this way, it makes working with a lot of elements easier.   I’m trying to create a way to apply additional attributes in a bulk way, considering ways to apply settings to alternating elements and such.