I have an ASP.NET web app that retrieves a JSON collection and outputs the content of the collection, via LINQ to a StringBuilder that has a lot of table and other tags in HTML, with my data pieces interspersed.
This is what I mean:
sb.AppendFormat(#"
<table cellpadding=""0"" class=""TableStyle"" style=""width: 70%; height: 100%;"" cellspacing=""5"">
<tr>
<td class=""PicHolder"" style=""width: 151px"" rowspan=""2"">
<a href=""http://twitter.com/{0}"" target=""_blank""><img height=""45px"" width=""45px"" src=""{1}"" alt=""{4}""></td>
<td style=""width: 100%; height: 36px;"" class=""LinkTitleCell"" valign=""top"">
<span class=""BoldText"" style=""height: 23px"">
<span class=""HyperLinks"">{6}</span></span></ br><span class=""NormText"">
</tr>
<tr>
<td style=""width: 100%; height: 10px;"" class=""MentionedXTimes"" valign=""top"">
<span class=""NormText"">Mentioned {3} time(s).</span></td>
</tr>
<tr>
<td style=""width: 151px"" class=""UserName""><span class=""UserName""><img height=""1"" src=""spacer.gif"" width=""1"" />{4}:</span></td>
<td style=""height: 23%; width: 100%"" class=""WhatUserSaid"" valign=""top"">
{5}</td>
</tr>
<tr>
<td style=""width: 151px"" class=""UserName"">Info:</td>
<td style=""height: 24px; width: 100%"" class=""LinkTitleCell"" valign=""top""><span class=""NormText"">{7}</span></td>
</tr>
<tr>
<td style=""height: 9px; width: 151px""></td>
<td class=""LinkGreen"" style=""height: 9px; width: 100%"" valign=""top"">{2}</td>
</tr>
<tr>
<td style=""height: 9px; width: 151px""> </td>
<td class=""TableSpacer"" style=""height: 9px; width: 100%"" valign=""top""> </td>
</tr>
</table>",
count.First.userName, count.First.imgURL, newdata, count.Count, count.First.userName, count.First.txtDesc, (title != string.Empty) ? title2 : newdata, metaDesc2);
You can see all of the {0} and {1} data place holders I am using in the code above, and the reference to the data required at the end of the StringBuilder method call.
I want to be able to separate the HTML from my app so that I can edit it more easily without having to escape all of the "" quote marks.
So I need a template that has place holder for where my data goes. This is a noob question and I know exactly what want but not how to implement it.
Any help much appreciated!
I'm getting some bad vibes here, like you're building the entire page or at least a very large part of it inside a single stringbuilder for output. This is a very bad thing to do.
If you want to "accumlate" your page string like this, you should write to the Response object directly instead. The StringBuilder forces you to keep all that html in memory on your server for every request, and memory use like this on a web server just won't scale well when you have many requests going at once. Even worse, there's a chance of these stringbuilders ending up on the Large Object Heap. If that happens it could ultimately cause OutOfMemoryExceptions. By contrast, the Response object buffers your html as you write it, and so you only use memory per request up to the size of the buffer. That will scale/perform much better.
Even better, though, is if you work with ASP.Net to make this happen rather than against it. That solves both the scaling problem and your "templating" problem. For example, I'll show you a better way to adapt just a small snippet of the html you posted. First write your .aspx markup like this:
<table cellpadding="0" class="TableStyle" style="width: 70%; height: 100%;" cellspacing="5">
<tr>
<td class="PicHolder" style="width: 151px" rowspan="2">
<asp:HyperLink runat="server" ID="TwitterLink" target="_blank">
<asp:Image runat="server" ID="TwitterLinkImage" Height="45px" Width="45px"/>
</asp:HyperLink></td>
...
</tr>
And then use code like this in your .cs code-behind:
TwitterLink.NavigateUrl = "http://twitter.com/" + count.First.userName;
TwitterLinkImage.ImageUrl = count.First.imgURL;
TwitterLinkImage.AlternateText = newdata;
There you go. Clean separation of markup and code/data that's more readable, avoids all the messy escaping, and will perform even better than your stringbuilder. If you have a lot of records that are exactly the same and you still want fine control over your HTML output, use an <asp:Repeater> control and set up markup like this in it's ItemTemplate. Then c# code will go in the repeater's ItemDatabound event.
As with most things there are a number of ways of doing it; from the pure code behind which you have as your original question through to the pure client side / jquery templating.
Another option would be to have a user control with the html part of the output in. This could have an associated property with the data object assigned to it. You could then access the data in the html you would put somethihng like:
<%= MyClass.Property %>
Where ever you want that value to appear in the html.
So what I'd look to do (not tested as don't have VS installed on this machine) is the following:
create a class which will store the data which you will be receiving in json format
Create the user control
Specifiy a property on the control which takes an instance of your class defined above
Add the control onto your aspx page
In the code behind of the aspx page set the retrieval and parsing of the json data in the Page_Load event.
Still in the Page_Load; assign the newly created instance of the object to the usercontrol property
Once this is done when the page renders the user control can access the data and display it through the mechanism (bit of code) above.
Hope this helps, been doing a lot of MVC stuff recently so my Web Forms is a little rusty :-)
If this doesn't make much sense, I appologise in advance and if you let me know I will try and update the post with some more code examples to try and make it make more sense :-)
Perhaps it's better to return the data as json to the browser and there use jqGrid or jQuery template.
Grz, Kris.
Related
I am on the server side of an asp.net application. There I have some html source code in a variable called 'HtmlText'. This source code is generated from xml via a xsl transformation, and is resulting in something like this:
<h1>ABC Test KH</h1>
<!--place for the control-->
<table class="tablesorter" id="tablesorter183">
<thead>
<tr>
<th align="left">Name</th>
<th align="right">DB</th>
<th align="right">DB Anteil in Prozent</th>
<th align="right">ABC</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" fieldName="Name">Fabrikam, Inc.</td>
<td align="right" fieldName="DB">881.378,00 €</td>
<td align="right" fieldName="DB_Anteil_in_Prozent">29,92</td>
<td align="right" fieldName="ABC">A</td>
</tr>
</tbody>
</table>
Now this source code is inserted in a aspx-website via the InnerHtml-property.
There is a div with id 'book' in that aspx:
book.InnerHtml = HtmlText
This works fine so far.
But now I want to create a dropdown-control in that html, which I can access on server-side. This control should be placed between the h1 and table-tags, where the comment <!--place for the control--> is located.
I know how to create asp-control dynamically and bind an event to that, but this works only if I have the aspx in the first place. I cannot do that to some html-source which exists just in a string at that time.
Is there any way to do what I want, or am I on the wrong track here?
Thanks in advance for any suggestions.
Kind regards,
Kai
I think the only solution is to create a control that inherits DropDownList, and override its RenderControl method.
Something like this:
public override void RenderControl(HtmlTextWriter writer)
{
//...
//Fill in the variable HtmlText content
//Split it to 2 variables - before and after the control place, and:
writer.Write(startString);
base.RenderControl(writer);
writer.Write(endString);
}
And use this control instead of DropDownList.
EDIT: In a case of several controls, I would use the way suggested here: Render .net controls to string and get events to fire:
Split the string to several strings - the first string - from the beginning to the first control, second string - from the first control to the second control, and so on.
And then insert each of the strings to a new LiteralControl, and add them to the page Like this:
book.Controls.Add(LiteralControl1);
book.Controls.Add(DropDownList1);
book.Controls.Add(LiteralControl2);
book.Controls.Add(Button1);
I have some code that gets a web response. How do I take that response and search for a table using its CSS class (class="data")? Once I have the table, I need to extract certain field values. For example, in the sample markup below, I need the values of Field #3 and Field #5, so "85" and "1", respectively.
<table width="570" border="0" cellpadding="1" cellspacing="2" class="data">
<tr>
<td width="158"><strong>Field #1:</strong></td>
<td width="99">1</td>
<td width="119"><strong>Field #2:</strong></td>
<td width="176">110</td>
</tr>
<tr>
<td width="158"><strong>Field #3:</strong></td>
<td width="99">85</td>
<td width="119"><strong>Field #4:</strong></td>
<td width="176">-259.34</td>
</tr>
<tr>
<td width="158"><strong>Field #5:</strong></td>
<td width="99">1</td>
<td width="119"><strong>Field #6:</strong></td>
<td width="176">110</td>
</tr>
<tr>
<td width="158"><strong>Field #7:</strong></td>
<td width="99">12</td>
<td width="119"><strong>Field #8:</strong></td>
<td width="176">123.23</td>
</tr>
</table>
Use the HTML Agility Pack and parse the HTML. If you want to do it the simplest way then go grab its beta (it supports LINQ).
As Randolf suggests, using HTML Agility Pack is a good option.
But, if you have control of the format of the HTML, it is also possible to do string parsing to extract the values you are after.
It is nearly trivial to download the entire HTML as a string and search for the string "<table" followed by the string "class=\"data\"". Then you can easily extract the values you are after by doing similar string manipulations.
I'm not saying you should do this, for the resulting code will be harder to read and maintain that the code using HTML Agility Pack, but it will save you an external dependency and your code will probably perform much better.
In a WP7 app I made, I started using HTML Agility Pack to parse some HTML and extract some values. This worked well, but it was quite slow. Switching to the string parsing regime made my code many times faster while returning the exact same result.
I am developing Web Application. In that i am using so many Div to open pop ups. Now my requirement is to create dynamic Div for that popup and all the content of that div comes from the Database.
So can anyone tell me how to create Div dynamically programatically?
My Sample code for Div..
<div id="Popup" runat="server" class="hidden-content">
<table width="auto">
<tr>
<td style="font-size: 20px; font-weight: bold; text-align: center;">
<p>
</p>
<b>Diabetes</b>
</td>
</tr>
<tr>
<td style="font-size: 15px; text-align: left;">
<p>
Type I diabetes (also known as juvenile diabetes) is the less common form of diabetes.
It usually is diagnosed during childhood or teen years and requires treatment with
insulin.
</p>
</td>
</tr>
</table>
</div>
I would insert either a PlaceHolder or a Literal control into you page and insert the html controls/text on PageLoad or PageRender.
If you use the Placeholder control you can create the content using the HTML controls in System.Web.UI.HtmlControls.
By using the Placeholder control, you could also write a custom WebControl that you could re-use in other locations within your site. This could then be added to the placeholder control at runtime.
For a liteal, you can just append the control div HTML as text.
you can add html using stringbuilder
Use below cose to add html programmatically.
using System.Text;
StringBuilder strdiv = new StringBuilder();
strdiv.Append("Put your Html here");
strdiv.Append("Add much as you want ");
after that assign that stringbuilder to label so get one label in html with id "htmllabel"
Add below line to append html in your label.
htmllabel.Text = strdiv.ToString();
You need to use the defined server control called asp:Panel, which gets rendered as a div. Create your panels programatically and add them to your page: e.g. Page.Controls.Add(myPanel);
I was working on a web application in which i need same thing as you require from here you will get some idea and make some modifications as per your requirement.Check my article here
If you have any doubt then ask.
Thanks :-)
This is inline code of a .aspx page:-
<table>
<tr>
<td>Some static data</td>
<td>Text box control</td>
<td><div id="div1"></div></td>
</tr>
</table>
Third <td> has a div 'div1'. This div does not have any data most of time on that page. But sometimes i need to display some dynamic data there). Now problem is, if there is no data in div 'div1', firefox consider it as a space in it and takes approx. 5px space in browser. (But IE8 in compatibility view is fine)
What is the work around here for firefox?
I'd consider if you actually need the div - I guess you are filling it with data in certain circumstances by targetting the ID, by why not just target the table cell instead?
<table>
<tr>
<td>Some static data</td>
<td>Text box control</td>
<td id="div1"></td>
</tr>
</table>
Try setting all margins and padding to 0 at the start of your CSS.
*{
margin: 0;
padding: 0;
}
And then you can set those values explicitly where required.
That's because you have a padding applied to the td elements. You could do this: <td style="padding:0"><div id="div1" style="display:none; padding:1px;"></td>
And shift the padding to the div element and the hide it when it is empty. Firefox doesn't apply any padding to it in that case. But, it should still look like other tds when there is data applied to it.
It sounds like you need to reset your styles. There's a couple of good ones out there including Eric Meyer's CSS reset and Yahoo YUI2 CSS reset.
I am writing an application that requires that my customer can layout their input forms in which ever way they choose.
I would like to use an HTML template with placeholders, and then replace these with secified .NET controls at runtime:
<table style="width: 100%;">
<tr>
<td colspan="2">
<fieldset title="Customers Template" >
<table style="width:100%;">
<tr>
<td width="140">
Policy Number:</td>
<td width="150">
$$Policy Number$$</td>
<td colspan="2" rowspan="3" valign="top">
Type 1:<br />
$$Type 1$$</td>
<td rowspan="3" valign="top">
Info:<br />
$$Info$$</td>
<td rowspan="3" valign="top">
Problems:<br />
$$Problems$$</td>
</tr>...
So I want to find and replace my $$xxx$$ text with various .NET controls, depending on the datatype of the field being added, at runtime.
Any suggestions on good ways to approach this?
Thanks,
Mark
Replace your $$xxx$$ blocks with <asp:PlaceHolder> controls.
At runtime you can parse the template
--- In the most simplest case, you can require the template be valid xhtml, then you can simply use the .NET XML APIs to iterate through all the ChildNodes of the XmlDocument. From each element build the appropriate ASP.NET Server control.
For a more complex (and complete HTML parser) see http://www.developer.com/net/csharp/article.php/2230091
As you parse, wherever you see <asp:PlaceHolder> - replace that with your logic that defines your template.
Tutorial: http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=752
If you're going to replace these placeholders with only strings take a look at NVelocity template engine. In this answer, I simply show how you can create an email by a template.
But for asp.net server controls, you can split your html template into chunks, and add them to your page as LiteralControl like that :
Page.Controls.Add(new LiteralControl(#"<td width='140'>
Policy Number:</td>
<td width='150'>"));
Page.Controls.Add(textBox1);
Page.Controls.Add(new LiteralControl(#"</td><td colspan='2' rowspan='3' valign='top'>
Type 1:<br />"));