ASP.NET AJAX accordion control is a wonderful control made of collapsible panels with an animation effect. Accordion control is mostly used for long content pages with various collapsible sections. The control can also be used as a site menu, collapsible panels gives a very good effect when accordion is used as a site menu.
In ASP.NET any menu control needs to be attached to the web.sitemap file to display the site navigation. Although accordion control does not provide this facility by default as the ASP.NET TreeView control (Accordion cannot be directly binded to SiteMapDataSource object as TreeView) but it is fairly simple to achieve that.
You need to drop a SiteMapDataSource object on the page and then bind the accordion control with the SiteMapNodeCollection instead of SiteMapDataSource. Get the SiteMapNodeCollection from SiteMapDataSource as follows and bind to the accordion control.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim siteMapView As SiteMapDataSourceView = CType(SiteMapDataSource1.GetView(String.Empty), SiteMapDataSourceView)
Dim nodes As SiteMapNodeCollection = CType(siteMapView.Select(DataSourceSelectArguments.Empty), SiteMapNodeCollection)
Accordion1.DataSource = SiteMapNodeCollection
Accordion1.DataBind()
End If
End Sub
In the aspx page add a repeater control in the <contenttemplate> of the accordion control to show the child items in the collapsible panel. The header of the accordion will show the first level nodes from the sitemap and the collapsible panel will show the child nodes of the header item.
<cc1:Accordion ID=”Accordion1″ runat=”server” SelectedIndex=”0″ FadeTransitions=”false”
FramesPerSecond=”40″ TransitionDuration=”250″ AutoSize=”None” RequireOpenedPane=”true”
SuppressHeaderPostbacks=”true” HeaderCssClass=”AccordionHeaderCssClass”>
<HeaderTemplate>
<a class=”AccordionSideBarLink” href='<%# Eval(“url”) %>’>
<%# Eval(“title”) %>
</a>
</HeaderTemplate>
<ContentTemplate>
<table>
<asp:Repeater ID=”Repeater1″ runat=”server”>
<ItemTemplate>
<tr>
<td id=”AccordionSideBarItem”>
<a class=”AccordionSideBarItemLink” href=”<%# CType(Container.DataItem, System.Web.SiteMapNode).Url %>”>
<%#CType(Container.DataItem, System.Web.SiteMapNode).Title%>
</a>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
</ContentTemplate>
</cc1:Accordion>
In order to bind the repeater control with the child nodes, add the following code in the Accordion DataBound control.
Protected Sub Accordion1_DataBound(ByVal sender As Object, ByVal e As AjaxControlToolkit.AccordionItemEventArgs) Handles Accordion1.ItemDataBound
If CType(e, AjaxControlToolkit.AccordionItemEventArgs).ItemType = AjaxControlToolkit.AccordionItemType.Content Then
Dim cPanel As AjaxControlToolkit.AccordionContentPanel = e.AccordionItem
Dim rptr As System.Web.UI.WebControls.Repeater = CType(cPanel.Controls(1), System.Web.UI.WebControls.Repeater)Dim sNode As System.Web.SiteMapNode = CType(CType(e, AjaxControlToolkit.AccordionItemEventArgs).AccordionItem.DataItem, System.Web.SiteMapNode)
Dim childNodes As System.Web.SiteMapNodeCollection = sNode.ChildNodes
If Not childNodes Is Nothing AndAlso childNodes.Count > 0 Then
rptr.DataSourceID = Nothing
rptr.DataSource = childNodes
rptr.DataBind()
End If
End If
End Sub
and this is how my web.sitemap is arranged.
<?xml version=”1.0″ encoding=”utf-8″ ?>
<siteMap xmlns=”http://schemas.microsoft.com/AspNet/SiteMap-File-1.0″ enableLocalization=”true”>
<siteMapNode url=”~/Login/Main.aspx” title=”$resources: SiteMap, ServicesHome” description=”” ImageUrl=”~/App_Themes/Standard/Images/ServicesHome_Small.gif” >
.
.
.
<siteMapNode url=”” title=”$resources: SiteMap, Licenses” description=”” ImageUrl=”~/App_Themes/Standard/Images/Licenses_Small.gif” EntityName=”LicenseBox” >
<siteMapNode url=”javascript:openWindow(‘../License/License.aspx?mode=new’,950,600,’License’)” title=”$resources: SiteMap, NewLicense” description=”” EntityName=”License” AccessType=”new”/>
<siteMapNode url=”javascript:openWindow(‘../LicenseRenewal/LicenseRenewal.aspx?mode=new’,950,600,’LicenseRenewal’)” title=”$resources: SiteMap, RenewLicense” description=”” EntityName=”LicenseRenewal” AccessType=”new”/>
<siteMapNode url=”javascript:openWindow(‘../LicenseCancel/LicenseCancel.aspx’,950,600,’LicenseCancel’)” title=”$resources: SiteMap, CancelLicense” description=”” EntityName=”LicenseCancel” AccessType=”new”/>
<siteMapNode url=”javascript:openWindow(‘../LicenseAmmendment/LicenseAmmendment.aspx’,950,600,’LicenseAmmendment’)” title=”$resources: SiteMap, AmmendLicense” description=”” EntityName=”LicenseAmmendment” AccessType=”new”/>
<siteMapNode url=”~/License/LicenseListing.aspx” title=”$resources: SiteMap, ExistingLicenses” description=”” EntityName=”LicenseListing”/>
<siteMapNode url=”javascript:openWindow(‘../Documents/Licensing Department Conditions.pdf’,950,600,’LicenseHelp’)” title=”$resources: SiteMap, LicenseHelp” description=”” EntityName=”Help” />
</siteMapNode>
.
.
.
</siteMapNode>
</siteMap>
Hi, It looks like a nice article however I have copy your sample code and I got several different errors. Your code is incomplete and therefore does not work. When you write an article, please make sure the code you post with is all there and you have tested that. Thanks
you get error because aleem is a dumb goat humping sob dumbshit
Hi Sonia,
Can you please let me know what problem you are having so I can rectify if there is any problem with the code. I cannot paste the entire project, I have just posted the portions of the code which I believe would be enough for understanding what is being done here.
Let me know if you need a sample project or full code.
Hi Aleem, thanks for your fast response. I have converted the code into C#: Here is the code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SiteMapDataSourceView siteMapView = (SiteMapDataSourceView)SiteMapDataSource1.GetView(string.Empty);
SiteMapNodeCollection nodes = ((SiteMapNodeCollection) (siteMapView.Select(DataSourceSelectArguments.Empty)));
Accordion1.DataSource = nodes;
Accordion1.DataBind();
}
}
protected void Accordion1_DataBound(object sender, AjaxControlToolkit.AccordionItemEventArgs e)
{
if (((AjaxControlToolkit.AccordionItemEventArgs)e).ItemType == AjaxControlToolkit.AccordionItemType.Content) {
AjaxControlToolkit.AccordionContentPanel cPanel = e.AccordionItem;
System.Web.UI.WebControls.Repeater rptr = (System.Web.UI.WebControls.Repeater)cPanel.Controls(1);
System.Web.SiteMapNode sNode = (System.Web.SiteMapNode)((AjaxControlToolkit.AccordionItemEventArgs)e).AccordionItem.DataItem;
System.Web.SiteMapNodeCollection childNodes = sNode.ChildNodes;
if ((childNodes != null) && childNodes.Count > 0)
{
rptr.DataSourceID = null;
rptr.DataSource = childNodes;
rptr.DataBind();
}
}
}
Error: The name ‘SiteMapDataSource1’ does not exist in the current context
If I add a sitemapdatasource tag in the html then i will start getting other errors such as System.Configuration.ConfigurationErrorsException: Resource key cannot be empty.
Appreciated that you replied so fast thanks. As I said the article looks nice :). By the way, you may want to take a look at this control: http://www.metabuilders.com/Tools/MultiViewBar.aspx Another interesting menu.
It is sort of given that you will need a SiteMapDataSource and I have also mentioned in the post that you need to drop one on the page.
The error “Resource Key cannot be empty” seems to be in your web.sitemap file. If you are using my sitemap file it may not work as it is using resource keys which you will not have, it was supposed to help you understand the arrangements sitemap file only.
Create a simple web.sitemap file only following the hierarchy provided in the sample and then check.
I hope it will work.
hi aleem,
am new to asp.net
i need to know whether we can use gridview inside accordion?
my problem is..accordion is connected with one datasource..am displaying som values in header template with that datasource..
in content template i kept one gridview…i need to connect sqldatasource to that gridview..am cant able to connect.Gridview is not displaying?
do you knw any other method to solve this?
kindly send me some sample code..using C#
Hi Aleem,
Thanks for the article.
I was doing something similar except for the child using OnItemDataBound. It works fine ! My only concern is with items that has been shown even for user with no permission.
The child nodes which the user has no permission to see are been shown accordingly (Repeater inside), but for the nodes displayed on HeaderTemplate, all nodes are appearing which is very weird.
Any idea what must be causing it?
Thanks.
Would it be possible to put together a zipped Visual Studio 2005 file containing a vb.net solution for this code?
If users would like to see a working sample in C# you can find it here:
http://blog.lavablast.com/post/2007/12/Hybrid-AccordionTreeView-Sitemap.aspx
When binding to the accordion control you have:
Accordion1.DataSource = SiteMapNodeCollection
Shouldn’t this be
Accordion1.DataSource = nodes
I’m just wetting my feet with this stuff so forgive me if I’ve assumed incorrectly!
Hi Aleem,
This is nice article, i also worked in vertscape bangalore, i went through the application it was very good, but it had this control not working properly on IE7 or 6 right ?
I just wanted to know how did you fixed it? what was the problem? If you can explain us it would be very help full for us!
Thanks for the wonderful article.
It solved my problem.
Allah bless you.
Rana
Very simple solution
from Chile… thanks a lot !
Hey guyz i want to write the above source code written in VB in C# , does anyone have a clue how to do it ??
For some reason it’s not working for me. I get the links for the root nodes that should be able to be clicked to expand the child nodes however that doesn’t happen, they just replace the page and have an href=””
Just a note for C# developers, don’t forget to add the event:
MyAccordion.ItemDataBound += new EventHandler(MyAccordion_ItemDataBound);
..if you want it to run the ItemDataBound event.
Aleem, how do you get the selected index of he root node when a user clicks a childnode??
Thank you so much Aleem, this is exactly what i was looking for and works perfectly fine for me! Good Job!!!!
Pingback: The Best of Telerik ASP.NET Ajax Controls « Aleem’s Weblog
Worked perfectly! Great article!
keep it cooming man i love it
It works, but it does not show the currently visible page. This could be done in the ItemDataBound event of the repeater.
Here’s a C# sample:
protected void AccordionRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
HyperLink hl = (HyperLink)e.Item.FindControl("hlSubMenuItem");
AccordionPane ap = (AccordionPane)e.Item.Parent.Parent.Parent;
Accordion ac = (Accordion)ap.Parent;
SiteMapNode sn = (SiteMapNode)e.Item.DataItem;
hl.Text = sn.Title;
hl.NavigateUrl = sn.Url;
if (Request.Url.AbsoluteUri.ToLower().Contains(sn.Url.ToLower()))
{
hl.CssClass="SelectedItemClass";
ac.SelectedIndex = ac.Panes.IndexOf(ap);
}
}
Hello Aleem,
I try your example so to bind an Accordion Control with Sitemap..
but I get the errors:
SiteMapNodeConnection is a type and cannot be used as an expression
Name ‘SiteMapDataSource’ is not declared
Can you please help me out with that..
regards
I got the same errors when I tried to use this code.
As I web-site possessor I believe the content material here is rattling fantastic , appreciate it for your efforts. You should keep it up forever! Best of luck.
Useful information. Lucky me I found your website by chance, and I’m shocked why this twist of fate didn’t took place earlier! I bookmarked it.
I was initially browsing for techniques for my blog site and
encountered your own post, “Using ASP.NET AJAX Accordion Control with Sitemap Aleem’s Weblog”, do you mind if perhaps I really make use of some of your points? Many thanks ,Christel
Good way of telling, and fastidious post to obtain facts on the
topic of my presentation focus, which i am going to present in institution of higher education.
as usual another dumb sob post with no source code serious alleem you need to get your unit incher out the muslims goats ahole
hey rich the who has aleem stick his unit incher you fat nigger ahole you link is bogus rofl
do u ever test the crap you post
Accordion1.DataSource = SiteMapNodeCollection will not compile in vb.net you horse cocksucking shithead
here is a link of the crap rof aleem the goat humper that actually works and has full source code
http://www.aspforums.net/Threads/193567/ASPNet-AJAX-Nested-Accordion-Menu-with-Submenu-using-SiteMap/?s=2#Replies