javaland235
javaland235

Reputation: 803

Hover a div with NgClass

I am trying to make a hover effect on a div with a Angular ngClass directive. In the template file I have a div element with class "list-item-container' which contains a div with class "list-item" that is iterated with a *ngFor directive. Inside the "list-item" div element I have three divs with class "list-item-column" which are placed horizontally like a table row with inline display. in the div with "list-item" class I have placed a mouseenter and mouseleave event listeners which calls hoverListItem() in my .ts file. the hoverListItem() function changes the value of listItemHovered variable to true or false. In the "list-item" class I have a ngClass directive which triggers a css class 'list-item-highlight' based on the value of listItemHovered boolean value which then changes to background to a different color.

The problem I'm facing is that upon hovering mouse pointer on the "list-item" div all my "list-item" divs are affected instead of the one I am hovering over. How to solve this problem?

.html file

<div class="list-item-container">
      <ng-container *ngFor="let opportunity of dealService.opportunities">
        <div [ngClass]="{'list-item-highlight': listItemHovered}" class="list-item" (mouseenter)="hoverListItem()"
             (mouseleave)="hoverListItem()"
             (click)="selectOpportunity(opportunity)">
          <div
            class="list-item-column">{{opportunity.account?.name === null ? "N/A" : opportunity.account.name}}</div>
          <div class="list-item-column">{{opportunity.requirementTitle}}</div>
          <div class="list-item-column">{{opportunity.salesValue | number: '1.0-2'}}</div>
        </div>
      </ng-container>
    </div>

.css file

.list-item-container{
  overflow: auto;
  width: 100%;
  max-height: 500px;
}
.list-item{
  font-size: 15px;
  border-radius: 10px ;
  margin-top: 5px;
  height: 50px;
  background: lightgray;
  color: black;
}

.list-item-highlight{
  background: #7e00cc;
  color: white;
}

.list-item-column{
  height: inherit;
  vertical-align: center;
  display: inline-block;
  width: 33.33%;
  padding-left: 40px;
}

.ts file

 hoverListItem() {
    this.listItemHovered = !this.listItemHovered;
  }

Upvotes: 4

Views: 13006

Answers (2)

nircraft
nircraft

Reputation: 8478

I would suggest use a directive to listen to the hover event on the target element and attach the class:

@Directive({
    selector: '[hoverDir]'
})


 export class HoverOverDirective { 
    @HostListener('mouseenter') onMouseEnter() {
       this.elementRef.nativeElement.class = 'list-item-highlight';
    }

     @HostListener('mouseleave') onMouseLeave() {
       this.elementRef.nativeElement.class = 'list-item-not-highlight';
     }
}

Or the easiest way is to make use of CSS pseudo property :hover and use it as below:

.list-item:hover {
  background: #7e00cc;
  color: white;
}  

Upvotes: 3

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

Right now you're creating and modifying listItemHovered flag inside component context, rather you should maintain a flag for each item level, which could help to easily identify wheather component has been highlighted or not.

[ngClass]="{'list-item-highlight': opportunity.listItemHovered}"
(mouseenter)="hoverListItem(opportunity)"
(mouseleave)="hoverListItem(opportunity)"

Component

hoverListItem(opportunity) {
   opportunity.listItemHovered = !opportunity.listItemHovered;
}

Though I'd recommend to use :hover pseudo class if requirement is just to highlight the element on hover. That can be easily doable by changing CSS rule. This way could save several change detection cycle to be ran.

.list-item:hover {
  background: #7e00cc;
  color: white;
}

Upvotes: 5

Related Questions