Custom SharePoint Navigation 2 Levels Deep - asp.net

I have a simple site consisting of a root site with 2 child sites.
Now I want the navigation for all 3 sites to be exactly the same and read:
Root Site | Child Site 1 | Child Site 2
With the currently selected site highlighted.
I have been able to nearly do this manually using an asp:repeater control and portalsitemapprovider. The problem is I can either get just the Root Site on the navigation (set ShowStartingNode to True) or just the child sites, I can't get both.
I know you can get both if you use a sharepoint:aspmenu control and set staticdisplaylevels to 2 but I don't like the messy code this control spits out. Basically i want to emulate this controls behaviour wrapped in my own compliant css. Any ideas?
Also as an addition does anyone have any ideas on how I can have it so if subsite1/2 have subsequent subsites/pages, it doesn't matter how many levels deep in the hierarchy a user is navigating, it still highlights the relevant subsite1 or subsite2? My current method compares currentnode with each of the providers nodes to work out which should be highlighted, but this doesn't work once the user has navigated away from the landing page of each subsite.
Thanks!

I think you have to start at the root and render that node in a first repeater and then use the childnodes of the root as a datasource for a second repeater, something like:
<asp:Repeater runat="server" ID="MenuRepeater"
DataSourceID="MainNavigationDataSource">
<HeaderTemplate>
// code here
</HeaderTemplate>
<ItemTemplate>
// code here
<asp:Repeater runat="server" ID="ChildMenuRepeater"
DataSource='<%# ((SiteMapNode)Container.DataItem).ChildNodes %>'>
<HeaderTemplate>
// code here
</HeaderTemplate>
<ItemTemplate>
// code here
</ItemTemplate>
</ItemTemplate>
For your second question, I think (if I understand it correctly) that you could use SiteMapNode.IsDescendantOf() method but I somehow recall that that will not work in SharePoint so I have used this sort of code to check if a node is the "active" node:
string CurrentContextUrl = SPUtility.GetPageUrlPath(HttpContext.Current);
Uri CurrentUri = new Uri(CurrentContextUrl);
bool Active = CurrentUri.LocalPath.Equals(currentNode.Url);
Hope it helps out somehow :-)

Related

bootstrap metismenu populated by datasource in asp.net

I want to create a "Tree" structured menu that is generated by a datasource.
I know how to do that with an asp.net tree view or a gridview.
However recently I have grown to love bootstrap and I just love the bootstrap mantis menu.
However metismenu only seem to work on lists 'li'. Then this became a problem for me as the list I want to generate is not static is dynamic. So I can't really bind the value one by one I need to have some other way of doing this.
Can anyone give me some ideas on how to achieve this in asp.net webforms?
PS: would a repeater work for this scenario?
You could use a repeater or a listview or pretty much anything that gives you control of the output html...
You have not presented a massive amount of information to go on but I suspect that you have at least some data that contains a text value and a URL.
private void BindMenuData()
{
var menuData = DataLayer.GetMenuStructure();
rptMenu.DataSource = menuData;
rptMenu.DataBind();
}
Then in your HTML/ASPX you will have something like
<asp:Repeater id="rptMenu" runat="Server">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<a href='<# Eval("URL")>'><# Eval("LinkText")></a>
</li>
</ItemTempate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
If you then needed sub menus you would need to nest another repeater inside the item template and bind to it in the repeater itemDataBinding/Databound (Cant remember which) event.
The sub menus leads to an extra layer of complexity which could quite easily descend into a mess of spaghetti code so take some time to think it through!
Of course the fall back could always be a method which uses a string builder to generate the HTML for the menu and spit it out to literal.... Not the best option in my opinion though!

Assign separate link to each repeater item in ASP .net

I was trying to develop a forum website (trying to mimic some of its features) and I am using Entity framework to get my data. I have to use repeater as my instructor asked me to do so.
I would be having something like this using repeater that gets data for "Forum Category" and "Sub-category" from 2 separate database tables:
Forum Category 1
Sub-Category 1
Sub-Category 2
Forum Category 2
Sub-Category 1
Sub-Category 2
Now, I would like, when clicked on those sub-category list to be directed to the page of their own using query string and that is what I am not being able to figure out at this time. When I assign a link to those sub-lists, since they are automatically generated all of them point to the page that I initially assign. I was wondering if there was someway to dynamically assign links for this scenario. I was thinking of using ENUM, but again how do I run a for loop there.
The code I have for the repeater is below:
<asp:Repeater ID="categoryRepeater" runat="server" OnItemDataBound="RepeaterDataBinding">
<ItemTemplate>
<asp:Label ID="categoryLabel" Text='<%#Eval("CatName") %>' runat ="server"
style="font-weight:bold;font-size:large" />
<br />
<asp:Repeater ID="forumRepeater" runat="server">
<ItemTemplate>
<%#Eval("ForumName")%><br/>
<%-- right up there. Instead of hardcoding "DesktopForum1.aspx?ForumID=" which makes all the links
to point to that page, I am trying to achieve a way to assign links to specific pages for each sub-list...
--%>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
I did try searching the forum, but could not come across with a problem that resembled my situation.
If you're able to get the sub-list page URL with the query that populates forumRepeater, this should work:
<a href='<%#Eval("ForumUrl")%>'><%#Eval("ForumName")%></a><br/>
Would you like to put some acnchor for each item?
It will look like that:
<a name="someAnchor"></a>
and Link will be as follows: www.mywebsite.com/blog/posts#someAnchor
For more details: http://www.echoecho.com/htmllinks08.htm
If it is still not good, you need to handle and process querystring values with Javascript

Which data control would be apt for the scenario?

Guys i have a job to display the list of subscribers as it is given in the image. I would like to know which data control in ASP.NET would be perfect for this scenario. I am just playing with Listview but i would like get inputs from the folks here. Thank You. Faraaz.
Update1: Should i use list of gridviews (nested inside a listview) here? Or can it be done with a single list view?
Obviously, grid-view would give you desired tabular layout (probably with the minimal efforts with Auto Generated Columns).
However, if paging, sorting, editing are note required then I would rather user Repeater control. The main reason being precise control over the mark-up. For example, grid-view does not support elements such as <colgroup> or <thead> (again, these elements may not be needed for your layout). If paging/sorting/editing etc is needed then ListView is better choice.
As far as, showing multiple tables goes, you can use nested controls - for example, repeater/list-view nesting a grid-view.
EDIT:
You are not very clear about the structure of data that you have and also about the exact layout that you want. So here's what I am assuming - you have a single List<Subscriber> containing both root subscribers and their children. And in the layout, you want one table for root subscribers followed by multiple tables - one for each root subscriber's children.
Mark-up will be something like
<asp:Repeater runat="server" ID="Outer" >
<HeaderTemplate>
<%-- Put a grid here for parent -->
<asp:GridView runat="server" ID="Root" DataSource='<%# GetRootSubscribers() %>' >
... column def etc
</asp:GridView>
</HeaderTemplate>
<ItemTemplate>
<!-- Put a grid here for children for current root subsriber -->
<asp:GridView runat="server" ID="Child" DataSource='<%# GetChildSubscribers(Eval("MemberID")) %>' >
... column def etc
</asp:GridView>
</ItemTemplate>
</asp:Repeater>
This will be supported by two code-behind methods such as
protected IEnumerable<Subscriber> GetRootSubscribers()
{
// I am not sure how you decide if a subscriber is a parent or not, I have just
// illustrated a condition where you have a parent id field to indicate the same
return allSubscribers.Where(s => s.ParentID == null);
}
protected IEnumerable<Subscriber> GetChildSubscribers(object memberId)
{
// I am not sure how you decide a child subscriber, I have just
// illustrated a condition where you have a parent id field to indicate the same
return allSubscribers.Where(s => s.ParentID.Equals(memberId));
}
// bind the outer repeater to root list
Outer.DataSource = GetRootSubscribers();
Outer.DataBind();
Hope this will give you some idea about how to proceed.
to me this is a GridView with usual header texts. The first bar above you can make with any other control or pure HTML right before the grid. ListViews are not grids and in my opinion should not be used when the final expected result is closer to a grid

Binding Label to SiteMap Current Node

What I want to do is something like this:
<asp:Label ID="titleLabel" runat="server"
**Text='<%# SiteMap.CurrentNode.Title %>'**></asp:Label>
Where I can bind the name of the current page node in the Site Map to the title label on that page. We are doing this because, until we get these names finalized, they may change often. The above code does not work, at least for me; it displays nothing.
Any ideas are appreciated.
EDIT: Obviously I could do this in the code behind (i.e. Page Load event or something similar) but I would really rather do it in the aspx code.
It does work with
<span><%= SiteMap.CurrentNode.Title %></span>
which is the same output as asp:Label
As an alternative to using a label, you could also use the SiteMapPath control and hide the parent nodes:
<asp:SiteMapPath ID="SiteMapPath1" runat="server" ParentLevelsDisplayed="0">
The property ParentLevelsDisplayed allows you to specify how many parent nodes of the current sitemap node you want to display.
Its been a while but I believe its <%= #Eval(SiteMap.CurrentNode.Title) %>
Edit:
Text='<%= SiteMap.CurrentNode.Title%>'
Hopefully that works the same as it would <%= SiteMap.CurrentNode.Title%>.

Trying to self contain pop ups which use the AjaxToolkit ModalPopUpExtender

I have 3 different kinds of ajax popups that need to exist across my site. I was hoping that I could simply create a user control for each one and place the panel and modal popup extender inside each one but this doesn't seem to be working. Has anyone tried this before or do you have a recommendation as to how I can avoid duplicate code for each pop up on different pages? Thanks!
Ah I figured out my issue with the User Control I believe.
The ModalPopUpExtender requires the TargetID property to be set otherwise an error occurs. Since this is sitting in a UserControl I just created a dummy link button that doesn't do anything and I set the property visible to false.
<asp:LinkButton ID="lnkBlank" runat="server" Visible="false" />
<asp:Panel ID="plContainer" style="display: none;" runat="server">
Hello?
</asp:Panel>
<cc1:ModalPopupExtender ID="mpe" runat="server"
BehaviorID="test"
TargetControlID="lnkBlank"
PopupControlID="plContainer" />
Apparently it doesn't appreciate that and the moment I set the visible property to true it started working. Not sure what the reasoning is for a TargetID since, I would think, most pop ups could be called from multiple links about the page. Perhaps I'm still not entirely clear on how this control is supposed to be used.
One option would be to write the popups in a asp.net user control (a .ascx page) and include that on the pages you need the popups. Have a public method in the ascx page that will show the popup, and call it from the parent page when you need to. If you already have a script manager on the parent page, you can't have a second one in the ascx page, but other then that there shouldn't be anything that would stop this from working. Hope this helps!
edit: here's what my modal popup extender control looks like...
<cc1:ModalPopupExtender
ID="mpeClassroom"
BackgroundCssCLass="modalBackground"
runat="server"
CancelControlID="lbClose"
OnOkScript="onOk()"
TargetControlID="Button1"
PopupControlID="pnlClassroom">
</cc1:ModalPopupExtender>
in my code behind page, my method just calls mpeClassroom.Show();
The problem with hidden link as TrgetControlID is that; when u set its visibility as false, server doesn't render it as well. PopExtender then cannot find control on the page.
Instead of setting its visibility to false, try to apply a style with display:none. This should work !

Resources