2

I've been trying different ways of changing the background color of the navbar when I visit specific pages (i.e. contact page), in angular - I've looked at ngclasses and different ways of trying to access the nav with no luck, as per other SO posts and the angular docs. So I thought I'd post up here. Here is the current code I've been playing with

navbar.component.ts

    import { Component, OnInit } from '@angular/core';

    @Component({
      selector   : 'app-navbar',
      templateUrl: './navbar.component.html',
      styleUrls  : ['./navbar.component.scss'],
      // template: '<img src="assets/img/wr-logo.png">'
      template: `
      <nav class="navbar navbar-expand-md navbar-fixed-top navbar-light bg-white main-nav" id="navbar navbar-change">
        <div class="container">
            <div class="navbar-collapse-nil collapse-nil nav-content order-1">
                <ul class="nav navbar-nav">
                    <li class="nav-item active">
                        <a class="nav-link" routerLink="/home/" id="imagelogo"></a>
                    </li>

                </ul>
            </div>
            <ul class="nav navbar-nav text-nowrap flex-row mx-md-auto order-2 order-md-2" id="center-nav-item">
            <div id="hoverDrop">
            <div class="dropdown">
            <button class="dropbtn">{{product_nav}}</button>
            <div class="dropdown-content">
              <a routerLink="/hours-of-rest/">{{hor_nav}}</a>
              <a routerLink="/on-leave/">{{leave_nav}}</a>

            </div>
          </div>
            </div>


              <li class="nav-item">
                <a class="nav-link" routerLink="/tour/">{{tour_nav}}</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" routerLink="/pricing/">{{pricing_nav}}</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" routerLink="/resources/">{{resources_nav}}</a>
              </li>

            </ul>
            <div class="ml-auto navbar-collapse-nil collapse-nil nav-content order-3 order-md-3" id="right-nav-item">
                <ul class="ml-auto nav navbar-nav">
                  <li class="nav-item"  onclick="blueNav">
                    <a class="nav-link" routerLink="/contact/" id="contact-nav-element" routerLinkActive="blue-active-link" [routerLinkActiveOptions]="{exact:
                      true}">{{contact_nav}}</a>
                  </li>

                  <li class="nav-item">
                    <a class="nav-link" href="https://google.com/" id="login-nav-element">{{login_nav}}  <i class="fa fa-arrow-right" aria-hidden="true"></i></a>
                  </li>
                </ul>
            </div>
        </div>
      </nav>
      `
    })
    export class NavbarComponent implements OnInit {

      product_nav:string;
      hor_nav:string;
      leave_nav:string;
      tour_nav:string;
      pricing_nav:string;
      resources_nav:string;
      contact_nav:string;
      login_nav:string;

      constructor() {

      }

      ngOnInit() {

        this.product_nav = 'Product';
        this.hor_nav = 'HoR';
        this.leave_nav = 'Leave';
        this.tour_nav = 'Tour';
        this.pricing_nav = 'Pricing';
        this.resources_nav = 'Resources';
        this.contact_nav = 'Contact';
        this.login_nav = 'Login';

        /* When the user scrolls down, hide the navbar. When the user scrolls up, show the navbar */
      var prevScrollpos = window.pageYOffset;
      window.onscroll = function() {
        var currentScrollPos = window.pageYOffset;
        if (prevScrollpos > currentScrollPos) {
          document.getElementById("navbar").style.top = "0";
        } else {
          document.getElementById("navbar").style.top = "-50px";
        }
        prevScrollpos = currentScrollPos;
      }




// window.onclick =
  //    function blueNav(){
  //    var blueTop = document.getElementByTagName("navbar");
  //      var i;
  //      for (i = 0; i < blueTop.length; i++) {
  //          blueTop[i].style.backgroundColor = "blue";
  //      }
  //    }


      window.onclick =
      function blueNav(){
        var blueTop = document.getElementById("navbar");
        var i;
        for (i = 0; i < blueTop.length; i++) {
            blueTop[i].style.backgroundColor = "blue";
        }
      }

      }

    }

any ideas appreciated

SJK
  • 91
  • 1
  • 10
  • 1
    Hi, `getElementById` returns only the first element with the given Id as far as I know, so `blueTop[i]` will always be undefined. If you want to style several elements with the same tag use `document.getElementByClassName` which returns an array of elements. – MichaelKie Sep 03 '18 at 09:18

3 Answers3

2

You can make use of subjects here. Create a service and add a subject there.

class service {
 public changeNavColor: subject = new Subject<any>();

}

Now, inject this service in all pages/components where you want to use it and in navbar component.

Now in ngOnInit lifecycle hooks of different components call

this.service.changeNavColor.next('red');

with the color that you want to set in navbar.

In navbar component,

this.service.changeNavColor.subscribe((color) => {
  this.navColor = color;

})

This will set property in navbar component and you can use that property in navbar component html using ngStyle binding or style.background binding.

Now when component is loaded it will pass a color value to navbar and sets its background.

Hope this helps.

Daniyal Awan
  • 107
  • 5
1

Add [ngClass]="{'contactpage-bg': rla.isActive }" to navbar

<nav [ngClass]="{'contactpage-bg': rla.isActive }"></nav>

In the nav-item for contact page

<li class="nav-item ">
        <a  #rla="routerLinkActive" routerLinkActive="active-route"
            routerLink="/contact">Contact</a>
</li>

And give the background color for contactpage-bg class

  • How do you make sure the other pages won't get affected? – QuanDar May 18 '21 at 13:28
  • edit: found an easier solution here: https://stackoverflow.com/questions/44376598/angular-apply-style-to-element-depending-on-sibling-routerlinkactive – QuanDar May 18 '21 at 13:36
0

In the end I just created a second navbar component as I needed quite a few more different links and buttons/ cta's on the 2nd menu navigation than I initially anticipated. I then injected the appropriate navigation to the corresponding component.ts page. Both of the other answers were also good approaches.

Hopefully this question can help others. I've tried to include a simple approximation of how I solved it with a simple routing approach

i.e in pageone.component.ts there would be

    @Component({
  selector: 'app-one',

  templateUrl: './pageone.component.html',
  styleUrls  : ['./pageone.component.scss'],
  template   : `
  <app-navbar-one></app-navbar-one>
  <section id="foo">...</section>
`

and in pagetwo.component.ts

@Component({
  selector: 'app-two',

  templateUrl: './pagetwo.component.html',
  styleUrls  : ['./pagetwo.component.scss'],
  template   : `
  <app-navbar-two></app-navbar-two>
  <section id="bar">...</section>
`

Hope that makes sense. Turns out the simple approach was more functional in my particular case (as I needed to do more than just change the background colour, on certain pages - different menu items/ page routes etc), as it turned out. Apologies if my English isn't clear in this explanation.

SJK
  • 91
  • 1
  • 10