Search code examples
javascriptjquerycsshtmlnav

How can I give the current page's link a disabled look?


In my web site, I have three pages: Home, About, and Contact. I want the current page's link to give some visual indication that clicking the corresponding link would be senseless as the user is already on that page. Is this task better handled by CSS or jQuery, and in either case, what is the most elegant solution that will also automatically apply to any pages which may be added in the future?

Here's my HTML diesbezueglich:

<nav>
    <ul id="menu">
        <li><a href="~/">Home</a></li>
        <li><a href="~/About">About</a></li>
        <li><a href="~/Contact">Contact</a></li>
    </ul>
</nav>

UPDATE

I wonder why this didn't work; I added to Site.css this:

nav ul li a.current {
    color: blue;
}

And the relevant HTML is:

<nav>
    <ul id="menu">
        <li><a href="~/">Home</a></li>
        <li><a href="~/About">About</a></li>
        <li><a href="~/Contact">Contact</a></li>
    </ul>
</nav>

Yet the links remain the same (as Led Zeppelin predicted).

UPDATE 2

I tried this to test out kind of an amalgam of the various ideas proposed here:

In Site.css:

.current {
    color: blue;
}

In _SiteLayout.cshtml:

<ul id="menu">
    <li id="home" name="home"><a href="~/">Home</a></li>
    <li><a href="~/About">About</a></li>
    <li><a href="~/Contact">Contact</a></li>
</ul>

In Default.cshtml:

<script type="text/javascript">
    $(document).ready(function () {
        $("#tabs").tabs();
        $(".fancybox").fancybox();
        $("home").addClass('current');
    });
</script>

...but no go; the "Home" link is as homely as ever (no pun intended).

I also tried giving all of the links an id of "location" and adding this to Default.cshtml's "ready" function:

if ($(#location).attr('href').indexOf('home') != -1) $('home').addClass('currentPage');
else if ($(#location).attr('href').indexOf('about') != -1) $('about').addClass('currentPage');
else if ($(#location).attr('href').indexOf('contact') != -1) $('contact').addClass('currentPage');

(where "currentPage" is the css class that sets the color to blue, and each nav link has an id of "location"); I reckon I would also have to add a "removeClass" for the two links with an index of -1 in each if/else block.

My beer is getting saltier by the nanosecond.

UPDATE 3

I tried this:

Added the IDs to the elements in _SiteLayout.cshtml:

<nav>
    <ul id="menu">
        <li id="home"><a href="~/">Home</a></li>
        <li id="about"><a href="~/About">About</a></li>
        <li id="contact"><a href="~/Contact">Contact</a></li>
    </ul>
</nav>

And added this to Site.css:

#home {color: orange;}
#home.current {color: blue;}
#about {color: orange;}
#about.current {color: blue;}
#contact {color: orange;}
#contact.current {color: blue;}

...but it did nothing - all the links are still gray no matter where I navigate.

UPDATE 4

Also tried this to no avail:

if ($('#home').attr('href').indexOf('Home') != -1) $('#home').addClass('currentPage');

UPDATE 5

I wonder if there's a way to use the _PageStart.cshtml to handle this? IOW, could I do something like:

@{
    Layout = "~/_Layout.cshtml";
    //pseudocode follows
    var currentPage = CurrentPage.Id;
}

//and then some jQuery (also pseudocode):

if @currentPage == Default {
    #home.display = none;
else if @currentPage == About {
    #about.display = none;
else if @currentPage == Contact {
    #contact.display = none;
} // perhaps set them all visible from the git-go

UPDATE 6

Another possibility that "jQuery for ASP.NET Developers" has inspired is something like the following inside the "ready" function (pseudocode; if this would work, I welcome the specific jQuery I would need to flesh this out):

// first set all of the nav ul li to their default color, right? (not shown)
// now, color the current one chartreuse:
$("nav ul li").each(function() {
    switch ($(this.name)) {
        case 'home':
            $(#home).css("color", "chartreuse");
            break;
        case 'about':
            $(#about).css("color", "chartreuse");
            break;
        case 'contact':
            $(#contact).css("color", "chartreuse");
            break;
    }
});

UPDATE 7

Well, I'm sure this is nobody's idea of elegant, but I did figure out a way to accomplish it by using a click event for each li. Elegantizations welcome to the jsfiddle here: http://jsfiddle.net/vV4h5/1/

As to the elegantization of the jsfiddle above, there must be a way to do something like this instead:

jQuery(function () {
    $("nav ul li").css("color", "black");
    var currentLI = theOneClicked; //??? how to get this???
    $(currentLI).css("color", "blue");
});

UPDATE 8

It works in jsfiddle, but not in my project; Having this in _SiteLayout.cshtml:

<nav>
    <ul id="menu">
        <li id="home"><a href="~/">Home</a></li>
        <li id="about"><a href="~/About">About</a></li>
        <li id="contact"><a href="~/Contact">Contact</a></li>
    </ul>
</nav>

. . .

jQuery(function () {
    $("#home").click(function (event) {
        $("#home").css("color", "blue");
        $("#about").css("color", "black");
        $("#contact").css("color", "black");
    });
});

jQuery(function () {
    $("#about").click(function (event) {
        $("#home").css("color", "black");
        $("#about").css("color", "blue");
        $("#contact").css("color", "black");
    });
});

jQuery(function () {
    $("#contact").click(function (event) {
        $("#home").css("color", "black");
        $("#about").css("color", "black");
        $("#contact").css("color", "blue");
    });
});

...does not work. Neither does moving just the first function to Default.cshtml, so that it looks like this:

$(document).ready(function () {
    $("#tabs").tabs();
    $(".fancybox").fancybox();
    $("#home").click(function (event) {
        $("#home").css("color", "blue");
        $("#about").css("color", "black");
        $("#contact").css("color", "black");
    });
});

Solution

  • UPDATED

    On second thought, your problem is that when you click the link to a new page, you are refreshing the javascript...so the click event fires but then is immediately replaced by the original DOM elements for whatever page you browse to.

    Use this instead:

    HTML/Razor

    <nav>
        <ul id="menu">
            <li><a href="/">Home</a></li>
            <li><a href="/About">About</a></li>
            <li><a href="/Contact">Contact</a></li>
        </ul>
    </nav>
    

    jQuery

    $(document).ready(function () {
            $("#menu a").each(function(){
                //set all menu items to 'black
                $(this).css("color","black");
    
                var linkPath=$(this).attr("href");
                var relativePath=window.location.pathname.replace('http://'+window.location.hostname,'');
    
                //set the <a> with the same path as the current address to blue
                if(linkPath==relativePath)
                    $(this).css("color","blue");
            });
    });