Tips for accessing the index of an image while hovering with the mouse in an Angular application

I am working on integrating the following features into my project.

  1. I want to implement an image box with functionality similar to the one in this Demo Implementation link.
  2. In my code, I have already implemented the side box feature, but I would like to know how to retrieve the index of an image along with all its details when hovering over that image.
  3. I aim to display the image exactly like the example link above when hovered over.

I would appreciate any assistance. Here is a snippet of my code:

  @ViewChild('hello',{static:false}) FirstRef!:ElementRef;
  @ViewChild('next',{static:false}) Next!:ElementRef;
  @ViewChild('prev',{static:false}) Prev!:ElementRef;

  SideImagesIcons=['../../../../assets/Product/p1.webp','../../../../assets/Product/p2.webp','../../../../assets/Product/p3.webp',
 '../../../../assets/Product/p4.webp','../../../../assets/Product/p5.webp','../../../../assets/Product/p6.webp','../../../../assets/Product/p7.webp'
,'../../../../assets/Product/p8.webp']

SideImages=['../../../assets/Product/p1.webp','../../../assets/Product/p2.webp','../../../assets/Product/p3.webp','../../../assets/Product/p4.webp'
,'../../../assets/Product/p5.webp','../../../assets/Product/p6.webp','../../../assets/Product/p7.webp','../../../assets/Product/p8.webp','../../../assets/Product/p9.webp']


imageArrayToDisplay:string[]=[];
displaySize=5;
displayIndex=0;
startIndex=0;
selectedIndex=0;
prevIndex=this.displaySize;
ngOnInit(): void {
   this.imageArrayToDisplay=this.SideImagesIcons.slice(this.startIndex,this.currentIndex);
   console.log("current index = "+this.currentIndex+"\nDisplay Index "+this.displayIndex+"\nStart Index"+this.startIndex+"\nPrev Index"+this.prevIndex);
  }

  prevClick(){
    this.prevIndex=this.startIndex-1;
    if(this.displayIndex>this.displaySize && this.prevIndex>=0)
    {
      this.displayIndex--;
      this.imageArrayToDisplay=this.SideImagesIcons.slice(this.prevIndex,this.displayIndex)
     this.startIndex--;
     this.Next.nativeElement.style.display='block';
    }
   this.currentIndex=this.displayIndex;
   if(this.prevIndex<=0)
   {
    this.Prev.nativeElement.style.display='none';
   }
   console.log("current index = "+this.currentIndex+"\nDisplay Index "+this.displayIndex+"\nStart Index"+this.startIndex+"\nPrev Index"+this.prevIndex);
    
    
  }
  currentIndex=this.displaySize;
  nextClick(){
    this.displayIndex=this.currentIndex+1;
    this.startIndex+=1;
    //this loop will run till to show the images till it reaches the last image
    if(this.displayIndex>this.displaySize && this.displayIndex <=this.SideImagesIcons.length)
    {
      this.imageArrayToDisplay=this.SideImagesIcons.slice(this.startIndex,this.displayIndex)
      this.currentIndex++;
      this.Prev.nativeElement.style.display='block';
    }
    //this will handle if we reaches to last image
    else if(this.currentIndex<=this.SideImagesIcons.length)
    {
      this.currentIndex=this.SideImagesIcons.length;
      this.displayIndex=this.currentIndex;
      this.startIndex=(this.SideImagesIcons.length-this.displaySize);
      this.Next.nativeElement.style.display='none';
    }
    console.log("current index = "+this.currentIndex+"\nDisplay Index "+this.displayIndex+"\nStart Index"+this.startIndex);
  }
 
.flex-container {
    display: flex;
    /* align-items: center; */
    flex-direction: column;
}

.container {
    align-content: center;
}

.box {
    display: flex;
}

.side {
    width: 108px;
    height: 400px;
    border: 1px solid gray;
    overflow-y: hidden;
}

.side::-webkit-scrollbar {
    display: none;
}

.slide-box {
    position: relative;
    width: 100%;
    height: 500px;
    border: 1px solid red;
}

.slide-box ul {
    transition: -webkit-transform .4s ease-in-out;
    transition: transform .4s ease-in-out;
    transition: transform .4s ease-in-out, -webkit-transform .4s ease-in-out;
    transform: translateY(0px);
    list-style: none;
}

.slide-box ul li {
    width: 64px;
    height: 64px;
    border: 1px solid green;
}

.inside {
    padding: 5px;
    width: 100%;
    height: 100%;
    position: relative;
}

.inside-li {
    width: 100%;
    height: 100%;
}

.inside-li img {
    max-height: 100%;
    max-width: 100%;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translateX(-50%) translateY(-50%);
}

.btn-prev {
    position: absolute;
    top: 0%;
    left: 39%;
    width: 64%;
    display: none;
}

.btn-next {
    width: 64%;
    position: absolute;
    bottom: 32%;
    left: 37%;
}

.enlarge-box {
    width: 400px;
    height: 400px;
    border: 1px solid black;
}

.inside-img-box {
    padding: 5px;
}

.inside-img-box .inside-li img {
    max-height: 99%;
    max-width: 100%;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translateX(-50%) translateY(-50%);
}
<div class="flex-container">
    <div class="row">
        <div class="col-6">
            <div class="container">
                <div class="box">
                    <div class="side">
                        <div class="slide-box">
                            <ul>
                                <li *ngFor="let prod of imageArrayToDisplay; let i=index">
                                    <div class="inside">
                                        <div class="inside-li">
                                            <img [src]="prod" alt="" [ngClass]="{'active':selectedIndex ===i}"> {{i}}
                                        </div>
                                    </div>
                                </li>
                            </ul>
                            <button #prev class="btn-primary btn-prev" (click)="prevClick()">Prev</button>
                            <button #next class="btn-success btn-next" (click)="nextClick()">Next</button>
                        </div>
                    </div>
                    <div class="enlarge-box">
                        <div class="image-box">
                            <ul>
                                <li>
                                    <div class="inside-img-box">
                                        <div class="inside-li">
                                            <img src="../../../assets/Product/p1.webp" alt="">
                                        </div>
                                    </div>

                                </li>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="col-6">
            <p #hello>Hello world</p>
        </div>
    </div>

</div>

Answer №1

to easily accomplish this, make use of the (hover) event and store the current iteration image in a variable

for instance:

<li *ngFor="let prod of imageArrayToDisplay; let i=index">
    <div class="inside">
       <div class="inside-li">
           <img (hover)="imageHover(prod)" [src]="prod" alt="" [ngClass]="{'active':selectedIndex ===i}"> {{i}}
       </div>
    </div>                                    
</li>

then within the imageHover method, retain the prod argument by assigning it to a class variable (in this case, we'll name it currentImageUrl) and access it from the template where you wish to display the larger image

<div class="inside-img-box">
    <div class="inside-li">
           <img [src]="currentImageUrl" alt="">
    </div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Craft fresh items within HTTP request mapping

I am currently working on a function that subscribes to a search api. Within the map function, my goal is to transform items into objects. I haven't encountered any errors in my code, but the response always turns out empty. Here's the snippet o ...

Exploring the integration of a standalone component in Angular 17 using an http service

I'm facing an issue with a standalone component: @Component({ standalone: true, // <--- See here selector: "app-login", imports: [FormsModule, CommonModule], templateUrl: "./login.component.html", styleUrl: "./lo ...

Is it necessary to have a Test Adapter in VSTS in order to include a code coverage report?

Currently, I am producing code coverage using Karma-coverage and hosting my output coverage folder on an http-server for local viewing. My question is: How can I display this report on the VSTS code coverage tab? Do I need to re-format my coverage result ...

Is it necessary to manually unsubscribe from observables in the main Angular component?

I'm facing a dilemma with my Observable in the root Angular (6.x) component, AppComponent. Typically, I would unsubscribe from any open Subscription when calling destroy() using the lifecycle hook, ngOnDestroy. However, since the AppComponent serv ...

Issues with conditional types in TypeScript functionality not yielding desired results

Here is some TypeScript code that I am working with: type NumberOrNever<T> = T extends number ? T : never function f<T>(o: T) : NumberOrNever<T> { if (typeof o === "number") return o; throw "Not a number!" } ...

Dealing with the possibility of an empty array when accessing elements by index in Typescript

What is the best way to handle accessing elements by index in an array in Typescript when the array can be empty, resulting in potentially undefined elements? I am developing a simple game using React and Typescript where I have a variable named game whic ...

Troubleshooting: Angular 2 View not reflecting changes after array push

I have encountered an issue with my two child components. They are both meant to share data from a json file that I load using the http.get/subscribe method. Oddly enough, when I try to push new data into the array, it doesn't seem to update in the vi ...

Scrollbar malfunction in Angular and Bootstrap主 The main scrollbar in Angular and Bootstrap is un

I am currently facing an issue with my Angular app using Bootstrap 5. The main html/body scrollbar does not work when elements overflow the view. I have tried various solutions such as setting a fixed height, adjusting overflow-y to scroll or auto for body ...

Modify the JSON format for the API POST request

I need assistance with making an API POST call in Angular 8. The JSON object structure that needs to be sent should follow this format: -{}JSON -{}data -[]exp +{} 0 +{} 1 However, the data I am sending is currently in this format: - ...

Obtain the promise value before returning the observable

I'm facing an issue with the code below, as it's not working properly. I want to return an observable once the promise is resolved. Any thoughts or suggestions would be greatly appreciated. getParalelos() { let _observable; this.getTo ...

Lazy-loading modules in SSR Angular 8 applications are currently unspecified

I am currently in the process of setting up my Angular 8 application to work with server-side rendering (SSR). However, I am encountering some undefined errors in webpack when running my application using ng serve, especially with lazy-loaded modules. Ever ...

Using NestJS to import and inject a TypeORM repository for database operations

This is really puzzling me! I'm working on a nestjs project that uses typeorm, and the structure looks like this: + src + dal + entities login.entity.ts password.entity.ts + repositories ...

Navigating with Angular Router: Strategies for managing routing within a submodule's router

Seeking guidance on handling a scenario where there is a router-outlet in a high-level component and another router-outlet within its sub-component. To resolve this issue, it appears necessary to place the sub-component in its own module and set up a dedi ...

TypeScript's type assertions do not result in errors when provided with an incorrect value

We are currently using the msal library and are in the process of converting our javaScript code to TypeScript. In the screenshot below, TypeScript correctly identifies the expected type for cacheLocation, which can be either the string localStorage, the ...

Pausing repetitive HTTP requests in an Angular 6 project within a do while loop

While waiting for the completion of one API call, I am recursively consuming an external API. The http calls are being made using import {HttpClient} from '@angular/common/http' As a newcomer to the framework, there may be something wrong in the ...

Is it possible for a component to accept another component as an input in Angular 2?

Important Reminder! Prior to implementing the technique mentioned in the answer, please review this discussion, which highlights the error Expression has changed after it was checked. Previous value: 'CD_INIT_VALUE'.. I have also shared a workar ...

What are the ways to integrate JSON data into Angular?

I am facing some issues with integrating JSON in Angular. Within my project, I am generating components and deleting the spec.ts files. Subsequently, I create a new file called prod.data.json { "products" : [ { ...

When sending a JSON string in an HTTP request with Express, the req.body variable may be empty

I'm facing an issue where Express is receiving an empty JSON string {} and I've been struggling to identify the cause. I've attempted using both bodyParser and express.json for the JSON parser, but the result remains the same. I've also ...

"The limitation of character input in an Ionic Angular input field is not being

After installing the APK on my Android device, I noticed that the input field allows me to enter more than 5 characters even though I have set a maximum length in both the HTML and TypeScript files. This is how my HTML looks: <ion-row id="rowValid ...

BrowserSync initiates without any access URLs specified

Recently, I set up a scaffolding project using Yeoman (ng-fullstack) and opted for the client side options only. The installation went smoothly, but when I try to run "gulp", all tasks are executed without any errors and it launches http://localhost:3000. ...