Angular overlaypanel it is staying everytime open

Viewed 946

I have created an Angular component like p-overlaypanel but it is staying open for every item I click, I want if I click another overlay panel the last clicked should be hidden, I wan'T only one to be clicked and show not everyone of them Below you can find code in stackblitz.

https://stackblitz.com/edit/angular-yrsyt6?file=src/app/app.component.ts

Here is the code

<div class="dropdown">

  <div  class="body">
    <ng-content select="[body]"></ng-content>
  </div>

  <div *ngIf="active" class="popup">
    <ng-content select="[popup]"></ng-content>
  </div>

</div>
.dropdown {
  position: relative;
  display: inline-block;
}

.popup {
  display: block;
  position: absolute;
  z-index: 1000;
}

export class OverlaypanelComponent implements OnInit {

  active = false;

  constructor() {

  }

  ngOnInit() {

  }
  @HostListener('document:click', ['$event']) clickedOutside($event) {
    this.active = false;
  }

  toggle($event) {
    $event.preventDefault();
    $event.stopPropagation();
    this.active = !this.active;
  }

  close() {
    this.active = false;
  }

}
1 Answers

In order to do this, you will have to have the child component (panel) somehow communicate to the parent that it has opened, and it will be the parent's responsibility to close the other panels. To that end, the active property should also be an Input binding. This means the addition of at least three things one way or the other: an Input binding to determine if the panel is active, an Input binding to identify the panel, and an Output binding to signal that the panel is being shown:

@Input() active = false;
@Output() activeChanged = new EventEmitter();
@Input() index;

toggle($event) {
  $event.preventDefault();
  $event.stopPropagation();
  this.active = !this.active;
  if (this.active) {
    this.activeChanged.emit(this.index);
  }
}

Now your parent component will have to bind to these properties and also respond to the Output to change the bindings of the other panels. This should be pretty easy to do with an array or some iterative data structure that you can use to contain the panels.

  panels = new Array(4).fill({ active: false });

  closeOtherPopups(index) {
    this.panels = this.panels.map((panel, idx) => (
      { active: idx === index }
    ));
  }

See this in action here: https://stackblitz.com/edit/angular-u96ssk?file=src/app/app.component.ts

Related