Lavanya
Lavanya

Reputation: 41

Angular 7 : close menu when click outside

I would like to know whenever click is triggered inside parent div #menu, irrelavant of html tags exists inside it.

nativeElement.parent didn't worked for me.

HTML code:

<button #toggleButton (click)="toggleMenu()"> Toggle Menu</button>

 <div class="menu" *ngIf="isMenuOpen" #menu>
    <div>
      I'm the menu. Click outside to close me
    </div>
    </div>

Angular script:

this.renderer.listen('window', 'click',(e:Event)=>{

        if(e.target !== this.toggleButton.nativeElement && e.target!==this.menu.nativeElement){
            this.isMenuOpen=false;
        }
    });

This is not working.

Upvotes: 4

Views: 14117

Answers (2)

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24424

you can reset menus state by listen to document click event in that case any click event in the menus need to run event stopPropagationmethod to prevent document click method , finally any click in the body of menus component gone to handle by you and any click event outside menus component resetToggle will run.

stopPropagation this prevent document click handler to run

  menuItemClickHandler(e , index ) {
   e.stopPropagation();
   // something magical  🧙‍♂️✨
    ...
  }

  @HostListener("document:click") resetToggle() {
    this.isMenuOpen=false;
  }

menus componenet

export class MenusComponent {

  menuslist = [1, 2, 3, 4, 5, 6, 7, 8];

  @HostBinding('class.active') isMenuOpen: boolean = false;

  constructor() { }

  menuItemClickHandler(e, index) {
    e.stopPropagation();
    // something magical  🧙‍♂️✨
    console.log(index);
    this.toggle(e); // toggle menus after you click 🎮
  }
  // component click
  @HostListener('click', ['$event']) click(e) {
    e.stopPropagation();

  }
  @HostListener("document:click") resetToggle() {
    this.isMenuOpen = false;
  }

  toggle(e) {
    e.stopPropagation();
    console.log('toggle')
    this.isMenuOpen = !this.isMenuOpen;
  }

}

menus component template

<ul ngClass="{slide : isMenuOpen}">
  <li *ngFor="let item of menuslist;let index=index" (click)="menuItemClickHandler($event,index)">
    {{item}}
  </li>
  </ul>

menus style will toggle menus to slide on or off base on menus is open value

:host {
  display: block;
  height: 50vh;
  width: 200px;
  background: #ccc;
  margin-left: -300px;
  transition: all 0.25s ease-in-out;
}
:host.active{
  margin-left: 0
}

stackblitz demo 🚀🚀

Upvotes: 2

Chellappan வ
Chellappan வ

Reputation: 27303

Add Host to component meta tag.

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  host: {
    "(window:click)": "onClick()"
  }
})

stopPropagation()

The stopPropagation() method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases.

toggleMenu($event) {    
    $event.stopPropagation();
    this.isMenuOpen = !this.isMenuOpen;
  }

  onClick() {
    this.isMenuOpen = false;
  }

Example:https://stackblitz.com/edit/angular-oenkbw

Upvotes: 14

Related Questions