Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create breadcrumbs dynamically on client side using javascript

I want to create breadcrumbs dynamically on client side using java script. The breadcrumbs will be the path followed by user while navigation as: Home > about us > our history..

The anchor tags will be generated on each page in the sequence in which the user navigate.

Now I can create these breadcrumbs using server side technology easily but I want to generate it dynamically on each page on client side. Now I don't know exactly how to implement it.

Some logic in my mind is as:

  1. Create an object type variable in java script with a name and value pair where name is the name of current page and value is the url of that page.

  2. Now pass this object variable using query string while navigating from one page to other.

  3. Then in the second page get that object variable from query string and extract the name and value pair from that object and then using that create the anchor and add it to targeted div (place holder).

  4. Again when user goes to another page add the name and value pairs for all the previous pages along with the name and value pair for current page at the last in the object variable and pass it to next page using query string.

  5. Now in next page do the same and create anchors.

Some what similar I got here using html5 client side storage as: html:

<ul id="navigation_links">
    <li>Page1</li>
    <li>Page2</li>
    <li>Page3</li>
</ul>

js:

$(document).ready(function(){
    bindEventToNavigation();
});

function bindEventToNavigation(){
    $.each($("#navigation_links > li"), function(index, element){
        $(element).click(function(event){
            breadcrumbStateSaver($(event.currentTarget).html());
            showBreadCrumb();
        });
    });
}


function breadcrumbStateSaver(text){
    //here we'll check if the browser has storage capabilities
    if(typeof(Storage) != "undefined"){
        if(sessionStorage.breadcrumb){
            //this is how you retrieve the breadcrumb from the storage
            var breadcrumb = sessionStorage.breadcrumb;
           sessionStorage.breadcrumb = breadcrumb + " >> "+text;
        } else {
           sessionStorage.breadcrumb = ""+text; 
        }
    }
    //if not you can build in a failover with cookies
}

function showBreadCrumb(){
     $("#breadcrumb").html(sessionStorage.breadcrumb);   
}
<div id="breadcrumb"></div>

but here instead of creating hyperlinked anchors it is creating simple text, whereas I want the breadcrumbs to be anchors and hyperlinked to their respective pages.

I am new to java script and don't know how to implement this. If you have any better logic and solution for this please tell me.

thanks in advance.

like image 907
Saurabh Palatkar Avatar asked Oct 22 '22 00:10

Saurabh Palatkar


2 Answers

When you are adding the items to the breadcrumb you are not adding them as links, you are just adding text and the click events you had binded to the li elements will not passed along. Finally, you are not giving any sort of href for those breadcrumbs to use.

Try something like this and put it on 4 pages with those links and the script file on each page

<div id="breadcrumb"></div>
<ul id="navigation_links">
    <li><a href="page1.html">Page 1</a></li>
    <li><a href="page2.html">Page 2</a></li>
    <li><a href="page3.html">Page 3</a></li>
    <li><a href="page4.html">Page 4</a></li>
</ul>

JS

$(document).ready(function(){
    bindEventToNavigation();
    showBreadCrumb(); //Show the breadcrumb when you arrive on the new page
});

function bindEventToNavigation(){
    $.each($("#navigation_links > li > a"), function(index, element){
        $(element).click(function(event){
            breadcrumbStateSaver($(this).attr('href'), $(this).text());
            showBreadCrumb();
        });
    });
}

function breadcrumbStateSaver(link, text) {
    if (typeof (Storage) != "undefined") {
        if (sessionStorage.breadcrumb) {
            var breadcrumb = sessionStorage.breadcrumb;
            sessionStorage.breadcrumb = breadcrumb + " >> <a href='" + link + "'>" + text + "</a>";
        } else {
            sessionStorage.breadcrumb = "<a href='" + link + "'>" + text + "</a>";
        }
    }
}

This is only going to put links on pages after the first one. So alternatively you can use

$(document).ready(function () {
    breadcrumbStateSaver(document.title, document.location.href);
    showBreadCrumb();
});

at the top of each page and automatically add it to the breadcrumb instead of doing it on the click. If you need the clicks to run some other function/event you can use span/li/div tags with an id that you can bind an event to instead of just using anchors.

Finally, this will not stop there from being duplicates in the crumb, so you may want to consider storing the links & text in an array and build the crumbs from that.

like image 77
Luke Avatar answered Oct 24 '22 10:10

Luke


Like @Luke said, you are not adding any links for the breadcrumbs to navigate. You have to store the text and link like so:

function breadcrumbStateSaver(link, text) {
if (typeof (Storage) != "undefined") {
    if (sessionStorage.breadcrumb) {
        sessionStorage.breadcrumb = sessionStorage.breadcrumb + ";" + text;
        sessionStorage.locations = sessionStorage.locations + ";" + link; //use any delim you prefer
    }
    else {
        sessionStorage.breadcrumb = text;
        sessionStorage.locations = link;
    }
}

You can just add both the text and link into one storage variable and split it with a delimiter to extract it!

Instead of capturing the link on click you can actually get the link when the page loads from document.location.href, and the text can be taken from document.title or some attribute which will be set in server. So on document.ready

$(document).ready(function(){
    breadcrumbStateSaver(document.title, document.location.href);
    showBreadCrumb();
});

To update the breadcrumbs inside a <ul>:

function showBreadCrumb(){
    let crumbs = sessionStorage.breadcrumb.split(";");
    let links = sessionStorage.locations.split(";");
    for(let index in crumbs)
        $("#navigation_links").append($("<li><a href="+links[index]+">"+ crumbs[index] +"</a></li>"));
}

This way it will it record every time user navigates your website. If you want the user to navigate through the breadcrumbs, by going back to the page they were in by clicking on the breadcrumb, change the above code to the following:

function showBreadCrumb(){
    let crumbs = sessionStorage.breadcrumb.split(";");
    let links = sessionStorage.locations.split(";");
    let crumbindex = parseInt(sessionStorage.crumbindex);
    for(let index in crumbs){
        $("#navigation_links").append($("<li><a class='crumb"+ (index==crumbindex ? "active" : "") + "' href='"+links[index]+"' data-node='"+index+"'>"+ crumbs[index] +"</a></li>")); //data-node will help in retrieving the index and class will be set to active for selected node
    }
}

also add:

$(document).ready(function(){
    $('#navigation_links').on('click', 'li a.crumb', function(){
        if (typeof (Storage) != "undefined") {
            sessionStorage.crumbindex = $(this).data('node');
            sessionStorage.navlinkclicked = "true"; //This will prevent from adding breadcrumb again
        }
    });
    breadcrumbStateSaver(document.title, document.location.href);
    showBreadCrumb();
});

Using the node index, you can insert the breadcrumb like so:

function breadcrumbStateSaver(link, text) {
if (typeof (Storage) != "undefined") {
    if (sessionStorage.breadcrumb) {
        if (sessionStorage.navlinkclicked && sessionStorage.navlinkclicked=="true") {
            sessionStorage.navlinkclicked = "false"; //prevent changes or you can remove the rest of the crumbs from sessionStorage.breadcrumb and locations using a for loop
        }
        else {
            if(sessionStorage.crumbindex && sessionStorage.crumbindex!=-1) {
                let crumbs = sessionStorage.breadcrumb.split(";");
                let links = sessionStorage.locations.split(";");
                let crumbindex = parseInt(sessionStorage.crumbindex);
                sessionStorage.breadcrumb = crumbs[0];
                sessionStorage.locations= links[0];
                for(let index in crumbs){
                    if(index==0) continue;
                    sessionStorage.breadcrumb = sessionStorage.breadcrumb + ";" + crumbs[index];
                    sessionStorage.locations= sessionStorage.locations + ";" + links[index];
                    if(index==crumbindex) break;
                }
                sessionStorage.breadcrumb = sessionStorage.breadcrumb + ";" + text;
                sessionStorage.locations = sessionStorage.locations + ";" + link; //insert the new link after crumbindex location
                sessionStorage.crumbindex = -1;
            }
            else{
                sessionStorage.breadcrumb = sessionStorage.breadcrumb + ";" + text;
                sessionStorage.locations = sessionStorage.locations + ";" + link; //keep appending
            }
        }
    }
    else {
        sessionStorage.breadcrumb = text;
        sessionStorage.locations = link;
    }
}

If you simply want the breadcrumbs for navigation, rather than recording the users traversal, you can simply split the url path using window.location.pathname. Given that your pages are stored in proper hierarchy with index pages, all you have to do is to split the url path and update showBreadCrumb() accordingly. You dont need to use session storage!

    function showBreadCrumb(){
        let crumbs = window.location.pathname.split("/");
        for(let index=0; index<crumbs.length-1; index++){
            let text = crumbs[index];
            if(index==0) text = "Home";
            $("#navigation_links").append($("<li><a class='crumb"+ (index==crumbs.length-2? "active" : "") +"' href='"+buildRelativeLink(crumbs.length-index)+"'>"+ text +"</a></li>"));
        }
    }
    function buildRelativeLink(level)
    {
        level = level - 1;
        let link="";
        for (let i=1; i<level; i++)
        {
            link=link+ "../"; //Used to navigate one level up towards parent
        }
        return link;
    }
like image 28
Stalin Thomas Avatar answered Oct 24 '22 10:10

Stalin Thomas