The above is the code in my .aspx page.
How this can be added from code behind dyanmically?
<ul runat="server" id="1">
<li>abc
<ul runat="server" id="2">
<li>3</li>
<li>2</li>
</ul>
</li>
</ul>
you can take the analogy of the tutorial given in this link :
http://neimke.blogspot.com/2011/01/create-delicious-user-interface-for.html
it worked for me - It dynamically adds the list items using the given code below using jquery .. check it pout ...
<li id="tagInputListItem"><input class="tagInput" id="tagInput" /></li>
You can put a PlaceHolder in your .aspx and give it an id, then use that id in code behind page and add controls to that placeholder.
For more information you can see in here.
And if you're really sure about "runat=server" attribute maybe this post of mine it's useful (here)
If you need clarifications give me a feedback.
You must use the "InnerHtml" property of "sidebarmenu1" control.
protected void Page_Load(object sender, EventArgs e)
{
this.loadHtml();
}
So you can generate every list item code and add it to the InnerHtml:
private loadHtml()
{
this.sidebarmenu1.InnerHtml = GetListHtml().ToHtmlString();
}
And a little example for this GetListHtml:
public string GetListHtml()
{
StringBuilder htmlBuilder = new StringBuilder();
htmlBuilder.AppendLine("<li>Flat");
htmlBuilder.Append("<ul runat="server" id="sidebarmenu2">");
htmlBuilder.AppendLine("<li>Flat 1`enter code here`</li>");
htmlBuilder.Append("<li>Flat 2</li></ul>");
return htmlBuilder.ToString();
}
This GetListHtml method can call to a DAL or load data from any other place... use a foreach to load every item...
You can use ASP Literal to populate data from back-end code
eg. if you have literal with id ltrNavigation
protected void Page_Load(object sender, EventArgs e)
{
ltrNavigation.text = "";
if (!IsPostBack)
{
ltrNavigation.text += "<ul id='sidebarmenu1'>";
ltrNavigation.text += "<li><a href='#'>Flat</a></li>";
ltrNavigation.text += "</ul>";
}
}
Related
I want to set HTML inside a div in my code, but the end result looks like this:
Here is my code:
protected void grdTags_SelectedIndexChanged(object sender, EventArgs e)
{
string RelatedText = grdTags.SelectedRow.Cells[5].Text;
dv.InnerHtml = RelatedText;
}
Here is the ASPX:
<div id="dv" runat="server">
</div>
It looks like you're passing in text into HTML. Consider using HttpUtility.HtmlEncode()
I've not tested this, but try:
dv.InnerHtml = HttpUtility.HtmlDecode(grdTags.SelectedRow.Cells[5].Text);
Please consider the following:
code behind:
public void InitiateTable()
{
Controls.Add(new LiteralControl("<table class=\"table table-invoice\" >")); //Line that gave me error
...
Controls.Add(new LiteralControl("</table>"));
}
on my ASP.Net page:
<% InitiateTable(); %>
When I run the code, it gives me an error saying:
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
Can someone please explain what I have done wrong?
Thank you.
Note Changed LiteralControl to Control as suggested in comment.
You cannot modify the controls collection where the container contains <% %> code blocks as the error message tells you. Controls.Add will modify the controls collection. To get around this:
In your aspx page change
<% InitiateTable(); %>
to
<asp:Literal runat="server" id="mytable" />
then in your page load method, add a call to InitiateTable()
then in your InitiateTable() method change your code to something like this:
public void InitiateTable()
{
var literalControlValue = new StringBuilder();
literalControlValue.Append("<table class=\"table table-invoice\" >");
...
literalControlValue.Append("</thead>"));
mytable.Text = literalControlValue.ToString();
}
Controls.Add(new LiteralControl("<table class='table table-invoice'>"));
The issue is when you use Controls you are referencing the Page itself rather than the area you call InitiateTable.
If you're inserting controls into this area, this is what a Placeholder is for:
<asp:Placeholder id="phTable"></Placeholder>
Then in your Page_Load or some other event code:
private void Page_Load(object sender, System.EventArgs e)
{
phTable.Controls.Add(new LiteralControl("<table class=\"table table-invoice\" >"));
phTable.Add(new LiteralControl("</thead>"));
}
If i have method like this to Draw my side Menu Dynamically :
private void DrawSideMenu()
{
LinkButton x;
TaskDTO TaskList = new TaskDTO();
List<TaskDTO> List = TaskList.DrawMenu(int.Parse(Session["emp"].ToString()));
HtmlGenericControl myDIV = new HtmlGenericControl("div");
myDIV.ID = "menu8";
HtmlGenericControl myOrderedList = new HtmlGenericControl("ul");//css clss for <ul>
myOrderedList.ID = "orderedList";
myOrderedList.Attributes.Add("class", "task");
HtmlGenericControl listItem1;
string count = "";
foreach (TaskDTO i in List)
{
count = AdjustMenuCount1(i.TaskCode);
x = new LinkButton();
x.ID = i.TaskCode.ToString();
x.Text = i.TaskName + " " + count;
x.Click += new EventHandler(TaskC);
x.Style["FONT-FAMILY"] = "tahoma";
listItem1 = new HtmlGenericControl("li");
listItem1.Attributes.Add("class", "normal");
if (count != "0")
{
listItem1.Controls.Add(x);
myOrderedList.Controls.Add(listItem1);
}
}
myDIV.Controls.Add(myOrderedList);
MenuTD.Controls.Add(myDIV);
Session["SideMenu"] = myDIV;//Save to redraw when page postbacks
}
This Method takes long time to draw my menu.so i call it one time in (!IsPostBack) and save it in session so that i could redraw it like that :
MenuTD.Controls.Add( ((System.Web.UI.Control)(Session["SideMenu"])));
It redraws it successfully but when i click on any link it doesn't hit the event because i thought it's not possible to save the x.Click += new EventHandler(TaskC); in the session ,so i want to know how to loop through my session content to resetting the delegate of my link ?
That idea won't work because if you're not wiring up the Event Handler every time the page is loaded, it won't run.
If we come back to the original issue, you said it's slow. Creating controls at runtime cannot be slow and it's most likely the way you create your list of items:
List<TaskDTO> List = TaskList.DrawMenu(int.Parse(Session["emp"].ToString()));
Instead of storing complete menu, try to store in the Session only List and create all controls as usual. If menu is required on one page only, then use ViewState instead of Session.
Also it makes sense to change the entire code as currently you hardcode all style and layout settings in the code. Create all layout (div, ul, li) in aspx, move all styles in css (for example, you use "task" class but still set "tahoma" in the code). This would simplify the code and bring more flexibility.
List<TaskDTO> List = null;
void Page_Load(object sender, EventArgs e)
{
if (ViewState["List"] != null) {
List = (List<TaskDTO>)ViewState["List"];
} else {
// ArrayList isn't in view state, so we need to load it from scratch.
List = TaskList.DrawMenu(int.Parse(Session["emp"].ToString()));
}
// Code to create menu, e.g.
if (!Page.IsPosBack) {
Repeater1.DataSource = List;
Repeater1.DataBind();
}
}
void Page_PreRender(object sender, EventArgs e)
{
// Save PageArrayList before the page is rendered.
ViewState.Add("List", List);
}
...
<ul id="orderedList">
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<li><%# Eval("TaskName") %></li>
</ItemTemplate>
</asp:Repeater>
</ul>
Maybe save it in application level so it only gets built once, then just put the menu into an object and loop through it to re-add the clicks.
I'm afraid that in order for it to work you are going to have to rebind the Click handler on every Page_Load.
Based on your code, and assuming your TaskC is available, you can make this method:
private void RebindMenuHandlers() {
if(Session["SideMenu"] == null)
return; // Your menu has not been built yet
var menu = ((System.Web.UI.Control)(Session["SideMenu"]));
var orderedList = menu.Controls[0];
foreach(var listItem in orderedList){
foreach(var control in listItem){
var linkButton = control as LinkButton;
if(linkButton != null){
linkButton.Click += new EventHandler(TaskC);
}
}
}
}
Then call it on your Page_Load event:
void Page_Load(object sender, EventArgs e)
{
RebindMenuHandlers();
// .... etc
}
I just typed this directly here, so please forgive any silly compilation mistakes, this should be enough to give you the general idea. Hope that helps.
I am trying to get the display name of an item in a droplink in the back-end C# code. I am using Sitecore 6.6, not using MVC, and am setting a droplink control in the CMS for clients called Address. The droplink source goes to /sitecore/Templates/User Defined/WAC/Address, and the individual items have an SEO-compliant name and a readable display name.
For example:
Item ID: {9E60F5F8-FBF2-4CBD-BB13-6A93397AAC87}
Name: 100-main-street
Display Name: 100 Main Street, Sample Town, 10011
My code:
protected void Page_Load(object sender, EventArgs e)
{
String sl = "";
Sitecore.Data.Items.Item currentItem = Sitecore.Context.Item;
// BEGIN main class list
Sitecore.Collections.ChildList classList = currentItem.Children;
foreach (Sitecore.Data.Items.Item mainPage in classList)
{
if (mainPage.TemplateID.ToString() == "{27A9692F-AE94-4507-8714-5BBBE1DB88FC}")
{
sl += "<span class=\"address\">" + mainPage.Fields["Address"] +"</span>";
}
else
{
}
}
// END main class list
classSessionList.Text = sl;
}
This code will give me the ID of the Item. If I use mainPage.Fields["Address"].DisplayName, I get "Address".
How can I get the Display Name of the item from the droplink?
Use LookupField for getting reference item below are the sample code:
LookupField address= (LookupField)mainPage.Fields["Address"];
Item addressItem = address.TargetItem;
string displayName = addressItem.Fields["DisplayName"].Value;
If you want it in one line then use below code:
((LookupField)mainPage.Fields["Address"]).TargetItem.DisplayName
Type cast the field to a ReferenceField. Then access the TargetItem property:
sl += "<span class=\"address\">" + ((ReferenceField)mainPage.Fields["Address"]).TargetItem.DisplayName +"</span>";
The thomas answer would work based on your code. But I would suggest you also to try to stick with ASP.Net and Sitecore server components.
That will avoid Null Reference errors, will support Page Editor better and also makes your code easier to maintain.
You can have a repeater in your markup like this:
<asp:Repeater ID="rptAdresses" runat="server">
<ItemTemplate>
<span class="address">
<sc:Text id="scAddress" runat="server" Field="__Display Name" Item="<%#(Sitecore.Data.Items.Item)Container.DataItem%>"></sc:Text>
</span>
</ItemTemplate>
</asp:Repeater>
And then bind the address on your code behind:
private void BindRepeater()
{
if (mainPage.TemplateID.ToString() != "{27A9692F-AE94-4507-8714-5BBBE1DB88FC}")
{
rptAdresses.Visible = false;
}
else
{
rptAdresses.DataSource = Sitecore.Context.Item.GetChildren();
rptAdresses.DataBind();
}
}
Another point that I notice was the line mainPage.TemplateID.ToString() != "{27A9692F-AE94-4507-8714-5BBBE1DB88FC}". That is a point that you also could improve. Hard coded IDs are not a good pratice. You could create a class to hold those things or, even better, you could think more about your design to avoid it.
cheers
All other solutions are perfect, but you can also use the code below:
var itemID=mainPage.Fields["Address"].value;
Item targetItem=Sitecore.Context.Database.GetItem(itemID);
if (mainPage.TemplateID.ToString() == "{27A9692F-AE94-4507-8714-5BBBE1DB88FC}")
{
sl += "<span class=\"address\">" + targetItem.DisplayName +"</span>";
}
else
{
}
With this approach you can use every field of target item.
I am working on asp.net c# . I am trying to find the header control in c# . But I am getting object not set to an instance of an object . My code is
public void R1_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Header)
{
HtmlGenericControl ulSubNav2 = (HtmlGenericControl)e.Item.FindControl("da-sliders");
ulSubNav2.Style.Add("background", "transparent url('DesktopModules/DNAiusParallelSlider/Images/waves.gif') repeat 0% 0%");
ulSubNav2.Style.Add("width", "100%");
ulSubNav2.Style.Add("height", "400px");
}
}
relevant HTML Code
<HeaderTemplate>
<div id="da-sliders" class="da-slider" OnItemDataBound="R1_ItemDataBound">
</HeaderTemplate>
this is because the system failed to find the control with the name you specified.
Try to add a "runat" tag to the div like this :
<div id="da-sliders" class="da-slider" OnItemDataBound="R1_ItemDataBound" **runat="server"**>
Now in your ItemDataBound you have access to the div item in the HeaderTemplate.