isolated scope custom directive for showcasing multiple image slideshows


The concern

I am looking to integrate this image carousel in multiple locations on the same page using the same directive. However, it appears that they are currently sharing the same scope.

For example:

When I click the arrow icons to navigate to the next image, all instances of the carousel trigger simultaneously. How can I prevent this from happening?

Thank you in advance.


JavaScript code snippet

productDetail.directive('imageSwitcher',
    ['$rootScope', '$resource', '$timeout', 'app_settings', 'mainConfig',
    function($rootScope, $resource, $timeout, app_settings, mainConfig) {

        var gridData = {
            imgCount : 0,
            currentImage : 0,
            nextImage : 1,
            prevImage : 1
        }

        var actions = {
        setCurrentImage : function(ind) {
            gridData.currentImage = ind > (gridData.imgCount - 1)
                ? 0
                : ind < 0
                    ? (gridData.imgCount - 1)
                    : ind;

            gridData.nextImage = (gridData.currentImage + 1) > (gridData.imgCount - 1)
                ? 0
                : (gridData.currentImage + 1) < 0
                    ? (gridData.imgCount - 1)
                    : (gridData.currentImage + 1);

            gridData.prevImage = (gridData.currentImage - 1) > (gridData.imgCount - 1)
                ? 0
                : (gridData.currentImage - 1) < 0
                    ? (gridData.imgCount - 1)
                    : (gridData.currentImage - 1);
        }
    }

    return {
        replace: true,
        templateUrl: '/image-switcher.html',
        scope : {
            pr : '=imageSwitcher'
        },
        link: function(scope, element, attrs) {
            scope.actions = actions;
            scope.gridData = gridData;
            scope.locale = locale;
            gridData.imgCount = scope.pr.prodData.productImageUrls.imgArray.length;

            var resetImageData = function() {
                gridData.imgCount = scope.pr.prodData.productImageUrls.imgArray.length;
                actions.setCurrentImage(gridData.currentImage);
            };

            $rootScope.$watch('hasBrokenImages', function(){
                for (var i = 0; i < $rootScope.brokenImages.length; i++) {
                    var ind = scope.pr.prodData.productImageUrls.imgArray.indexOf($rootScope.brokenImages[i], 0);
                    if (ind > -1) {
                        scope.pr.prodData.productImageUrls.imgArray.splice(ind, 1);
                    };
                };
                resetImageData();
            })

            scope.$watch('pr.prodData.currentColorCode', function(newVal, oldVal){
                scope.$evalAsync(function(e){
                    $timeout(function() {
                        resetImageData();
                    }, 100);
                });
            });

            scope.$watch('pr.productId', function(newVal, oldVal){
                scope.actions.setCurrentImage(0)
            });
        }
    }
}]
);

HTML markup snippet

<div image-switcher="pr">
    <div class="product-images expanded" >
    <span class="fullwidth"
        ng-click="actions.setCurrentImage((gridData.currentImage+1))">
        <img ng-src="{{ pr.prodData.productImageUrls.imgArray[gridData.currentImage]}}"
            />

    </span>
    <img ng-src="{{
            pr.prodData.productImageUrls.imgArray[gridData.nextImage]}}"
        ng-hide="true"/>
    <div class="hiddenImages" ng-hide="true">
        <img ng-src="{{
                pr.prodData.productImageUrls.imgArray[gridData.prevImage]}}"
             />
    </div>
</div>
<div style="text-align: center;" ng-show="pr.prodData.productImageUrls.imgArray.length > 1">
    <p class="img-counter">
        {{gridData.currentImage + 1}}/{{gridData.imgCount}}
    </p>
    <p>
        <a class="mini-image-switcher mis-prev icon-L_arrow"
            ng-click="actions.setCurrentImage((gridData.currentImage-1))"></a>
        <a class="mini-image-switcher mis-next icon-R_arrow"
            ng-click="actions.setCurrentImage((gridData.currentImage+1))"></a>
    </p>
</div>

Answer №1

To improve the broadcasting of your event, consider implementing it like this:

$rootScope.$broadcast('previous', "myFirstCarousel");

Subsequently, you can capture the event using the following code:

$scope.$on('previous', function(event, carouselName) {
  if(carouselName == $scope.currentCarouselName)
   // Perform desired action
});

Incorporate the following into the directive definition:

        pr : '=pr',
        currentCarouselName : '=carouselName'

Modify your HTML accordingly:

<image-switcher pr="pr1" carouselName="myFirstCarousel">

This approach allows the directive's scope to receive 'pr1' as a parameter for the first directive and subsequent directives should have unique parameters like 'pr2'. Additionally, each directive will have a distinct carousel name specified in the HTML declaration for easy identification. I hope this explanation is helpful.

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

XSRF Cookies are failing to attach to the request header when an https iframe is being loaded on an http site

Recently, I successfully implemented XSRF protection on a website using MVC and AngularJS. The secure site can be accessed in two ways: through a direct post or within an iframe. Below is the code snippet: .config(function ($httpProvider) { $h ...

Encountering issue with API request in NextJs: "Error message - 'banner.map is not a function'"

After following a tutorial that demonstrated how to request data from an API and display it, I encountered an issue when trying to view the page in my NextJs project. The error message "banner.map is not a function" appeared. Below is the code snippet wh ...

When a user clicks on an anchor tag, close the current window, open a new window, and pass the

I have a scenario where I have an anchor tag that triggers the opening of a window on click. In this newly opened window, there is a table with a column containing another anchor tag. Here is what I am trying to achieve: Code for the anchor tag: functio ...

Steps for making a Three.js 3D line collection with specified width and thickness

Is there a way to create a Three.js 3D line series with customizable width and thickness? Although the Three.js line object does have a linewidth attribute, it is not universally supported across all browsers and platforms in WebGL. Here is how you can s ...

Is there a way to continuously submit a form in React every 10 seconds, even if it includes events?

I have a form with input fields where I collect data upon form submission. However, I want the form to submit automatically every 10 seconds without the need to click a button or press enter. I tried using useEffect to create an interval, but it resulted i ...

What is the best way to send a POST request with an array containing multiple objects within it?

Unique Context Currently, I am expanding my knowledge of JavaScript by working on a REST API project using node.JS and express. I have encountered a challenge while attempting to parse an array of objects that contains nested arrays of objects. Below is a ...

The axios POST request successfully returns a status code of 200, but unfortunately, the database

https://i.sstatic.net/FYO7k.png I have encountered an issue with my code where I am able to receive a response with status 200, however, the database is not updating. The backend has indicated that it received null data. axios.post('api/nos ...

Revamp the angular design of the mat-tree UI bottom border line issue

Can you help me with changing the direction of the mat tree from right to left? I need to remove the bottom border, please refer to the image https://i.sstatic.net/ecRIO.png here ...

"Encountering an error retrieving weather forecast API in JavaScript - issue with

I've been attempting to fetch the weather forecast API JSON in a similar manner to how I accessed the current weather API, but unfortunately, it doesn't seem to be working no matter what approach I take. let inOneDay = { fetchWeather: functio ...

Trouble with variable in require path causing issues with r.js

As a newcomer to optimizing with r.js, I am also a big fan of requirejs build-config.js ({ appDir: "./src/main/webapp/webresources/javascript/", baseUrl: "./", dir: "./target/webresources/js", optimizeCss ...

JavaScript Lint Warning: Avoid declaring functions inside a loop - unfortunately, there is no way to bypass this issue

In my React JS code snippet, I am attempting to search for a value within an object called 'categories' and then add the corresponding key-value pair into a new map named sortedCategories. var categoriesToSort = []; //categoriesToSort contains ...

Is there a way to implement a directive wrapper for ng-grid that allows the grid options to be specified using a directive attribute?

My goal is to create a reusable directive wrapper for ng-grid, where I can dynamically apply the ng-grid options through the use of an attribute. Below is the basic structure of the code that almost achieves what I am looking for: angular.module('my ...

The Bootstrap 4 card component is a versatile and stylish

Currently working on a display layout using Bootstrap 4, specifically utilizing cards. The issue I'm facing is that the text exceeds the limit of the card, causing it to overflow. Is there a solution to make the text automatically wrap to the bottom ...

sending a updated variable to ajax after it has been modified within a function

Apologies if my question is not clear as I am new to this. I have a scenario with 3 drop-down select boxes. The first box allows the selection of width, the second for length, and the third for height. Each of these has pre-defined values. When a value is ...

Limitations on Embedding Videos with YouTube Data API

I have been using the Youtube Data API to search for videos, but I am encountering an issue with restricted content appearing in the results. Specifically, music videos from Vevo are showing up even though I only want videos that can be embedded or placed ...

What could be causing my fetch post request to only hit on breakpoint and not otherwise?

In my React .Net application, I am using the following code snippet: handleAdd(userId, name) { name = encodeURIComponent(name); fetch('api/deck/create/' + userId + '/' + name, { method: 'POST' }).then(); } This ...

Leveraging the openPlunkr functionality

The Developer Guide for Angular.js showcases a convenient feature where users can click on a button labeled "Edit in Plunker" to instantly upload all files to Plunker and create a new private Plunk with these files. I am currently using an HTML-5 present ...

Blocked: Stripe Connect Embedded Onboarding Popup

I have been diligently following the steps in the tutorial to set up Onboarding with Stripe Connect, which can be found at the following link: After completing all the necessary setup, I encountered an issue where the iFrame containing the "Add Informatio ...

Converting a string of hexadecimal color into hexadecimal format using JavaScript

I wrote a function that converts a musical note into a hexadecimal color value. const colorFromNote = note => `0x${note}${note}${note}` For example, when 'C4' is passed in, the function returns 0xc4c4c4. Unfortunately, this approach doesn&apo ...

Uncovering the faces that grace the screen: A guide on finding them

When a user is navigating through a scene in my application, I want to be able to identify the visible faces on the screen (excluding those that are not in the camera's field of view or hidden by other objects). One approach I considered was using th ...