As part of the legacy codebase I’m working with at the moment I have recently been required to edit a product listing page to do something simple; add an extra link underneath each product.
Interestingly enough the product listing page is constructed as a collection of System.Web.UI.Controls, generating an HTML structure directly in C# which is then styled after being rendered completely flat.
For example:, each item in the listing could look a bit like this
[csharp]
public class CodeControl : Control
{
protected override void CreateChildControls()
{
AddSomeStuff();
}
private void AddSomeStuff()
{
var image = new Image
{
ImageUrl = "http://memegenerator.net/cache/instances/250×250/8/8904/9118489.jpg",
Width = 250,
Height = 250
};
Controls.Add(image);
var hyperlink = new HyperLink { NavigateUrl = "http://memegenerator.net/", Text = "Business Cat" };
Controls.Add(hyperlink);
var title = new HtmlGenericControl();
title.Attributes.Add("class", "title");
title.InnerText = "£19.99";
Controls.Add(title);
}
}
[/csharp]
And then the code to render it would be something like:
[csharp]
private void PopulateContainerDiv()
{
var ul = new HtmlGenericControl("ul");
for (var i = 0; i < 10; i++)
{
// setup html nodes
var item = new CodeControl();
var li = new HtmlGenericControl("li");
// every 3rd li reset ul
if (i % 3 == 0) ul = new HtmlGenericControl("ul");
// add item to li
li.Controls.Add(item);
// add li to ul
ul.Controls.Add(li);
// add ul to div
containerDiv.Controls.Add(ul);
}
}
[/csharp]
The resulting HTML looks like:
[html]
<ul><li><img src="http://memegenerator.net/cache/instances/250×250/8/8904/9118489.jpg" style="height:250px;width:250px;" /><a href="http://memegenerator.net/">Business Cat</a><span class="title">£19.99</span></li>
.. snip..
[/html]
And the page itself:
I’ve never seen this approach before, but it does make sense; define the content, not the presentation. Then to make it look nicer we’ve got some css to arrange the list items and their content, something like:
[css]
ul { list-style:none; overflow: hidden; float: none; }
li { padding-bottom: 20px; float: left; }
a, .title { display: block; }
[/css]
Which results in the page looking a bit more like
So that’s enough background on the existing page. I was (incorrectly, with hindsight, but that’s why we make mistakes right? How else would we learn? *ahem*..) attempting to implement a change that wrapped the contents of each li in a tag so that some jQuery could pick up the contents of that li and put them somewhere else on the page when a click was registered within the li.
So I did this:
[csharp highlight=”4,10,13″]
// setup html nodes
var item = new CodeControl();
var li = new HtmlGenericControl("li");
var form = new HtmlGenericControl("form");
// every 3rd li reset ul
if (i % 3 == 0) ul = new HtmlGenericControl("ul");
// add item to form
form.Controls.Add(item);
// add form to li
li.Controls.Add(form);
// add li to ul
ul.Controls.Add(li);
// add ul to div
containerDiv.Controls.Add(ul);
[/csharp]
I added in a <form> tag and put the control in there, then put the form in the li and the li in the ul. However, this resulted in the following HTML being rendered:
Eh? Why does the first <li> not have a <form> in there but the rest of them do? After loads of digging around my code and debugging I just tried something a bit random and changed it from a <form> to a <span>:
[csharp highlight=”4,10,13″]
// setup html nodes
var item = new CodeControl();
var li = new HtmlGenericControl("li");
var wrapper = new HtmlGenericControl("span");
// every 3rd li reset ul
if (i % 3 == 0) ul = new HtmlGenericControl("ul");
// add item to form
wrapper.Controls.Add(item);
// add form to li
li.Controls.Add(wrapper);
// add li to ul
ul.Controls.Add(li);
// add ul to div
containerDiv.Controls.Add(ul);
[/csharp]
Resulting in this HTML:
Wha? So if I use a <span> all is good and a <form> kills the first one? I don’t get it. I still don’t get it, and I’ve not had time to dig into it. in the end I just altered the jQuery to look for closest(‘span’) instead of closest(‘form’) and everything was peachy.
If anyone knows why this might happen, please do comment. It’s bugging me.