ASP.NET Custom Navigation in Master Page - asp.net

All,
I am trying to decide the best way to convert my current asp.net page into a master page. This issue I have is with the navigation. I have 3 aspx pages which are essentially html with nothing flash in as yet. These are:
Home
Reports
Admin
In my current pages, the menu built using static html as follows:
<div id="nav">
<ul>
<li>Home</li>
<li>Reports</li>
<li>Admin
</li>
</ul>
</div>
The class for each li a class is currently determined in the actual html source. So in Default.aspx the class for li a href="Default.aspx" ... would point to the selected tab class in my css, tab-selected. The other classes for the rest of li a's would be tab-unselected.
Again in reports.aspx, the class for li a href="reports.aspx" ... would point to the selected tab class in my css, tab-selected. The other classes for the rest of li a's would be tab-unselected.
My CSS is displaying the menus perfectly with the above.
I then thought I would try moving to Master pages. So I copied the above into the master page. This looks ok but the problem is as the navigation is in the Master page, how can I change the highlight the current page in the navigation.
Then I thought I would try and use the control and put the above navigation items in it. When I ran the navigation was rendered as a table and so completely broke my css. I thought tables were bad in terms of laying out things like menus and you should use unordered lists?
Question is, what is the best way to implement my navigation with ASP.NET?
Thanks
Andez

If you want to use your html list to display your navigation but style your list items using CSS then you could use this technique.
Use inline code blocks such as (assuming VB)
<% If Page.Request.Path.Contains("Default.aspx") Then %>
<li class="selected">
<% Else %>
<li>
<%End If%>
Home</li>
You would need an IF statement for each page and the code will look a bit scrappy. I'm not saying it's the best way but basically if you are using a single piece of html for you menu (but it in the Masterpage or a Control) you will need to use some logic code somewhere for the html to be different on each page. You could do this in the code-behind as well but adding some inline code blocks is the perhaps the easiest/quickest way. You could get more funky and write a helper class that wraps it all up in a select statement and just call
MenuHelper.RenderLink("Default.aspx")
but that will take more work - give me a shout if fancy trying this approach instead.
As for why your tables broke I don't know. My opinion would be if you want to use tables and your site/users won't suffer from it then go ahead - but if you have to consider mobile devices and screen readers etc then it is my understanding that tables will be harder to navigate. It's really up to you!
Cheers

Came across the following link:
http://forums.asp.net/t/1626206.aspx
Version 4.0 of the .NET Framework has some nice changes to the asp:Menu control. One of them is to render as a list. Yay! So for now I have moved from VS2008 to VS2010 Express.
After a little fiddling around I am now using a site map with an asp:Menu within a Master page as follows:
Web.sitemap
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="" title="" description="">
<siteMapNode url="Default.aspx" title="Home" description="" />
<siteMapNode url="reports.aspx" title="Reports" description="" />
<siteMapNode url="administration.aspx" title="Administration" description="" />
<siteMapNode url="ChildPage.aspx" title="Master Template" description="" />
</siteMapNode>
</siteMap>
Site.master
...
<head runat="server">
<link rel="stylesheet" type="text/css" href="styles/mystyle.css" />
</head>
<body>
<form id="Form1" runat="server">
<div id="header">
<div id="nav">
<asp:SiteMapDataSource id="nav1" runat="server" />
<asp:Menu ID="main-menu" runat="server" DataSourceID="nav1"
Orientation="Horizontal" StaticSelectedStyle-CssClass="tab-selected"
CssClass="nav"
StaticDisplayLevels="2" IncludeStyleBlock="False" RenderingMode="List" >
</asp:Menu>
</div>
</div>
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</form>
</body>
The thing with the Site Map is that you are required to have 1 top level siteMapNode which I leave as empty. StaticDisplayLevels is set to 2 in the asp:Menu, so the list is rendered as follows:
<ul class="level1">
<li><a></a></li>
<li><a class="level2 selected" href="/Web%20Portal/Default.aspx">Home</a></li>
<li><a class="level2" href="/Web%20Portal/reports.aspx">Reports</a></li>
<li><a class="level2" href="/Web%20Portal/administration.aspx">Administration</a></li>
<li><a class="level2" href="/Web%20Portal/ChildPage.aspx">Master Template</a></li>
</ul>
As you can see it puts the top level siteMapNode as the first item in the list. Which I do not want. To work around this I hide the element using the following CSS.
#nav li:first-child a
{
display: none;
}
Everything is now looking nice and very similar to the static html pages.
Andez

May be the solution I am trying to provide is not optimized but worked for me.
In the static HTML Menu in the Master page, have all the "li" tag with the ID as of the Page Name.
<ul>
<li ID="home"><a href="home.aspx">Home</li>
<li ID="About"><a href="about.aspx">About</li>
<ul>
Then in the Master Page use JQuery to get the Page Name. Some thing like
$(function () {
var filePath = window.location.pathname;
var fileName = filePath.substr(filePath.lastIndexOf("/") + 1);
var name = fileName.split('.');
var page_name = name[0];
$('#' + page_name).addClass("active"); // Add the CSS class which sets the active Menu
});
In CSS do something like
.active
{
background=#000;
color=#fff;
}
I hope this helps..

Related

How to make jQuery rendered content editable in Sitecore experience editor

We have a Sitecore project and the code/files are from an ASP.NET web application.
The HTML for the products section is as follows
<div class="products-section">
<ul class="tabs">
<li>Product 1</li>
<li>Product 2</li>
</ul>
<div class="product">
<h3>Product Name</h3>
<img src="/images/img1.jpg" />
<span>Description</span>
</div>
</div>
This is how it works for an end user.
EU will click on a Product tab (eg: Product 1), which will change the content inside <div class="product">, without postback.
For the author, this section must be editable from the Experience editor. Usually, I would use asp:Repeater with sc:Text,sc:Image to render it.
But, here the data has to be retrieved using ajax calls, which means no Repeater or Sitecore controls.
In such case, how can I make the content editable from Experience editor.
The only ideas I came up with:
Get data of all the products in Page_Load, bind it using Repeater and then use jQuery to Show/Hide the respective divs. (doesn't seem a nice way though)
Tell the content author, that this section can only be edited from Content editor and not from the experience editor :)
What are my options here.
One option could be to render your page differently when in the experience editor. Check the mode in your code and use a repeater when editing, otherwise use the jquery output.
You can use Views to easily display/hide the output you want.
<asp:MultiView runat="server" ID="ProductsView">
<asp:View runat="server" ID="StandardView">
<div ...>
...
</div>
</asp:View>
<asp:View runat="server" ID="EditorView">
<asp:Repeater..>
...
</asp:Repeater>
</asp:View>
</asp:MultiView>
In your code behind:
ProductsView.SetActiveView((Sitecore.Context.PageMode.IsExperienceEditor || Sitecore.Context.PageMode.IsExperienceEditorEditing) ? EditorView : StandardView)
Based on the active view, you can decide to attach data to the repeater or not (don't do that when the StandardView is active, for performance)
I'm not sure why would an end user interact with Experience Editor as Experience editor is used by Content Authors for authoring the site and updating the content on the Page itself.
But if this is a requirement for a Content Author you can use the sitecore services client api for updating the content using ajax call.
Use this document to see how ssc works.
Let me know if you have a different ask.

Empty asp:BulletedList doesn't show up in html

I'm trying to add an empty asp:BulletedList to a page so I can run a jquery on it. But when I open the page the bulletlist doesn't show up.
Is there a trick to getting an empty asp:BulletedList to show up?
Empty BulletedList like this:
<asp:BulletedList ID="BulletedList1" runat="server">
</asp:BulletedList>
will not render into page HTML at all because it makes no sense much as <UL> element without <LI> elements.
But if you add at least one (even empty) list item:
<asp:BulletedList ID="BulletedList1" runat="server">
<asp:ListItem></asp:ListItem>
</asp:BulletedList>
It will render as
<ul id="BulletedList1">
<li></li>
</ul>

jquery Mobile aand Asp.net Button click event not firing and redirecting to back url

I have follwing code
<div class="main" data-role="content">
<div class="choice_list menuwrapper" >
<ul data-role="listview" data-inset="true">
<li><a href="CreateUser.aspx" data-transition="slidedown" >
Create User
</a></li>
<li><a href="WebForm1.aspx" data-transition="slidedown">
Manage User
</a></li>
<li><a href="Default.aspx" data-transition="slidedown">
Upload File
</a></li>
</ul>
</div>
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>`
but when i try to click any button on createuser or other page the button_click event is not firing in asp.net and the page redirects to default.aspx,
I found when gooogled that using
$(document).bind("mobileinit", function () {
// jQuery Mobile's Ajax navigation does not work in all cases (e.g.,
// when navigating from a mobile to a non-mobile page), especially when going back, hence disabling it.
$.mobile.ajaxEnabled = false;
$.mobile.ajaxLinksEnabled = false;
});
it will solve, but no luck in my case,
Could somebosy please help me.
Thanks
I had a similar issue with a rather large mobile project. We also ran into other bugs when using .NET masterpages with jQuery Mobile. We ended up not using a masterpage in the end because there were just too many issues.
Try adding data-ajax="false" in all of your links. That should be what the code you posted is doing, but it might not be working depending on the version of JQM you're using.

how to trigger asp.net multiview?

I'm still getting my head around asp.net.
I followed some online examples of using multiviews and got them working just fine when I use something like a Menu class as the trigger to select the active view. Having the onClick event makes it pretty easy.
But I can't figure out how to change the emmited code from the Menu control.
I have the following multiview control...
<asp:View ID="0" runat="server">
<p>view page 1</p>
</asp:View>
<asp:View ID="1" runat="server">
<p>view page 2</p>
</asp:View>
And I need to have the following structure used to trigger the views.
(Note: this needs to be what gets emitted to the browser. Not necessarily the literal code in the aspx page)
<a class="button large-plain" href="" >
<span>
See page 1
</span>
</a>
<a class="button large-plain" href="" >
<span>
See page 2
</span>
</a>
For clarification: we have a style sheet provided by an exteranl designer that works with the above markup. If I could just make the triggers asp button controls, or a menu control, it would be easy. But the style sheet doesn't work then, and I'm told the world will end if the style sheet doesn't work.
Can I customise a Menu control so that it outputs this kind of structure? (And if so, how?)
I could just hard code the links that trigger the views (the structure is not going to change). But if I hardcode it, how do I call the onClick event what the links are clicked?
I think you might be able to try the following to change the tags into server-side controls and then use that as the trigger. Adding ID and runat="server" to any html element means that you can then access them programmatically as you would any other .NET style control. Additionally if you're using .NET 4.0 you can also add the ClientIdMode="Static" attribute so that the ID's are as you typed and not modified by ASP.NET.
To solve the Click problem you can add the OnServerClick="" attribute to specify which method to call on the server when the link is clicked.
<a class="button large-plain" href="" ID="ViewPage1" runat="server" OnServerClick="ViewPage1_Click">
<span>
See page 1
</span>
</a>
<a class="button large-plain" href="" ID="ViewPage2" runat="server" OnServerClick="ViewPage2_Click">
<span>
See page 2
</span>
</a>

How to avoid Adding runat="server" destroying my server tags <%...%>

Adding runat="server" is not rendering my server tags <%...%>
I have a masterpage with a few <li> for menu and since I have to set class=selected for the current page, I am using a little server tag to find the url and assign the particular class.
I have total of 10 <li> and not all menu is available to all types of user, I need to toggle few of the <li> if the user is not admin, so I have runat="server" added to them so I can set their visible=false through c#
Here is how it is at a glance:
<li runat="server" id="liBlog" class='<%= Request.Url.AbsoluteUri.EndsWith("/Blog") ? "selected" : "" %>'>Group Blog</li>
<li runat="server" id="liPoll" class='<%= Request.Url.AbsoluteUri.EndsWith("/Poll") ? "selected" : "" %>'>Poll</li>
<li id="liInvite" class='<%= Request.Url.AbsoluteUri.EndsWith("/Invite") ? "selected" : "" %>'>Invite</li>
<li id="liFavourite" class='<%= Request.Url.AbsoluteUri.Contains("/Favourite") ? "selected" : "" %>'>My Favourites</li>
The <li> without runat="server" works fine, when on correct page the source code shows class="selected" or class="" as appropriate, the other <li> used to work fine too, until I decided to add the runat="server".
Once I added that runat="server", the whole block of class="" is being sent out to the html page, its not processing the server tags at all! I right click on the html and look at the source, it's being rendered as:
<li id="ctl00_ctl00_ContentPlaceHolder1_liBlog" class="<%= Request.Url.AbsoluteUri.EndsWith("/Blog") ? "selected" : "" %>">Group Blog</li>
It's pouring out my server tags into the source code!
Why is this behaviour seen? How can I avoid it?
I looked up a lot of similar threads in here and there was nearly nothing in google, so made this, I dont think this is a duplicate question.
You can't use the <%= %> syntax inside the properties of tags that have the runat="server" attribute on them.
You either need to:
Set the properties via your code-behind
Create an Expression Builder (and part 2 and part 3) and use the <%$ %> syntax (note: these are links to stuff I wrote on my blog, so, beware the self link =)
for your requirement you can also use ASP.NET menu and XmlSiteMap to do the same thing.

Resources