Restricting the scope of ngClick in multiple instances with AngularJS

I'm working on developing a directive that can toggle an element open or closed when a specific link is clicked. The issue I'm facing is that, upon clicking one trigger, all instances are being toggled open instead of just the intended one.

If you'd like to take a look at my current code, it's available here: http://plnkr.co/edit/IA1hrbAoUEvvkwDjRAh6

Any suggestions on how I could rectify this situation without having to define templates within the directives themselves?

Answer №1

Check out this functional plunk that meets your requirements:

http://plnkr.co/edit/HcoyFyCSnrfmLu3lI7a6

The beauty of this setup is that each directive operates independently with its own scope object. You no longer even need a controller.

Also refer to:

Your updated directive definition:

app.directive('panelTrigger', function() {
    return {
      scope:{},
      link: function($scope, element, attrs) {

        $scope.toggle = function() {
           $scope.visibility = !$scope.visibility;
        };

        // Default visibility is false
        $scope.visibility = false;

        $scope.$watch(attrs.visible, function( newValue, oldValue ) {

          if ( newValue === oldValue ) {
              return;
          }

          var elm = angular.element(element.children()[1]);
          if (newValue) {
            elm.attr('style', 'display: block;');
          } else {
            elm.attr('style', 'display: none;');
          }
        });
      }
    };
})

Additionally, make a slight adjustment to your HTML code:

      <div data-panel-trigger data-visible="visibility">
        <a ng-click="toggle()" href="#">Panel A</a>
        <div class="panel span2">
          <p>Panel Content</p> 
        </div>
      </div>

Answer №2

The reason for this issue is that you are utilizing a single instance of PancelCtrl for all three panels. As a result, the directive is unable to determine which panel should be toggled since it is not specified anywhere.

You have two possible solutions:

Option 1: Create a separate instance for each li element:

<!-- (ensure to remove 'data-ng-controller="PanelCtrl"' from 'div.subfooter') -->
<li data-ng-controller="PanelCtrl">
  <a ng-click="toggle()" href="#">Panel A</a></a>
  <div data-panel-trigger data-visible="visibility" class="panel span2">
    <p>Panel Content</p>
  </div>
</li>
<li data-ng-controller="PanelCtrl">
  <a ng-click="toggle()" href="#">Panel B</a>
  <div data-panel-trigger data-visible="visibility" class="panel span2">
    <p>Panel Content</p>
  </div>
</li>
<li data-ng-controller="PanelCtrl">
  <a ng-click="toggle()" href="#">Panel C</a>
  <div data-panel-trigger data-visible="visibility" class="panel span2">
    <p>Panel Content</p>
  </div>
</li>

By doing this, you will have three separate instances of PanelCtrl, and each one will toggle the corresponding child element.

Alternatively, you can determine which panel is adjacent to the clicked link (using jQuery like $(this).siblings("div")). However, the first option is more preferable as it encapsulates the code behavior for each panel added to the site.

Best of luck!

Answer №3

The reason for this is that they are influencing the same scope. Include

scope:{
  ...
  ...
 }

In your directive declaration and apply bind attributes to your directive's scope as necessary.

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

Executing a function in Node-Express with a database connection at the beginning of the application

I am relatively new to Node.js and currently working on a Node.js - Express solution as a back-end for an AngularJS web application. My goal is to send an email when the MSSQL database query returns specific information. I have successfully implemented thi ...

Retrieve the checkbox value and assign it to an object in the $scope of an Angular

As a newcomer to angularjs, I've been struggling with this code snippet for the past two days. My goal is to retrieve values from selected checkboxes within my angular js controller. I have experimented with both ng-true-value and ng-false-value, bu ...

Exploring Non Blocking IO through an Example

While browsing through a node.js tutorial, I stumbled upon this informative page that uses the example of a "Restaurant service" to explain a scenario. In the context of Blocking IO, they provide the following code snippet: // requesting drinks for table ...

retrieving the value of an object key based on changing information

console.log(x, obj.fares) //return undefined output adultFare Object {adultFare: "9.00", childFare: null, seniorCitizenFare: null, disabledFare: null,} How do I retrieve the adultFare value from the object? Is looping through the keys necessary? I expec ...

Is there a way to store session variables in Angular without the need to make an API call?

I am currently working with a backend in PHP Laravel 5.4, and I am looking for a way to access my session variables in my Angular/Ionic project similar to how I do it in my Blade files using $_SESSION['variable_name']. So far, I have not discove ...

What is the best way to ensure that a link fragment scrolls to the top of the page in Angular?

Having trouble with link fragments in my Angular single-page-app: <a href="/#/search">Search</a> When clicking this link, it takes me to the right page but keeps my scroll position. I want it to scroll to the top of the page so I'm curre ...

Incorporating HTML into the Ajax Response

I recently encountered a strange issue with a service that returns an HTML page as the AJAX response. This page contains a form that is automatically triggered by scripts within the page, resulting in a POST request being sent when the page is rendered. My ...

What steps can I take to personalize Material UI within a React application?

As someone who is new to this UI framework and React, I have been tasked with developing an application that requires more design patterns. I specifically chose a framework that does not depend on jQuery code. However, I am facing challenges when it comes ...

Step-by-step guide for importing a JSON file in React typescript using Template literal

I am facing an error while using a Template literal in React TypeScript to import a JSON file. export interface IData { BASE_PRICE: number; TIER: string; LIST_PRICE_MIN: number; LIST_PRICE_MAX: number; DISCOUNT_PART_NUM: Discout; } type Discoun ...

Utilizing Google Sheets as a secure, read-only database for Angular applications without the need to make the sheet accessible to the

Seeking a way to utilize Google Sheets document as a read-only database for my Angular application, I have attempted various methods. However, the challenge with all these approaches is that they necessitate public sharing of the Sheet (accessible to anyon ...

Create a typescript class object

My journey with Typescript is just beginning as I delve into using it alongside Ionic. Coming from a background in Java, I'm finding the syntax and approach quite different and challenging. One area that's giving me trouble is creating new object ...

How to manage form submissions in Vue.js using inputs within child components

I'm working on a parent component that acts as a form. This form consists of multiple child components, each containing input fields. <template> <div class="form"> <generalData v-model="input" /> <textAreas v- ...

What is the best method to delete a value from localStorage using redux-persist?

In my index.js file, I have set up a persist configuration as shown below: import {configureStore, combineReducers} from "@reduxjs/toolkit" import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from 'redu ...

Can React JSX and non-JSX components be combined in a single project?

I'm currently faced with a question: If I have a parent component in JSX but need to include an HTML tag like <i class="fa fa-window-maximize" aria-hidden="true"></i>, which is not supported by React JSX (correct me if I'm wrong), can ...

Refreshing JqGrid tables after making changes and saving a row

In my PHP file, I have 4 jqGrid tables where I pass a different JSON array for each table. The data displayed on the grids come from one table with various SQL conditions. I am using inline editing for all the grids. After editing and saving a row in tabl ...

Having trouble changing the Font Awesome icon on click?

I'm struggling to figure out why I can't change a font awesome icon using a toggle. I've tried various solutions but nothing seems to be working. Any insights on what might be causing this issue? (HTML) <span class="toggle-icon" ...

Creating a React render method that relies on both asynchronous requests and state changes

Currently, I am immersing myself in the world of ReactJS and Redux. However, I have encountered a hurdle that seems insurmountable to me. In one of my projects, I have a React component that is responsible for fetching data asynchronously. export class M ...

AngularJS enhances user experience by allowing textareas to expand upon click

I am just starting to learn about angular.js and I'm wondering how to add a text area when clicking on an image. ....... ..... ..... </thead> <tbody> <tr ng-repeat="stu in Studentlist"> <td>{{stu.rollno}}</td> <td> ...

Retrieve information by utilizing query string parameters in Next.js

When using my getInitialProps function, I make two requests to fetch data. Now, I want to add a condition to make an additional request if the query params key is for a legal person. For example, if the URL is https://www.example.com.br/?legal-person, I n ...

What is the correct way to generate a normal map using THREE.js?

Experimenting with the Normal map Ninja demo, I attempted to apply it to a cube in my scene using the most recent version of Three.js from the development branch: // Setting up common material parameters var ambient = 0x050505, diffuse = 0x331100, specul ...