Adding different CSS classes when using the EPiServer PageTree control
Another little quick tip. I was browsing the EPiServer World forum and came across a common question.
by David Green
I am using the EpiServer:PageTree control to generate a nested <ul><li> list in the format below.
However I am also using a dropdown menu system called UDM which requires that the class and id “udm” are on the first <ul> tag.
The container object of the PageTree controller exposes the Indent property that we can use for this. Below is a simple example of how to add a CSS class to the first ul in your list (code is based on SubMenu.ascx from the EPiServer Public Templates package).
<%@ Control Language="C#" EnableViewState="false" AutoEventWireup="False" CodeBehind="SubMenu.ascx.cs" Inherits="EPiServer.Templates.Public.Units.Static.SubMenu" %> <EPiServer:PageTree ShowRootPage="false" runat="server" id="Menu"> <IndentTemplate> <ul <%# AddCssClassToFirstLevel(Container.Indent, "udm") %>> </IndentTemplate> <ItemHeaderTemplate> <li> </ItemHeaderTemplate> <ItemTemplate> <EPiServer:Property PropertyName="PageLink" runat="server" /> </ItemTemplate> <SelectedItemTemplate> <EPiServer:Property CssClass="selected" PropertyName="PageName" runat="server" /> </SelectedItemTemplate> <ItemFooterTemplate> </li> </ItemFooterTemplate> <UnindentTemplate> </ul> </UnindentTemplate> </EPiServer:PageTree>
using System; using EPiServer; using EPiServer.Web.WebControls; namespace EPiServer.Templates.Public.Units.Static { public partial class SubMenu : UserControlBase { private MenuList _menuList; /// <summary> /// Gets or sets the data source for this control /// </summary> public MenuList MenuList { get { return _menuList; } set { _menuList = value; } } protected override void OnLoad(System.EventArgs e) { base.OnLoad(e); if (MenuList == null) { return; } Menu.PageLink = MenuList.OpenTopPage; Menu.DataBind(); } protected string AddCssClassToFirstLevel(int level, string cssClassName) { if (level == 1) { return string.Format("class=\"{0}\"", cssClassName); } return string.Empty; } } }
We can easily add more complex logic. We also have access to the HasChildren property, which tells us if the active page has any children.
Hope this helps.
Hi Frederik
Thank you very much for your blog post. It has worked perfectly.
The Container.Indent value in the IndentTemplate is very useful.
Regards
David Green
Nicely done. Very, very handy.
Hi Frederik – Excellent again
Container.Indent works nicely for nested levelled navigation – but any suggestions if you wanted to change the style using a similar method within the ItemTemplate to change the style on the first and last items?
My guessed approach would be something like this (pseudo code)
[Code Behind]
if (Container.Position == 1 || Container.Position == Container.MaxCount) { …code here to return different class information for css }
Hi Alex
Could you post the markup you’re going for?
Frederik
Hi Frederik
Very proudly solved it on my own
Here’s the code used, and basically I expose the ‘PagePeerOrder’ property from the CurrentPage (the one that you can set in the EPiSERVER Editor tool in the Advanced tab for the page), and use this to check whether the page is my first page (PagePeerOrder set to 100 the same as EPiSERVER does with the first page by default) or my last page (with PagePeerOrder set to 999 so that it will always be the last page).
<li >
///
/// Adds first and last classes to the list items
///
///
/// Returns the css class in XHTML tag format
///
/// Current level of navigation passed in using the Container.Index value
/// The EPiSERVER Advanced Sort Index of the page
protected string AddCssClassToPrimaryNavigationLi(int level, string sortIndex)
{
int mySortIndex;
string myReturnValue;
if (int.TryParse(sortIndex, out mySortIndex))
{
switch (mySortIndex)
{
case 100:
return string.Format(“class=\”first\”");
break;
case 999:
return string.Format(“class=\”last\”");
break;
default:
myReturnValue = string.Empty;
break;
}
}
else
{
myReturnValue = string.Empty;
}
return myReturnValue;
}
… I’m sure there might be a nicer way to do it, but this works so should hopefully be a good reference for anyone else following Frederik’s great posts and my less great comments on them
Alex
Code was eaten by the page above so let’s try posting the .aspx code again in a pre tag
.aspx code
<li >.aspx.cs code
/// /// Adds first and last classes to the list items /// /// /// Returns the css class in XHTML tag format /// /// Current level of navigation passed in using the Container.Index value /// The EPiSERVER Advanced Sort Index of the page protected string AddCssClassToPrimaryNavigationLi(int level, string sortIndex) { int mySortIndex; string myReturnValue; if (int.TryParse(sortIndex, out mySortIndex)) { switch (mySortIndex) { case 100: return string.Format("class=\"first\""); break; case 999: return string.Format("class=\"last\""); break; default: myReturnValue = string.Empty; break; } } else { myReturnValue = string.Empty; } return myReturnValue; }Sorry Frederik – messing up your blog! – here it is without the ‘less than, percent, hash’ opening tag and ‘percent, greater than’ end tags
.aspx front code
Hi, i just discovered your blog, thanks for your post. I found it really interesting.