I have a table in my aspx page:
<table id="tbl" runat="server">
</table>
I need to set to set the table caption in the code behind, so that it renders as follows:
<table id="tbl" runat="server">
<caption>Monthly savings</caption>
</table>
Any help will be greatly appreciated.
The previous response from Brad M is almost correct, you must add a runat="server" attribute, an ID attribute and set it to some value you see fit, and then on the server side code:
One big caveat thought, you need to place the caption before the table element, inside is not possible
idYouGave.InnerText = "Monthly savings";
Since you can't use the directly inside the , do something like this to achieve what you want:
<tr>
<th colspan="numOfCols"><caption>...</caption></th>
</tr>
Just add the runat="server" attribute to your caption element, as well as give it an ID. Then just refer to it in code behind as caption.InnerText = "Monthly savings";
It is not possible. Control HtmlTable can contain <tr> and only them, everything else will be removed. Here is the full note from MSDN:
A complex table model is not supported. You cannot have an HtmlTable
control with nested <caption>, <col>, <colgroup>, <tbody>, <thead>, or
<tfoot> elements. These elements are removed without warning and do
not appear in the output HTML. An exception will be thrown if you
attempt to programmatically add these table model elements to the
Control.Controls collection of the HtmlTable control.
Your options are either to switch to asp:Table control, or switch back to plain markup.
Related
Is there a way to set HtmlAgilityPack to leave the markup exactly as it was inputted? My issue is that I allow users to set the html layout of a data output on their website. The format they use is similar to ASP.NET's repeater control.
Take the following example:
<table>
<ItemTemplate>
<tr>
<td>
<div>Item Markup</div>
</td>
</ItemTemplate>
<AltItemTemplate>
<td>
<div>Alternate Item Markup</div>
</td>
</tr>
</AltItemTemplate>
</table>
When I load this into HtmlAgilityPack, it will add the closing tr tag to the ItemTemplate and remove the actual closing tr tag from the AltItemTemplate. Later in the processing, the <ItemTemplate></ItemTemplate> and the alternate tags are removed, which would result in valid html. When HtmlAgilityPack loads this in, it will not result in valid html.
I can and have successfully parsed this via string manipulation, however, I thought if I could use HtmlAgilityPack then it would be more efficient and easier to work with.
Anyone know if I can use HtmlAgilityPack to do this? or if I should just stick with the string manipulation (.NET's substring, indexof, remove, etc).
Short answer is no. If you need to manipulate the content as a DOM, the HTML has to be correctly nested.
However, if you can live with all TR content as pure text (not DOM), than you could add this at the beginning of your processing:
ElementsFlags.Add("tr", HtmlElementFlag.CanOverlap | HtmlElementFlag.Empty);
But like if say, if you do this, everything between TR tags will be seen as text data, not as a DOM tree, so for example, you won't be able to do XPATH queries on the child DIV nodes.
Well to tell HTMLAgilityPack to not try to fix the tags closers, you need to remove the tag from the elements flags:
dim hp as HtmlDocument
hp.LoadHTML(htmlcode)
hp.DocumentNode.ElementsFlags.Remove("tr")
Now check the hp.DocumentNode and you will see that HTMLAgilityPack didnt attempt to fix the tags closers
Dim dnode As HtmlAgilityPack.HtmlNode = hp.DocumentNode
dim tosee as strin = dnode.OuterHTML
Man, I never really learnt all the embedded code blocks and stuff you can use in ASP.NET. What I'm trying to do is the following:
I have a repeater
It renders a table
In each row, I need to add a data-bind attribute (yes, for Knockout) containing some text and the rowindex.
More specifically, I want to render:
<table>
<tr data-bind="with:myItems()[0]">
...
</tr>
<tr data-bind="with:myItems()[1]">
...
</tr>
<tr data-bind="with:myItems()[2]">
...
</tr>
</table>
I've tried:
data-bind="<%# String.Format("myItems()[{0}]", Container.ItemIndex) %>"
But that doesn't work (data-bind="<%# Container.ItemIndex %> will however. So I'm trying to combine code with information from the databound item.
I know there is a foreach binding in Knockout, but I can't use it because:
I want/need my HTML to be constructed server-side initially
There's other, specific javascript that needs the HTML to exist already so I can't let Knockout populate the table
I'm using an ASP.NET Repeater, which doesn't mix well with Knockout's templates.
I also know, I could just do this in code-behind (with <tr runat="server" ... >) but I'm trying to put all my layout and javascript in markup and js files, not in C# code.
So, can I, in some way, add code in my markup to combine text I choose, with info from the current databound item?
Bummer, apparently, the answer is dead simple, and it didn't work the first time because of another mistake I made:
<tr data-bind="with: myItems()[<%# Container.ItemIndex %>]">
I put more info on my Blog and a working example on GitHub.
I have the following code:
<tr id="test" runat="server">
<td align="<%=myalignment%>">
I set myalignment = "center", however, when the page is rendered, it doesn't grab the variable. It just shows exactly how it is above. I wanted to programatically change certain TDs to "center" or "left" and I thought this would work. Any ideas?
If tr doesn't have runat="server", then it works fine...
Controls that run server-side can't have properties set declaratively and resolved dynamically via the <%= %> (Response.Write) syntax.
Expressions can be used, or in a pinch, you can use <%# %> databinding syntax, but then you need to call DataBind() on the control or page, and that can have nasty side effects.
As an alternative, you should be able to iterate over cells or reference specific cells in the codefile. You might have to add the runat=server attribute to each cell as well -- not sure about that.
I'm stumped by a seemingly simple problem. In my ASP.NET page, I have a table which has a few rows that need to be shown or hidden conditionally from the back end. Sounds simple, right?
What I tried is something like this in the front-end code:
<table>
<tr>
<td id="demorow1">
<p>This row always shows up!</p>
</td>
</tr>
<tr id="conditionalrow" runat="server">
<td id="formoptionsrow">
<!-- This row contains a number of form elements that should only SOMETIMES be shown, as determined by the back-end code. -->
</td>
</tr>
</table>
And in the code-behind file I just do this to hide the code:
conditionalrow.Style["display"] = "none";
This makes the row disappear as intended. I don't mind that it's just invisible, it won't hurt anything. However, this has the side-effect of making several HTML form elements inside of conditionalrow gain ASP.NET's convoluted IDs and NAMEs. This throws off a lot of Javascript functions related to the form that I don't have time to change or rework right now. I need to be able to hide the form (or remove it from the code entirely) from the code behind file, but without changing the IDs and NAMEs of child elements.
I know there's some kind of setting in the newer versions of ASP.NET that allows you to override ASP.NET's ID reassignment. Unfortunately, I'm stuck with ASP.NET 2.0 and don't have the option of using anything newer for this project. What do you recommend?
Instead of making the row a server side control, use a code block to give it an appropriate CSS class.
<tr class="<%:VisibilityClass%>">
Where, in your code behind you have a VisibilityClass string property that return the CSS class name:
public string VisibilityClass
{
get
{
if(shouldBeVisible)
return "visible";
return "hidden";
}
}
You can also use functions if a property is not appropriate.
can you not do a conditionalrow.Visible = false;
I have an <asp:ListView> but for some reason the LayoutTemplate section does not show when the list is empty, although the <EmptyDataTemplate> section shows. The LayoutTemplate contains the headers for the table, and I want to show an empty table when there are no items in the datasource, not just the content of EmptyDataTemplate.
If there is no choice I will copy the LayoutTemplate into EmptyDataTemplate but it seems stupid to have to do this. Ideas?
From the MSDN:
The empty template is displayed in a
ListView control when the data source
that is bound to the control does not
contain any records and the
InsertItemPosition property is set to
InsertItemPosition.None. The template
is rendered instead of the
LayoutTemplate template. If the
InsertItemPosition property is set to
a value other than
InsertItemPosition.None, the
EmptyDataTemplate template is not
rendered.
the key words here are "...the template is rendered instead of the LayoutTemplate template..."
So I think, you have to copy the LayoutTemplate into the EmptyDataTemplate template.
In a very simple way you can get both your headers and a message saying that there were no data.
You make your LayoutTemplate like the following idea:
<LayoutTemplate>
<table>
<tr>
<td>a header</td>
<td>another header</td>
<td>third header</td>
</tr>
<tr runat="server" id="itemPlaceholder">
<td colspan="3"
There is no data!
</td>
</tr>
</table>
</LayoutTemplate>
Notice that the tr that is the placeholder (marked by id="itemPlaceholder") actually contains something. It contains what should be shown when there is no data. Then, in code behind, you set the <EmptyTemplate> to be equal to the <LayoutTemplate> (so that you have only one such template to maintain). I do it like this:
Private Sub lvwThings_Init(sender As Object, e As EventArgs) Handles lvwThings.Init
lvwThings.EmptyDataTemplate = lvwThings.LayoutTemplate
End Sub
The logic then is as follows:
When there is data, i.e. when the actual <LayoutTemplate> is used, the whole <tr runat="server" id="itemPlaceholder">, with the td and text it contains, will be replaced by the <ItemTemplate>.
But, when there is no data, i.e. when the <EmptyTemplate> is used (instead of the <LayoutTemplate>), nothing inside the <EmptyTemplate>is replaced, so everything is shown as it is.
You can also put your into a User Control (.acsx). Then include it in the layout template and the empty template... and it will feel less stupid since you can still manage it in one spot. I know how you feel about copying the same code...seems like something a 5th grader would do. Using a control is a more grown up approach.
I just solved this problem when you have InsertItemTemplate with EmptyDataTemplate.
Arrcording to MS docs, that's you can't have both. So I decided to create new tag in InsertItemTemplate.
You can preview my example code here.
<InsertItemTemplate>
<% if (CheckEmptyTable())
{ %>
<tr>
<td colspan="6">No data founds。</td>
</tr>
<% } %>
// Your insert template input here
<tr style="">
</tr>
</InsertItemTemplate>
My result image: