How can I disable the Menu control from styling itself in javascript? - asp.net

I'm using Visual Studio 2010 and ASP.NET 4.0 to render a Menu control as an HTML list so I can style it using CSS. Here is the code I am using below
<asp:Menu ID="navlist" runat="server" Orientation="Horizontal"
SkipLinkText="" ClientIDMode="Static" DataSourceID="MenuSource"
MaximumDynamicDisplayLevels="0" IncludeStyleBlock="False"
StaticDisplayLevels="2">
</asp:Menu>
This produces the following HTML
<!-- URL shortened -->
<script src="/WebResource.axd?...t=634066906994188146"type="text/javascript"></script>
<div id="navlist">
<ul>
<li>Link 1</li>
<li>Link 2</li>
</ul>
</div>
At first glance this looks like exactly what I wanted. However, if I open up WebResource.axd there is a whole bunch of javascript code related to the menu. Part of this code is applying it's own inline styles to the list. Using FireBug I can view the HTML markup after the javascript has executed and it looks something like this:
<div id="navlist" style="float: left;">
<ul class="level1 static" tabindex="0" style="position: relative; width: auto; float: left;" role="menubar">
<li role="menuitem" class="static" style="position: relative; float: left;">
Link 1
</li><li role="menuitem" class="static" style="position: relative; float: left;">
Link 2</li>
</ul>
</div>
These inline styles ultimately affect the layout of my page. I have no need for any of the scripts in WebResource.axd. How can I prevent this script from being rendered in the final markup of the page?

You can tell the menu to NOT style itself if you want to just use the IncludeStyleBlock Attribute
By default its turned on "true"
<asp:Menu IncludeStyleBlock="False" />

On your css use the !important

I've created a custom menu (derived from System.Web.UI.WebControls.Menu) and replaced the OnPreRender:
public class MyCustomMenu : System.Web.UI.WebControls.Menu
{
protected override void OnPreRender(EventArgs e)
{
// Don't call base OnPreRender
//base.OnPreRender(e);
}
}
That did the trick.

You can't do much to change the out-of-the-box functionality of the Menu control. However, you could either create your own control or use the CSS Control Adapter Toolkit.

I tried to override the asp:menu with a custom class, but still haven't learned how to simply remove all attributes from the ul, li, and a tags so that I could apply my own css code to a clean list.
Imports Microsoft.VisualBasic
Namespace MCO
Public Class MyCustomMenu
Inherits Menu
Protected Overrides Sub OnPreRender(e As EventArgs)
' don't use this:
' MyBase.OnPreRender(e)
' but leaving this blank produces NO rendered menu
End Sub
End Class
End Namespace
I have also tried the jQuery method:
$("#navlist li,#navlist li a,#navlist ul,#navlist div").removeAttr('style');
But because the .net webresource is the last thing to run, I found that jQuery line didn't work. It should, but doesn't. :(

I managed this by removing inline styles and changing some class names via jQuery. Of course you can re-style every element but it just produces a lot of unnecessary css code.
Use this, if you want to remove those inline styles from li, a, ul and divs:
$("#navlist li,#navlist li a,#navlist ul,#navlist div").removeAttr('style');
Second you can change those class names e.g.:
$("#from-this-element").removeClass(.remove-me).addClass('.new-class');
And I think it's the best way to use this script after the page has loaded.

Related

ASP.NET WebForms - Issues disabling list item

I am running (ASP.NET Web Forms) VB.Net code and in the aspx page, i have something like this:
<ul id="tabsdefault" class="tab-menu">
<li id="accessingIndividuals" runat="server"><a>Accessing Individuals</a></li>
</ul>
and in the code behind file, i have this code:
accessingIndividuals.Disabled = true
However, before upgrading to .NET 4.6, this code worked and now after the upgrade, it does not disable the list item.
I have also manually changed the aspx page item with this:
<ul id="tabsdefault" class="tab-menu">
<li id="accessingIndividuals" runat="server" disabled="disabled"><a>Accessing Individuals</a></li>
</ul>
but that did not work and nor did the following:
<ul id="tabsdefault" class="tab-menu">
<li id="accessingIndividuals" runat="server" disabled="true"><a>Accessing Individuals</a></li>
</ul>
Any idea what has changed in .NET Framework or how can disable this item?
Looking at the page source using Developer Tools, the output is like this:
<ul id="tabsdefault" class="tab-menu">
<li id="accessingIndividuals" enabled="false" disabled="disabled" class="selected"><a>Accessing Individuals</a></li>
</ul>
Looks like all new Browsers ignore the disable attribute on a list item. One possible solution is:
li[disabled]
{
pointer-events: none;
opacity: 0.6;
}

show/hide css menu item depending user role using asp.net

I have the css layout: One column fixed width layout, from maxdesign.com
I have two menu items defined like the following:
<div id="navigation">
<ul>
<li>Data Entry</li>
<li>Reports</li>
</ul>
</div>
Now, let's say that I have two roles: guest and operator, and I want that for example if a user with role guest is logged in, then just the Report item from the menu appear, and in case of a user operator is logged in, then both options appear.
How can I accomplish that?
EDIT:
Based on your responses, I'll go with the server side logic to deal with this:
<div id="navigation">
<ul>
<li><asp:LinkButton ID="lkbDataEntry" runat="server">Data Entry</asp:LinkButton></li>
<li><asp:LinkButton ID="lkbReports" runat="server">Reports</asp:LinkButton></li>
</ul>
</div>
Thanks!
You can put this in the Page_Load..
Dim cs As ClientScriptManager = Page.ClientScript
If Not cs.IsClientScriptBlockRegistered(Me.GetType(), "RoleVariable") Then
Dim js As New String
js = "var _role = " & role & ";"
cs.RegisterStartupScript(Me.GetType(), "RoleVariable", js, True)
End If
And from there, you will have the role in the Javascript realm, where you can manipulate the visibility of the items you want.
So...
<script type="text/javascript">
function hideStuff() {
if (_role === "operator") {
// hide/show your elements here
}
else if (_role === "guest") {
// hide/show your elements here
}
}
</script>
Keep in mind that this approach is all client-side and is therefore easy for another developer to manipulate if they really wanted to. But on the other hand, it's the simplest. Don't use this approach for high-security situations.
You could give your menu elements an ID attribute and then in your codebehind either use RegisterClientSideScriptBlock or use Response.Write to send JavaScript to the client to hide (or show) elements based on some condition.
how about something simple like?
<% if(Page.User.IsInRole("operator") || Page.User.IsInRole("guest")) { %>
<div id="navigation">
<ul>
<% if(Page.User.IsInRole("operator")) { %>
<li>Data Entry</li>
<% } %>
<li>Reports</li>
</ul>
</div>
<% } %>
I don't 100% think you can (or should) be doing logic operations with stylesheets. You may need to have some javascript and then decide based on guest or operator which style to display

FindControl results in null reference

I have anchor tags like this
<div id="menu_container">
<ul id="nav-bar">
<li>Home</li>
<li><a href="Account.aspx" runat="server" id="menu_item_account" >Account</a></li>
<li>Servers</li>
<li>Statistics</li>
<li>Tutorials</li>
<li>Contact us</li>
<div id="login_registration_container">
Sign in / Register
</div>
</ul>
</div>
I want to change the CSS class for menu_item_default this way:
WebControl wc = (WebControl)FindControl("#menu_item_default");
wc.Attributes.Add("class", "value");
error: null reference exception
How can this be done?
You shouldn't use '#' symbol in the FindControl argument:
WebControl wc = (WebControl)FindControl("menu_item_default");
Using a MasterPage and the element is in a ContentPlaceholder:
If so then you must retrieve the ContentPlaceholder first, and from it retrive the element you want.
If your page has the following Content-area for example:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
Then you would do the following (error handling omitted):
var mainCtrl = Master.FindControl("MainContent");
var anchor = (HtmlAnchor) mainCtrl.FindControl("menu_item_default");
anchor.Attributes.Add("class", "value");
Using a MasterPage and the element is in the MasterPage:
use:
var anchor = (HtmlAnchor) Master.FindControl("menu_item_default");
Is there a particular reason you are using a regular anchor tag? Why not use an ASP.Net LinkButton? That will make it much easier to reference in the code.
If the control is on the master page, try
Master.FindControl()

change master page <a href link from content page

i have this on my master.page
<ul class="menu">
<li class="first" runat="server" id="Li2">
<a runat="server" id="A1" href="../NewEntry.aspx">Create a New Entry</a>
</li>
</ul>
when i go to content page ("NewEntry.aspx") i want the link name to be changed to "Update Entry"
<ul class="menu">
<li class="first" runat="server" id="Li2">
<a runat="server" id="A1" href="../UpdateEntry.aspx">Update Entry</a>
</li>
</ul>
any feedback?
Make the link an asp:Hyperlink. Then have the master page expose a function or property:
public void SetLink(string href, string text)
{
A1.NavigateURL = href;
A1.Text = text;
}
Call the function from the main page.
You can use a hyperlink control <asp:hyperlink> and set the url as well as the text values.
I would recommend handling this as a HyperLink control as others have mentioned. If for some reason you must handle this as a server-side HTML anchor, you can access it using the following code from your webform code-behind:
HtmlAnchor link = (HtmlAnchor)(this.Master).FindControl("A1");
link.InnerText = "Update Entry";
You can also define a content place holder where you have "Create a New Entry". Leave that as the default inside that place holder, and only in the content page set content for it to Update Entry.

CSS form[action] not working with Query Strings

Hi all having a few problems with my CSS
I am trying to highlight a link on the navigation based on the page the user is on.
I have this style which works as I would like it to do, but when I pass a query-string into pcisHPprofile.aspx the CSS is not working. Does anyone know how i can get this style to work with query-strings?
body form[action="pcisHPprofile.aspx"] #btnuser
{
padding: 18px 4px 5px 4px;
background-image: url(../images/tabbluleft.gif) ;
background-repeat:no-repeat;
color: #fff;
}
<div id="nav" class="nav" >
<ul>
<li id="tab1">
<a id="btnsession" href="pcissessionlist.aspx" > <span >Session</span></a>
</li>
<li id="tab2">
<a id="btnsystem" href="pcissystemsettings.aspx" > <span >System Settings</span></a>
</li>
<li id="tab3">
</li>
<li id="tab4">
<a id="btnuser" href="pcisuserlist.aspx" > <span >User Logins</span></a>
</li>
<li id="tab5">
<a id="btninterpreter" href="pcisinterpreterlist.aspx" > <span >Interpreter Profile</span></a>
</li>
<li id="tab6"><asp:LinkButton ID="btnreports" runat="server" Visible="false" cssid="cssreports" PostBackUrl="#"><span>Reports</span></asp:LinkButton></li>
</ul>
</div>
I assume that the #btnuser ARE some buttonS inside the some forms, where one of the forms have action="pcisHPprofile.aspx"?
If that is correct, then your error is the fact that you have many buttons with the same id attirbute id="btnuser". The ID attibute MUST be uniqe on the page. change the id="btnuser" to class="btnuser" on the buttons and your selector from:
body form[action="pcisHPprofile.aspx"] #btnuser {
}
to
body form[action="pcisHPprofile.aspx"] .btnuser {
}
Then it should work.
In the first form it might work only if the FIRST button with id="btnuser" is actually inside the form with action="pcisHPprofile.aspx". If it is inside any other form, then it will not work.
Best regards,
SWilk
UPDATE:
After OP updated the question, I think that this form of selector should work:
body form[action^="pcisHPprofile.aspx"] #btnuser {
...
}
It would a element with id=btnuser inside a form, which action begins with "pcisHPprofile.aspx". It would not matter if the acutal action attibute contain only "pcisHPprofile.aspx" or "pcisHPprofile.aspx?any-parameters&and=some-values".
Best regards,
SWilk
Using action attribute for styling is a bad practice. Just give your form a name, class or ID like <form class="pcisHPprofile" action="pcisHPprofile.aspx"> and then apply CSS style to that name/class/id.
form.pcisHPprofile {
padding: ...
Found a working solution. a little hacky which I am not 100% keen on but it works.
I changed the query string to look like this
profile.aspx?-&username=
from this
profile.aspx?username=
and I changed the style to
Form[action|="pcisinterpreterprofile.aspx?"] #tab5
{
background-image: url(../images/tabbluright.gif);
background-repeat:no-repeat;
}
The difference is that I have changed the = to an |=.
[att|=val]
Represents an element with the att attribute, its value either being
exactly "val" or beginning with "val"
immediately followed by "-" (U+002D).
This is primarily intended to allow
language subcode matches (e.g., the
hreflang attribute on the a element in
HTML) as described in RFC 3066
([RFC3066]) or its successor. For lang
(or xml:lang) language subcode
matching, please see the :lang
pseudo-class.
by doing this the css selector works on pages with query strings. you just need to make sure the query string has at least ?- at the start. As I said at the last its not great but works.

Resources