How to change the content of a html element on hover in Angular


Codever Logo

(P) Codever is an open source bookmarks and snippets manager for developers & co. See our How To guides to help you get started. Public bookmarks repo on Github - Star


Use case

I find my self often use the autocomplete function of my last searches in the search box to find and access bookmarks and snippets I recently looked for. I figured out since I do that, why not make it easier. So I did - I added sort of quick access to my last searches directly from the side menu in the landing page. See it in action below:

Quick access to My Last Searches animation
Quick access to My Last Searches animation

One tricky part was to show the whole content of the search when its length passes a certain limit. That meant when hovering dynamically changing the content of the html anchor a element. This was even more difficult, because the list is dynamically generated out of the last searches. Let’s see how I implemented that.

Implementation

First I initialise the elements of the booleans list hoveringLastSearches to false. We also need a method - hovering(), which returns the boolean value of an element from the list given its index:

export class AppComponent implements OnInit {

 //... other code parts removed for brevity

  private hoveringLastSearches: boolean[] = [];

  ngOnInit(): void {
    this.keycloakService.isLoggedIn().then(isLoggedIn => {
        //... other code parts removed for brevity
        this.latestSearches$ = this.userDataStore.getUserData$().pipe(
          map(userData => {
            for (let i = 0; i < 10; i++) {
              this.hoveringLastSearches.push(false);
            }
            return userData.searches.slice(0, 10);
          })
        )
      }
    });
  }

 //... other code parts removed for brevity

  hovering(i: number): boolean {
    return this.hoveringLastSearches[i];
  }

}

In the html template, when hovering over the element (mouseover event) or when exiting the element (mouseout) I set the corresponding boolean value to true, respectively to false of the corresponding element in the list. Then when displaying the content, depending on the result of the hovering(index) result I use the longer, respectively the short version of the text:

    <ng-container *ngFor="let mySearch of latestSearches; let i = index" class="mt-1">
        <span class="mt-1 mr-2">
            <a
              (mouseover)="hoveringLastSearches[i]=true"
              (mouseout)="hoveringLastSearches[i]=false"
              [routerLink]="['/search']"
              [queryParams]="{q: mySearch.text, sd: mySearch.searchDomain }"
              class="badge badge-secondary mb-1  ml-2"
              [class.my-snippets-last-search]="mySearch.searchDomain === 'my-snippets'"
              [class.public-snippets-last-search]="mySearch.searchDomain === 'public-snippets'"
              [class.my-bookmarks-last-search]="mySearch.searchDomain === 'my-bookmarks'"
              [class.public-bookmarks-last-search]="mySearch.searchDomain === 'public-bookmarks'"
              title="Search in "
            >  <i class="fa fa-xs fa-search mr-1"></i>
              <span
                *ngIf="!hovering(i); else longVersion"></span>
              <ng-template #longVersion></ng-template>
              <i *ngIf="mySearch.searchDomain === 'my-snippets' || mySearch.searchDomain === 'public-snippets'"
                 class="fa fa-xs fa-code ml-1"></i>
              <i *ngIf="mySearch.searchDomain === 'my-bookmarks' || mySearch.searchDomain === 'public-bookmarks'"
                 class="fa fa-xs fa-bookmark ml-1"></i>
            </a>
        </span>
    </ng-container>
Subscribe to our newsletter for more code resources and news

Adrian Matei

Adrian Matei
Life force expressing itself as a coding capable human being