I have a list defined like so:
<ul id="myList" class='myClass'>
<li class="myItemClass">Item 1</li>
<li class="myItemClass">Item 2</li>
</ul>
using .NET how can I add items to the list dynamically? I also need to specify the class name on each new item
you can even use that HTML, adding runat="server" you will be able to treat it as a HTMLControl no mater what control it is, I do this often with div's
<ul id="myList" runat="server" class="myClass">
<li class="myItemClass">Item 1</li>
<li class="myItemClass">Item 2</li>
</ul>
then you get that HTMLControl and play with it
HtmlGenericControl li;
for (int x = 3; x <= 10; x++)
{
li = new HtmlGenericControl("li");
li.Attributes.Add("class", "myItemClass");
li.InnerText = "Item " + x;
myList.Controls.Add(li);
}
you will end up with:
<ul id="myList" runat="server" class="myClass">
<li class="myItemClass">Item 1</li>
<li class="myItemClass">Item 2</li>
<li class="myItemClass">Item 3</li>
<li class="myItemClass">Item 4</li>
<li class="myItemClass">Item 5</li>
<li class="myItemClass">Item 6</li>
<li class="myItemClass">Item 7</li>
<li class="myItemClass">Item 8</li>
<li class="myItemClass">Item 9</li>
<li class="myItemClass">Item 10</li>
</ul>
of course that you can use an ordered or unorderer list, they also below to the ASP.NET Web Controls.
<asp:BulletedList runat="server" ...
You could use asp:BulletedList like
<asp:BulletedList ID="MyList1" CssClass="MyClass" runat="server">
<asp:ListItem Text="Item1" class="MyClass" />
</asp:BulletedList>
Add add code like
ListItem item = new ListItem("Item2");
item.Attributes.Add("class", "MyClass");
MyList1.Items.Add(item);
Or if for some specific reason you need to use the ul tag then you can add a runat="server" to it. E.g.
<ul id="MyList2" class="MyClass" runat="server">
<li class="MyClass">Item1</li>
</ul>
With code like
HtmlGenericControl li = new HtmlGenericControl("li");
li.Attributes.Add("class", "MyClass");
li.InnerText = "Item2";
MyList2.Controls.Add(li);
The simplest way you can solve this problem is by using the asp repeater control
<ul id="myList" class='myClass'>
<asp:Repeater ID="repeaterMyList" Runat="server">
<ItemTemplate>
<li class="myItemClass">
<%# Eval("Item") %>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
[Edit] - Do remember to set the datasource on repeaterMyList and call databind on the repeater control in the codebehind.
repeaterMyList.DataSource = someDataTable;
repeaterMyList.DataBind();
I'm assuming that there is a valid reason for you not to use the BulletedList webserver control. Anyway, this is an interesting programming exercise that illustrates the internals of the Htmlservercontrol architecture and how they map to simple HTML tags.
The HTML ul and li tags are not directly mapped as HTMLServercontrols. This means that even if you add a runat="server" attribute to the list, it's contents will not be directly accessible as listitems.
However, all controls not directly mapped as Html server controls are accessible via the HtmlGenericControl class. This makes it possible to create and modify such controls dynamically.
The solution, therefore, is twofold:
Make the unordered list runat="server" so that you can access it in server-side code. Also, you should make the existing items in the list runat="server", else they will be only be accessible as an LiteralControl that contains the first two listitems as plain text.
In code, access the contents of the list and add a new HtmlGenericControl of type "li" to it.
The following (bare-bones simple) page demonstrates this procedure :
<%# Page Language="VB" AutoEventWireup="false" %>
<%# Import Namespace="System.Collections.Generic" %>
<script runat="server">
Private Shared addedItems As List(Of HtmlGenericControl)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
'On first load, instantiate the List.
addedItems = New List(Of HtmlGenericControl)
End If
End Sub
Protected Sub btn1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
'Add the previously created items to the UL list.
'This step is necessary because
'...the previously added items are lost on postback.
For i As Integer = 0 To addedItems.Count - 1
myList.Controls.Add(addedItems.Item(i))
Next
'Get the existing no. of items in the list
Dim count As Integer = myList.Controls.Count
'Create a new list item based on input in textbox.
Dim li As HtmlGenericControl = CreateBulletItem()
'Add the new list item at the end of the BulletedList.
myList.Controls.AddAt(count, li)
'Also add this newly created list item to the generic list.
addedItems.Add(li)
End Sub
Private Function CreateBulletItem() As HtmlGenericControl
Dim li As New HtmlGenericControl("li")
li.InnerText = txtNewItem.Value
li.Attributes("class") = "myItemClass"
Return li
End Function
</script>
<html>
<head runat="server">
<title>Test Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<ul id="myList" class='myClass' runat="server">
<li runat="server" class="myItemClass">Item 1</li>
<li runat="server" class="myItemClass">Item 2</li>
</ul>
<input type="text" id="txtNewItem" runat="server" />
<asp:Button ID="btn1" runat="server" Text="Add" OnClick="btn1_Click" />
</div>
</form>
</body>
</html>
Related
Here is a snippet of my code:
<%for (int i = 1; i <= MessageList.Count; i++)
{
switch (LevelList[i-1])
{
case 0:%>
<div class="well offset1" style="width:80%">
<h1><%= MessageList[i - 1].Header%></h1>
<p><%= MessageList[i - 1].Body%></p>
<ul>
<li style="display:inline">Likes: <%= MessageList[i - 1].NumberOfLikes%></li>
<li style="display:inline">Replies: <%= MessageList[i - 1].NumberOfReplies%></li>
</ul>
<ul>
<li style="display:inline"><asp:Button ID="LikeButton" messID="<%# MessageList[i-1].MessageID %>" runat="server" Text="Like" /></li>
<li style="display:inline"><asp:Button ID="ReplyButton" messID="<%# MessageList[i-1].MessageID %>" runat="server" Text="Reply" /></li>
</ul>
</div>
<%break;
My problem is with the "messID" in this part:
<li style="display:inline"><asp:Button ID="LikeButton" messID="<%# MessageList[i-1].MessageID %>" runat="server" Text="Like" /></li>
At first I was attempting to pass a variable to the codebehind using messID="<%= calculated value%>" and using Button.Attribute["messID"] to access this variable, however, instead of passing the calculated variable as a string this passed a string that looked <%= calculated variable%>. After some research I found out that the <% could not be used with asp controls. So now I am attempting to use the <%# tag and DataBind(), however, now whatever is inside the <%# tags is not recognizing the variable i which is part of the forloop. Why does this happen?
Why not you just use html a tag?
All I want to do is to procedural generate buttons on my page, each of which will correspond to a message. When a user clicks on one of the reply buttons, it takes them to a page where they can write their response.
change
<li style="display:inline"><asp:Button ID="LikeButton" messID="<%# MessageList[i-1].MessageID %>" runat="server" Text="Like" /></li>
to
<li style="display:inline">Like</li>
I tried Menu, TreeView, BulletedList, Repeater, HtmlGenericControl but without result.
What I would like to have is asp control which render something:
<ul>
<li>Item 1</li>
<li>Item 2
<ul>
<li>Item 2.1</li>
</ul>
</li>
</ul>
For example menu it's render SPAN no UL.
<asp:Menu runat="server">
<Items>
<asp:MenuItem Text="Item 1" />
<asp:MenuItem Text="Item 2">
<asp:MenuItem Text="Item 2.1" />
</asp:MenuItem>
</Items>
</asp:Menu>
I also tried
<asp:Menu RenderingMode="MenuRenderingMode" />
But it's not working. I'm using ASP.NET 3.5.
I need create dynamic ul list and after click on item it will check in db if exist nested items and add them to clicked list as nested ul.
I cant render whole menu at once because of performence.
Sorry if I'm not very clear.
Thanks for help.
You need to use nested repeaters:
<asp:Repeater ID="rptFoo" runat="server" OnItemDataBound="rptFoo_ItemDataBound">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:HyperLink ID="lnkFoo" runat="server" />
<asp:Repeater ID="rptBar" runat="server" OnItemDataBound="rptBar_ItemDataBound">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><asp:HyperLink ID="lnkBar" runat="server" /></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
And then in the ItemDataBound handler, you need to check whether each top level item has child elements, if it does, assign those elements to the sub repeater and databind, else hide it.
protected void rptFoo_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
{
FooType obj = (FooType)e.Item.DataItem;
Repeater rptBar = (Repeater)e.Item.FindControl("rptBar");
if(obj.Children.Count() > 0)
{
rptBar.DataSource = obj.Children;
rptBar.DataBind();
}
else
{
rptBar.Visible = false;
}
}
}
If you just need access to the ul and li elements from codebehind you can easily add a runat="server" attribute to them. The id attribute is necessary in order to be able to reference a single element:
<ul id="mainMenu" runat="server">
<li id="mainMenuItem1" runat="server">Item 1</li>
<li id="mainMenuItem2" runat="server">Item 2
<ul id="subMenu" runat="server">
<li id="subMenuItem1" runat="server">Item 2.1</li>
</ul>
</li>
</ul>
This structure could also be build from codebehind using HtmlGenericControls.
Another option could be to use user controls: http://msdn.microsoft.com/en-us/library/y6wb1a0e%28v=vs.100%29.aspx
I have this code. This code is a part of my menu items:
<li class="" id="fifth-li">
<ul style="visibility: hidden; display: none;" id="fifth-ul">
<li><asp:HyperLink ID="hpl_undergraduate" runat="server"></asp:HyperLink></li>
<li><asp:HyperLink ID="hpl_graduate" runat="server"></asp:HyperLink></li>
</ul>
<asp:HyperLink ID="hpl_lessons" runat="server">
<asp:Image ID="img_lessons" runat="server" />
<strong></strong>
<em id="em_lessons" runat="server"></em>
</asp:HyperLink>
</li>
And this is a part of my .cs code file:
em_lessons.InnerHtml = lang["MENU_LESSONS"];
hpl_lessons.Text = lang["MENU_LESSONS"];
hpl_undergraduate.Text = lang["MENU_UNDERGRADUATE"];
hpl_graduate.Text = lang["MENU_GRADUATE"];
hpl_lessons.NavigateUrl = "lessons.html";
hpl_undergraduate.NavigateUrl = "lessons-801.html";
hpl_graduate.NavigateUrl = "lesson-802.html";
img_lessons.ImageUrl = "images/lessons.png"; //Here the image url is defined.
This code is for my web page's menu. There are a few more items like this. I add an image to the img_lessons object on the codebehind. But after running the page I get this code:
<li class="" id="fifth-li">
<ul style="visibility: hidden; display: none;" id="fifth-ul">
<li>
<a id="MainContent_hpl_undergraduate" href="lesson-801.html">
Undergraduate
</a>
</li>
<li>
<a id="MainContent_hpl_graduate" href="lesson-802.html">
Graduate
</a>
</li>
</ul>
<a id="MainContent_hpl_lessons" href="lessons.html">
Lessons
</a>
</li>
I was thinking that if I pull out img_lessons between <asp:HyperLink></asp:HyperLink>, the image would have been shown. But no way. I have changed the codes a bit to be cleaner.
The point is not about the image path, is about some programmatic incompetence/inconvenience. Because I do not see a <img id="MainContent_img_lessons" ... /> code on the browser's code view.
As you can see my image does not look. What do you think?
Regards.
When you do this:
hpl_lessons.Text = lang["MENU_LESSONS"];
you are wiping out any and all markup from the inside of the hyperlink.
EDIT: Since it looks like you already have a <em> tag that you have made a server tag, this line:
em_lessons.InnerHtml = lang["MENU_LESSONS"];
should already be setting viewable text, so, really, you should only have to remove the line mentioned above.
You are clearing the hyperlink innerHTML when you are setting the .Text to lang["MENU_LESSONS"]
What you would need to do is change your markup as follows:
<asp:HyperLink ID="hpl_lessons" runat="server">
<asp:Image ID="img_lessons" runat="server" />
<strong><asp:Literal ID="lit_lessons"/></strong>
<em id="em_lessons" runat="server"></em>
</asp:HyperLink>
And then change your code so that it reads
lit_lessons.Text = lang["MENU_LESSONS"];
I have a little problem with my ASP.Net Page.
I'm trying to get all controls from my masterpage within the masterpage code.
I did this with the Child page using this code
foreach (Control ctrl in ContentPlaceHolder1.Controls)
{
if (ctrl.GetType() == typeof(Label))
{
//Do Stuff...
}
}
but when i try to get the other controls with
foreach (Control ctrl in this.form1.Controls)
it doesn't work completly.
I get 3 of my Labels but can't access the rest.
Here is a part of my ASP Code
<div style="float: right;">
<ul class="main-language language-level main-language-level-0" >
<li><a href="">
<asp:Label runat="server" Text="Deutschland" ID="lbl_Language"/>
</a>
<ul class="language-level main-language-level-1">
<li>
<a href="?Lng=EN">
<asp:Label ID="lbl_English" runat="server" Text="United Kingdom" ForeColor="#0D679C" Font-Names="Century Gothic" />
</a>
<span>English</span>
</li>
<li>
<a href="?Lng=DE">
<asp:Label ID="lbl_German" runat="server" Text="Deutschland" ForeColor="#0D679C" Font-Names="Century Gothic" />
</a>
<span>Deutsch</span>
</li>
</ul>
<img class="menu-image" src="Images/arrow_languageselection.png" />
</li>
</ul>
<br />
<a href="CustomerServiceLogin.aspx?Lgn=22TR" runat="server" id="LogLink">
<asp:Label CssClass="ButtonOrange" runat="server" ID="lbl_Login" />
<asp:Label CssClass="ButtonOrange" runat="server" ID="lbl_Logoff" Visible="false" />
</a>
</div>
The only labels i can find are lbl_Language,lbl_English and lbl_German
Has somebody a solution for this?
Sincerely
CarnVanBeck
If the labels that you cannot access are nested inside another control then they will not be returned when you iterate over form1.controls. You will need a recursive solution to return all of your controls.
foreach (Control ctrl in this.form1.Controls)
{
if (ctrl.Controls.Count > 0)
{
// do recursive call
}
}
I want to populate a List dynamically and display the list when i hover over a button
<div class="invite">
<asp:Button ID="Button1" runat="server" Text="Invite" CssClass="invite-link"/>
<div class="invite-drop">
<div class="holder">
<ul runat="server">
<li>
<a href="#">
<img src="images/img3.png" width="22" height="22" alt="image description" />
<span>Chris Robin</span>
</a>
</li>
<li>
<a href="#">
<img src="images/img3.png" width="22" height="22" alt="image description" />
<span>Danny Defoee</span>
</a>
</li>
<li>
<a href="#">
<img src="images/img3.png" width="22" height="22" alt="image description" />
<span>Gustav Lee</span>
</a>
</li>
<li>
<a href="#">
<img src="images/img3.png" width="22" height="22" alt="image description" />
<span>Eric Rees</span>
</a>
</li>
</ul>
<a class="select" href="#">Or select friend</a>
</div>
</div>
</div>
My list is as follows and i am trying to construct it dynamically :
HtmlGenericControl list = new HtmlGenericControl("ul");
for (int i = 0; i < 3; i++)
{
HtmlGenericControl listItem = new HtmlGenericControl("li");
HtmlGenericControl anchor = new HtmlGenericControl("a");
Image im = new Image();
//im.ImageUrl = ds.Tables[0].Rows[1].ItemArray.ToString();
anchor.Attributes.Add("href", "");
anchor.Controls.Add(im);
anchor.InnerText = "TabX";
}
EDIT :
i have been successful in transferring the list from codebehind however the formatting isnt correct want to display the images one below the other
My question is how do i transfer it to aspx design page? and display it on the hover event
Please help
Add the dynamically created ul from server side into Page controls collection or anywhere on the page and make it hidden by default through css or inline style display:none. Give an id or class to ul which will help to find the element on the client side.
On the client you can find it using $('ul.classname') or $('#listId) and then show it using show() on the hover event and position it as per your requirement.
Based on your code.
Give an id to ul
<ul ID="list" runat="server">
Note in the for loop you should add the anchor to the list control.
for (int i = 0; i < 3; i++)
{
HtmlGenericControl listItem = new HtmlGenericControl("li");
HtmlGenericControl anchor = new HtmlGenericControl("a");
Image im = new Image();
//im.ImageUrl = ds.Tables[0].Rows[1].ItemArray.ToString();
anchor.Attributes.Add("href", "");
anchor.Controls.Add(im);
anchor.InnerText = "TabX";
list.Controls.Add(anchor);
}
Js
$('.invite-link').hover(function(){
$('#list').show();
}, function(){
$('#list').hide();
});