Highlighting Menu Bar in ASP.NET Web Application - c#

I have a Visual Studio 2010 and when I added a NEW project, VS gives me default css and UI themes. I have 6 aspx pages. Now whenever user is going into some specific page, I want the menu bar of that page to get highlighted so that user will know which page he/she is.
I have a page called: CommSetup.aspx. In the page_load I have written this code:
And in the master page I changed this:
In code behind:
protected void Page_Load(object sender, EventArgs e)
{
foreach (MenuItem item in NavigationMenu.Items)
{
var navigateUrlParams = item.NavigateUrl.Split('/');
if (Request.Url.AbsoluteUri.IndexOf(navigateUrlParams[navigateUrlParams.Length - 1]) != -1)
{
item.Selected = true;
}
}
}
Markup:
<body runat ="server" clientidmode ="Static" id = "MasterBody">
<form runat="server">......
<asp:Menu ID="NavigationMenu" runat="server" StaticSelectedStyle-CssClass ="Selected" CssClass="menu" .....
This is what I added in Site.css:
div.menu ul li a.Selected
{
background-color: #bfcbd6;
color: #465c71;
text-decoration: none;
}

Here's an example of doing exactly what you're asking for using CSS:
http://hicksdesign.co.uk/journal/highlighting-current-page-with-css
You should be able to achieve that using static ID naming on your controls (instead of letting ASP.NET assign the ID value to each control).
EDIT:
To get this to work with a master page, change the <body> tag in your master page to:
<body runat="server" clientidmode="Static" id="MasterBody">
Then in the Page_Load of each page, you can overwrite the id for each page (the master page in my example is of type SiteMaster):
protected void Page_Load(object sender, EventArgs e)
{
Control c = Page.Master.FindControl("MasterBody");
if (c != null)
{
c.ID = "Page1";
}
}
Update (2):
I tried running Farzin's example and it didn't seem to work, so here is what I was able to verify worked for me (you won't need the Page_Load from before in your content pages):
Site.master
<asp:Menu ID="NavigationMenu" ...>
<StaticSelectedStyle CssClass="selected" />
...
</asp:Menu>
Site.master.cs
protected void Page_Load(object sender, EventArgs e)
{
foreach (MenuItem item in NavigationMenu.Items)
{
item.Selected = Page.ResolveUrl(item.NavigateUrl).ToLowerInvariant() == Request.Path.ToLowerInvariant();
}
}
Styles/Site.css
div.menu ul li a.selected
{
/* put your style definition here */
}

You should parse current url in Master page (code behind) and assign different css clss to menu item that belongs to current url.
foreach (MenuItem item in NavigationMenu.Items)
{
var navigateUrlParams = item.NavigateUrl.Split('/');
if(Request.Url.AbsoluteUri.IndexOf(navigateUrlParams[navigateUrlParams.Length - 1]) != -1)
{
item.Selected = true;
}
}
just put this code in Form_Load event of your main master page (code behind)

You could use the ASP.NET Site Navigation functionality. Scott Mitchell has put out one of the definitive articles on it here.

Related

Hide <li> asp.net items depending on user privileges

I have to hide column 4 when specific users log in to a website. This is my current code for asp and c#:
protected void Page_Load(object sender, EventArgs e)
{
((LoggedIn)Page.Master).CurrentPage = LoggedIn.LoggedInMenuPages.1;
if (CurrentCustomer.AdminRole==false)
{
******NEED TO HIDE ITEM 4
}
}
Put runat="server" to the elements and also specific ID, after that go in Page_Load write the ControlID.Visible=false
ASPX
<li id="AdminElement" runat="server">
//other tags
</li>
Page_Load
AdminElement.Visible = CurrentCustomer.AdminRole;
//remove the class attribute from the aspx
AdminElement.Attributes["class"] = GetCurrentPageStyle("4");

Creating buttons/href from a list of names on the server side with javascript?

I have a list of button names and uri's containing links to other pages in my website. This is stored in my database. I also have a javascript function that can create buttons dynamically preferably when the page loads. Now what I need is on the server side to iterate through the list of button names and create a button for every button in the list?
Is this possible. I was thinking of maybe using the string builder to build some html to create the buttons or the method I like more is to call the javascript everytime I need a new button.
Here is my javascript function:
function createHref(Name, Uri) {
var leftDiv = document.createElement("div"); //Create left div
leftDiv.id = "left"; //Assign div id
leftDiv.setAttribute("style", "float:left; width:66.5%; line-height: 26px; text-align:left; font-size:12pt; padding-left:8px; height:26px;"); //Set div attributes
leftDiv.style.background = "#FF0000";
a = document.createElement('a');
a.href = Uri;
a.innerHTML = Name
leftDiv.appendChild(a);
document.body.appendChild(leftDiv);
}
Since this is ASP.NET I would use a Repeater and set the datasource to the button data you pull from your database.
For examples sake, I will assume you have a custom object MyButton that maps to your data:
public class MyButton
{
public MyButton()
{}
public string Name { get; set; }
public string Href { get; set; }
}
You would then have some markup for the repeater:
<asp:Repeater ID="rptMyButtons" runat="server" OnItemDataBound="rptMyButtons_ItemDataBound">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:HyperLink ID="hypUrl" runat="server" />
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
You would then bind your data to the repeater and set some properties on the objects:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
rptMyButtons.DataSource = //your data from the database
rptMyButtons.DataBind();
}
}
protected void rptMyButtons_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
{
MyButton button = (MyButton)e.Item.DataItem;
HyperLink hypUrl = (HyperLink)e.Item.FindControl("hypUrl");
hypUrl.Text = button.Name;
hypUrl.NavigateUrl = button.Href;
}
}
It seems like you may be trying to build a sitemap?
I have a list of button names and uri's containing links to other pages in my website
Which is why I have used a <ul> and <li>'s to contain your buttons in a list which makes more sense. It is quite easy to change this back to a <div> however.

Dynamic Div creation asp.net

I am trying to create Div dynamically on the press of button click.
For that i refered this link>> http://forums.asp.net/t/1349244.aspx
and made code on server side(.cs page) as follows>>
public static int i = 0;
protected void Button1_Click(object sender, EventArgs e)
{
i++;
HtmlGenericControl newControl = new HtmlGenericControl("div");
newControl.ID = "NEWControl"+i;
newControl.InnerHtml = "This is a dynamically created HTML server control.";
PlaceHolder1.Controls.Add(newControl);
}
This code was giving me just one div each time when i press the button., I wanted to have addition of divs.
On client side using javascript also i tried>>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" OnClientClick="addDiv();" />
</div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</form>
</body>
</html>
<script type="text/javascript">
function addDiv() {
alert("Control comming in function");
var r = document.createElement('Div');
r.style.height = "20px";
r.style.width = "25px";
r.appendChild("div");
alert("Control going out of function");
}
</script>
Both of these didnt work.
What mistake am i making?
Is there any thing wrong?
Use this
public int Index
{
get
{
if(ViewState["Index"]==null)
{
ViewState["Index"]=0;
}
else
{
ViewState["Index"]=int.Parse(ViewState["Index"].ToString())+1;
}
return int.Parse(ViewState["Index"].ToString());
}
}
protected void Button1_Click(object sender, EventArgs e)
{
HtmlGenericControl newControl = new HtmlGenericControl("div");
newControl.ID = "NEWControl"+Index;
newControl.InnerHtml = "This is a dynamically created HTML server control.";
PlaceHolder1.Controls.Add(newControl);
}
It is giving you one div, cause you are adding one div.
Remember that asp.net needs you to create all dynamically added controls on very PostBack after that.
If you want two controls you have to add two to the PlaceHolder.
Just use one parent div with some ID(predefined lets say id="dvDynamic") and runat="server"
and then use it the dvDynamic.innerHTML = "<div> /* dynamic div contents */ </div>"
Its the simplest way, as if you are using html element in ASP.net use dom controls for better generation. Dynamic creation of control will require handled, interface and many things to co-ordinate with that control. As its not predefined by system. you have to create it.
SO choose the DOM element option. that is faster and better :)
I hope this will help :)

How to disable user control from code-behind?

I have 2 user controls in an ASPX page. By default the second user control should be disabled. In that user control i am having only one text box. So i find the control in the page load event like this:
TextBox txtLocation = (TextBox)PI_CompLocationTree.FindControl("txtLocation");
txtLocation.Enabled = false;
But i am getting txtLocation as null. How do I get the control in the ASPX page from the ASCX control?
My Updated Code..In Aspx page..
<%# Register Src="~/UserControl/PI_CompLocationTree.ascx" TagName="PI_CompLocationTree"
TagPrefix="uc1" %>
<div id="Div2">
<div class="location">
<div class="usLocation">
<uc1:PI_CompLocationTree ID="PI_CompLocationTree1" runat="server"/>
</div>
</div>
</div>
In Page Load...
PI_CompLocationTree PI_CompLocationTree = new PI_CompLocationTree();
protected void Page_Init(object sender, EventArgs e)
{
var userControl = (PI_CompLocationTree)this.FindControl("PI_CompLocationTree1");
userControl.EnabledTextBox = false;
}
In ASCX Page...
<asp:TextBox ID="txtLocation" CssClass="fadded_text fadded_text_ctrl" Style="width: 260px;
float: left;" runat="server" Text=""></asp:TextBox>
In ASCX Code Behind...
public partial class PI_CompLocationTree : System.Web.UI.UserControl
{
public bool EnabledTextBox
{
get { return txtLoc.Enabled; }
set { txtLoc.Enabled = value; }
}
}
Use FindControl Methods as Follow..
1. UserControlClass objOfUserControl = (UserControlClass)Page.FindControl("UserControlID");
TextBox txtLocation= objOfUserControl.FindControl("txtLocation");
txtLocation.Enabled = false;
2.You Can Also use Public Property as Follow
In User Control Codebehind
public bool TextBoxUSC
{
set{txtLocation.Enabled = value;}
}
In Aspx Code Behind
UserControlClass.TextBoxUSC=false;
If You are using Master Page
ContentPlaceHolder cph = (ContentPlaceHolder)this.Page.Master.FindControl("MainContent");//"MainContent" is ContentPlaceHolder's ID
UserControlClass userCntrl = (UserControlClass)cph.FindControl("UserControlID");
userCntrl.TextBoxUSC = false;
Try this
Edited
Make Enabled false in aspx you can make like this:
Add property to your UC:
public bool EnabledTextBox
{
get{return IdTextBox.Enabled;}
set{IdTextBox.Enabled=value;}
}
then in aspx:
IdOfYourUserControlWithProperty.EnabledTextBox = false;
Hope it helps
Robin You can delete
TextBox txtLocation = (TextBox)PI_CompLocationTree.FindControl("txtLocation");
txtLocation.Enabled = false;
In your aspx, add forms with runat="server"
Delete also
PI_CompLocationTree PI_CompLocationTree = new PI_CompLocationTree();
You don't need because you use FindControl
Your work is good
PI_CompLocationTree1.EnabledTextBox = false; //from .aspx page. There's no need to use FindControl if you've added it statically to the webpage.

Updatepanel issue with client side "class" changing of a control inside repeater

I'm having trouble with using UpdatePanel and changing the 'class' attribute of a control inside a repeater by javascript.
Here some code:
--on the aspx--
<script type="text/javascript">
function changeClass(ctl) {
if (ctl.className == "marked") {
ctl.className = "unmarked";
} else {
ctl.className = "marked";
}
}
</script>
<!-- some html -->
<asp:UpdatePanel ID="upp" runat="server">
<ContentTemplate>
<asp:Repeater ID="rpt1" runat="server" onitemdatabound="rpt1_ItemDataBound">
<ItemTemplate>
<a id="aButton" runat="server" href="javascript:void(0)">
<!-- some other controls -->
</a>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
--Codebehind--
protected void rpt1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
MyClass obj = (MyClass)e.Item.DataItem;
((HtmlAnchor)e.Item.FindControl("aButton")).Attributes.Add("class", "marked");
//some other code....
}
}
//method called after the bind on 'rpt1'
private void mymethod()
{
foreach (RepeaterItem ri in rpt1.Items)
{
HtmlAnchor aButton = (HtmlAnchor)ri.FindControl("aButton");
if (Must-be-unmarked)
aButton.Attributes.Add("class", "unmarked");
aButton.Attributes.Add("OnClick", "changeClass(this);");
}
}
The problem is, when I click on an "aButton" the class is changed normally, but when I come in codebehind and get de 'class' of control to check if it's marked or unmarked, I only get the controls marked in ItemDataBound of repeater, not the "aButton"s marked by me at execution time.
here is what I do to get the "aButton"s marked:
private void checkMarked()
{
foreach (RepeaterItem ri in rpt1.Items)
{
if (((HtmlAnchor)ri.FindControl("aButton")).Attributes["class"] == "marked")
{
//do something...
}
}
}
When you change class property from client-side code, the server side will not know about it.
You'll need to add a hidden <input> with marked/unmakred so you can check the contents from the server on a post-back.
Another approach would be to sipmly have your javscript postback to the server directly when an item changes from marked/unmakred.

Categories

Resources