Search code examples
javascriptangulartypescriptsassangular11

ngClass and onClick Not Applying to Div


I have a javascript project that I'm trying to convert into Angular and I'm having trouble understanding why the classes some of my are making the menu disappear even after reading the documentation again. I want the menu I have to rotate into and X only if .menu-btn is clicked on.

Here is the javascript code I'm trying to convert:

 // Select DOM Items
const menuBtn = document.querySelector(".menu-btn");
const menu = document.querySelector(".menu");
const menuNav = document.querySelector(".menu-nav");
const menuBranding = document.querySelector(".menu-branding");
const navItems = document.querySelectorAll(".nav-item");

// Set Initial State Of Menu
let showMenu = false;

menuBtn.addEventListener("click", toggleMenu);

function toggleMenu() {
  if (!showMenu) {
    menuBtn.classList.add("close");
    menu.classList.add("show");
    menuNav.classList.add("show");
    menuBranding.classList.add("show");
    navItems.forEach((item) => item.classList.add("show"));

    // Set Menu State
    showMenu = true;
  } else {
    menuBtn.classList.remove("close");
    menu.classList.remove("show");
    menuNav.classList.remove("show");
    menuBranding.classList.remove("show");
    navItems.forEach((item) => item.classList.remove("show"));

    // Set Menu State
    showMenu = false;
  }
}

app.component.html

<header>
    <div class="container">

        <div class="menu-btn" [class.menu-btn.close]="check" (click)="myfunction()">
            <div class="btn-line"></div>
            <div class="btn-line"></div>
            <div class="btn-line"></div>
          </div>
          
          <!-- Overlay that comes up when you click menu -->
    
          <!-- Profile Image put in through CSS -->
          <nav class="menu" [class.menu-btn.show]="check" (click)="myfunction()">
            <div class="menu-branding" [class.menu-btn.show]="check" (click)="myfunction()">
                <div class="portrait"></div>
            </div>
           
            <!-- Pages -->
            <ul class="menu-nav" [class.menu-btn.show]="check" (click)="myfunction()">
                <li class="nav-item current" [class.menu-btn.show]="check" (click)="myfunction()">
                    <a href="index.html" class="nav-link">Home</a>
                </li>
                <li class="nav-item" [class.menu-btn.show]="check" (click)="myfunction()">
                    <a href="about.html" class="nav-link">About</a>
                </li>
                <li class="nav-item" [class.menu-btn.show]="check" (click)="myfunction()">
                    <a href="work.html" class="nav-link">Work</a>
                </li>
                <li class="nav-item" [class.menu-btn.show]="check" (click)="myfunction()">
                    <a href="contact.html" class="nav-link">Contact</a>
                </li>
            </ul>
          </nav>
    </div>
</header>

app.component.scss

     $primary-color: red;
$secondary-color: blue;

@mixin easeOut {
  transition: all 0.5s ease-out;
}

.container{
  background-color: grey;
  height:100px;
  box-sizing: border-box;
  
}

a{
  text-decoration: none;
  color:white;

}
.btn-line{
  color:blue;
}


header{
  position: fixed;
  z-index:2;
  width:100%;
}

.menu-btn{
  position: absolute;
  z-index:3;
  right:35px;
  top:35px;
  cursor: pointer;
  @include easeOut;

  .btn-line{
    width: 28px;
    height: 3px;
    margin: 0 0 5px 0;
    background: white;
    @include easeOut;
  
  }
  //Rotate Into X with Menu Lines
  &.close {
    transform: rotate(180deg);

    .btn-line {
      // Line 1 - Rotate
      &:nth-child(1) {
        transform: rotate(45deg) translate(5px, 5px);
      }

      // Line 2 - Hide
      &:nth-child(2) {
        opacity: 0;
      }

      // Line 3 - Rotate
      &:nth-child(3) {
        transform: rotate(-45deg) translate(7px, -6px);
      }
    }
  }
}

.btn-line{
  color:black;
}

app.component.ts

export class AppComponent {
  title = 'menu';

   check:boolean=true;
  
    myfunction(){
      this.check=true;
    }

}

Solution

  • I believe the simple answer is that you cannot add two classes at once with the [class.xxx.yyy] directive...

    If you want both classes applied you have to do it in two separate [class...] directives, or use an ngClass directive, e.g. [ngClass]="{ xxx: check, yyy: check }"

    EDIT (following comment) your template has stuff such as [class.menu-btn.show]="check" I must have guessed wrong when I assumed that you wanted to add both the show and the menu-btn class based on the value of the variable check - if that wasn't your intention, I'm sorry. But at any rate, the class you wish to add must be the sole name in that directive (after class.), so if you want to add the show class, do [class.show]="check". And you can use multiple such directives, each for a different class.