2

I have two component in my project. One is header.component and another is sidebar.component. In header.component, I have nav button to open sidebar. So, Basically when someone clicks on the button sidebar will be open. I declared is-open class to my CSS file to add it to the sidebar component's element. So I need to listen click event from header.component and toggle is-open class to sidebar.component

I added a simple js file to my angular project for that like this below:

window.onload = function () {
    let navBtn = document.getElementById('drawerbtn')

    navBtn.addEventListener('click', function () {
        let navDrawer = document.getElementById('navdrawer')
        navDrawer.classList.toggle('is-open')
        console.dir(navDrawer)
    })
}

I checked the console and it's working but in my element is-open class is not adding. How can I do that so easily?

6
  • 1
    Why are you not using [ng-class]? Commented Mar 29, 2020 at 7:49
  • Because there are two different components. Commented Mar 29, 2020 at 7:51
  • You should share your code for both components Commented Mar 29, 2020 at 7:52
  • 2
    There are many ways to share data across components - stackoverflow.com/questions/39325503/… It is generally considered bad practice to use jquery in angular unless absolutely necessary Commented Mar 29, 2020 at 7:53
  • Use event observables to communicate between multiple components Commented Mar 29, 2020 at 7:54

3 Answers 3

3

The best solution for that is to create a service which it will be tasked to manage the state of the sidebar or whatever you want. In this service you need to create one variable eg: isMenuOpen this variable could be a BehaviorSubject or Subject. Then in the component, you need to subscribe to changes in that variable or directly in your HTML using the async pipe. And lastly, when you need to show the menu, you can switch between 2 CSS classes or directly changing using the property "display" between none and block. Angular is platform agnostic, using window or document you are breaking this agnosticism.

Sign up to request clarification or add additional context in comments.

Comments

1

This will do the job for you:

In HTML:

<button [ngClass]="isOpen() ? 'is-open': ''" (click)="toggle()">Toggle</button>

In TS file:

isOpened: boolean=false;

isOpen(){
 return this.isOpened;
}

toggle(){
 this.isOpened=!this.isOpened;
}

This can be even simplified as below:

In HTML:

<button [ngClass]="isOpened ? 'is-open': '' (click)="isOpened=!isOpened">Toggle</button>

In TS:

isOpened: boolean=false;

The above code is applying to the same buttons. But what if we have to implement those in different components. Say 3 components - header, side-nave and main-content.Then we have to communicate between components using @Input and @Output to get the state. Below links might help:

https://stackblitz.com/edit/angular-sf-side-menu?file=src%2Fapp%2Fapp.component.ts

https://angular-sf-side-menu.stackblitz.io

Hope this helps.

3 Comments

This just an example that modify the class in the same button. You toggle class attribute for sideNav of header click as well. Just an example to show how the syntax is.
I'm using two different components. Your example just works for the same element.
Are you looking for something like this: angular-jsajy9.stackblitz.io ?
0
<button class="button" (click)="$event.target.closest('.parent').classList.toggle('open')"></button>

1 Comment

Thank you for your interest in contributing to the Stack Overflow community. This question already has existing answers. It would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient. Can you kindly edit your answer to offer an explanation?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.