Dwigh
Dwigh

Reputation: 441

find which link caused route to change

The application uses angularjs. I have a navigation bar which opens pages and also another UI which also opens the same pages(same links).

I am using $locationChangeStart to toggle open the sub-menu in the navbar when I open a page from the other UI.

When I open the same page from the from the navigation bar, the toggle happens and the sub-menu of navbar closes.

$rootScope.$on("$locationChangeStart", function(event, next, current) { 

  $rootScope.hashUrl = next.split('#').pop();
  $rootScope.hashUrl = '#' + $rootScope.hashUrl;
  console.log($rootScope.hashUrl, "URL");   //#!/addflats
  $rootScope.addActiveToSidebarElement(event, next, current);

});

The function the locationChangeStart calls:

$rootScope.addActiveToSidebarElement = function(event, next, current) {
  $rootScope.anchorElement = $("a[href='" + $rootScope.hashUrl + "']");
  if (parentLi.hasClass('associationChildLi')) {
    $rootScope.anchorElement.addClass('selectedSideBarChildActive');
    $('.associationUl').slideToggle();
  }
}

Both links(from navigation bar and other UI) cause the route change. How do I find which link caused the route to change?

Edit:

I will try to explain better. I have two links that open the same page. One link from a navigation bar, one from a tile.

When I open the page, I want to highlight the respective nav item. It works naturally when I use the navigation bar. When I open the page from the tile, I have to highlight the nav item.

So I am using $locationChangeStart to detect which route I am currently on and find the <li><a href='#!/addflats'>link</a></li> element in the navigation bar which matches the current route and add a class that highlights it.

I need to find which link(navigation bar or tile) caused the route to change

Upvotes: 4

Views: 398

Answers (4)

T. Shashwat
T. Shashwat

Reputation: 1165

It's very handy to add references to $state and $stateParams to the $rootScope so that you can access them from any scope within your applications.

You can try ui-sref-active directive in module ui.router.state , that alongside ui-sref to add classes to an element when the related ui-sref directive's state is active, and removing them when it is inactive. ui-sref-active can live on the same element as ui-sref or on a parent element. The first ui-sref-active found at the same level or above the ui-sref will be used. Will activate when the ui-sref's target state or any child state is active.

here is working plunker http://next.plnkr.co/plunk/dY3NluIyEFU7yuhh , when you click on Route 1 it will show you route1.html and its state will change to active, and same when you click Route 2 if you click on R1 items inside route1.html it will navigate to route2,HTML and will change state of Route 2 to active.

Hope that's what you looking.

Upvotes: 0

DavidC
DavidC

Reputation: 1862

If you have two links that you want to differentiate you could add a search term to the URL:

<li><a href='#!/addflats?from=nav'>link</a></li>

and

<li><a href='#!/addflats?from=tile'>link</a></li>

Upvotes: 2

Mark Clark
Mark Clark

Reputation: 535

Just to clarify, it sounds like your goal is different from your question. I will attempt to address what sounds like your goal: 'Highlight a nav item that reflects my active state'.

I would think that you would want to use $locationChangeSuccess because using start will likely put you before whatever DOM manipulations happen during and after the state change which could include a reload of your navigation template.

It is important to note, you should not be making these DOM manipulations in a controller. At the very least, you should have a controller around your navigation and have $scope variables that you can bind to these navigation items with ng-class.

Once you are using a controller around your nav, you can listen to the $locationChangeSuccess event from that controller, inspect the new url that is returned and set the appropriate $scope variable(s).


If you are using ui-router this becomes a great deal easier because you can simply use ng-class="{'active':$state.includes('example.state')}" on the nav html element in question AngularUI: $state.includes

Upvotes: 0

Shubham Jain
Shubham Jain

Reputation: 307

Bubbling principle of DOM might help you in this scenario.
When an event happens on an element, it first runs the handlers on it, then on its parent, then all the way up on other ancestors.

Similarly here click event occurs on tag it handles that event and move all the way up to its parent tag. So when you will click on the ui buttons it will give you parent tag as and when you will click on navbar buttons it will give you as parent tag and you will get to know which route has been hit.

see this example

document.getElementById("ui").addEventListener("click", myFunction);
document.getElementById("navbar").addEventListener("click", myFunction);
function myFunction() {
	alert("Parent Tag Name-"+this.tagName)
}
ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
    overflow: hidden;
    background-color: #333;
}

li {
    float: left;
}

li a {
    display: block;
    color: white;
    text-align: center;
    padding: 14px 16px;
    text-decoration: none;
}
<div id="ui">
  <a href="">Home</a>
  <a href="">News</a>
  <a href="">Contact</a>
  <a href="">About</a>
</div>
<br>
<ul id="navbar">
  <li><a >Home</a></li>
  <li><a href="">News</a></li>
  <li><a href="">Contact</a></li>
  <li><a href="">About</a></li>
</ul>

Upvotes: -1

Related Questions