"Engage with an Angular directive using a button positioned in any location on the

There is a directive implemented on my webpage with an assigned id attribute, regardless of its functionality. Now, I need a second directive that essentially triggers the first one.

Here is an example of what I aim to achieve:

<body>
    <!-- various elements -->
    <my-directive id="test"></my-directive>
    <!-- various elements -->
    <controlling-directive directive-id="test"></controlling-directive>
</body>

The controllingDirective could be defined as follows:

.directive('controllingDirective', function() {
    link: function(scope, elem, attrs) {
        element.on('click', function(){
            // Call directive with attrs.directiveId
        });
    }
}

The question arises: How can this be achieved and what is the optimal approach?

I have considered two methods:

One involves using document.getElementById and angular.element(..).isolateScope() as shown below:

.directive('myDirective', function() {
    scope: {},
    link: function(scope, elem, attrs) {
        scope.actionToStart = function() {...};
    }
}

.directive('controllingDirective', function() {
    link: function(scope, elem, attrs) {
        element.on('click', function(){
            angular.element(document.getElementById(attrs.directiveId))
                    .isolateScope().actionToStart();
        });
    }
}

Alternatively, an event on $rootScope could be utilized:

.directive('myDirective', function($rootScope) {
    scope: {},
    link: function(scope, elem, attrs) {
        $rootScope.$on(attrs.id + 'Start', function(){...});
    }
}

.directive('controllingDirective', function($rootScope) {
    link: function(scope, elem, attrs) {
        element.on('click', function(){
            $rootScope.$emit(attrs.directiveId + 'Start');
        });
    }
}

Neither of these options feels ideal. Is there a simpler solution that I may be overlooking for achieving this task?

It's important to note that the 'require' option cannot be used since the directives are not interconnected in the DOM structure.

Answer №1

It seems like you can achieve the desired functionality without using angular.element or events. A simple watch and attributes can suffice.

var myApp = angular.module('myApp', [])

.directive('myDirective', function() {
  return {
    template: '{{cur}}',
    scope: {
      cur: '='
    },
    link: function(scope, elem, attrs) {
      if (!scope.cur) scope.cur = 1;
      scope.$watch(function() {
        return scope.cur;
      }, function(newVal, oldVal) {
        if (newVal !== oldVal) {
          if (oldVal == 4) scope.cur = 1;
        }
      });
    }
  };
}).directive('controllingDirective', function($rootScope) {
  return {
    scope: {
      directiveCur: '='
    },
    template: '<button type="button" ng-click="click()">Click me</button>',
    link: function(scope, elem, attrs) {
      scope.click = function() {
        scope.directiveCur += 1;
      }
    }
  };
});
div {
  margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<div ng-app="myApp">
  <div>
    <my-directive data-cur="test"></my-directive>
    <controlling-directive directive-cur="test"></controlling-directive>
  </div>
  <div>
    <my-directive data-cur="test2"></my-directive>
    <controlling-directive data-directive-cur="test2"></controlling-directive>
  </div>
</div>

UPDATE variant using $rootScope

var myApp = angular.module('myApp', []);
myApp.controller('Test', function($scope) {});

myApp.directive('myDirective', function($rootScope) {
  return {
    template: '{{test}}',
    scope: {
      cur: '@'
    },
    link: function(scope, elem, attrs) {

      if (!$rootScope[scope.cur]) scope.test = $rootScope[scope.cur] = 1;
      console.log($rootScope[scope.cur], scope.test);
      scope.$watch(function() {
        return $rootScope[scope.cur];
      }, function(newVal, oldVal) {
        if (newVal !== oldVal) {
          if (oldVal == 4) scope.test = $rootScope[scope.cur] = 1;
          else scope.test = $rootScope[scope.cur];
        }
      });
    }
  };
});


myApp.directive('controllingDirective', function($rootScope) {
  return {
    scope: {
      directiveCur: '@'
    },
    template: '<button type="button" ng-click="click()">Click me</button>',
    link: function(scope, elem, attrs) {
      scope.click = function() {
        $rootScope[scope.directiveCur] += 1;
      }
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<div ng-app="myApp">
  <my-directive data-cur="test"></my-directive>
  <controlling-directive directive-cur="test"></controlling-directive>
  <br/>
  <my-directive data-cur="test2"></my-directive>
  <span ng-controller="Test">
    <controlling-directive data-directive-cur="test2"></controlling-directive>
  </span>
  <div>test: {{test}}
    <br/>test2: {{test2}}</div>
</div>

UPDATE2 variant with factory

var myApp = angular.module('myApp', []);

myApp.factory('shared', function() {
  return {
    inc: function(cur) {
      if (this[cur] == 4) this[cur] = 1;
      else this[cur] += 1;
    }
  }
});
myApp.controller('Test', function($scope) {});

myApp.directive('myDirective', function(shared) {
  return {
    template: '{{shared[cur]}}',
    scope: {
      cur: '@'
    },
    link: function(scope, elem, attrs) {
      if (!shared[scope.cur]) shared[scope.cur] = 1;
      scope.shared = shared;
    }
  };
});


myApp.directive('controllingDirective', function(shared) {
  return {
    scope: {
      directiveCur: '@'
    },
    template: '<button type="button" ng-click="click()">Click me</button>',
    link: function(scope, elem, attrs) {
      scope.click = function() {
        shared.inc(scope.directiveCur);
      }
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<div ng-app="myApp">
  <my-directive data-cur="test"></my-directive>
  <controlling-directive directive-cur="test"></controlling-directive>
  <br/>
  <my-directive data-cur="test2"></my-directive>
  <span ng-controller="Test">
    <controlling-directive data-directive-cur="test2"></controlling-directive>
  </span>
</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

The onChange event of the dropdownlist in MVC is not functioning correctly and is not properly triggering the action

Hey everyone, I'm trying to achieve a functionality where changing the selection of a dropdown list will trigger an AJAX call to a specific action with some data being passed. Below is the code I have implemented for this purpose. Despite verifying th ...

Creating an AJAX function to display a popup window for users who are already registered - here's how!

I am currently working on a dropwizard-java project. Whenever users click the subscribe button, it displays a thank you message for subscribing and then checks if the user is already registered. I would like to have a pop-up window immediately show whethe ...

Changing colors using JavaScript: A step-by-step guide

Hey there! I'm looking to change the color code in this script from $("#Tcounter").css("color","black") which uses the color word "black", to "#317D29". Can someone help me figure out how to do this? <script type="text/javascript"> $(document). ...

Interactive Map Displayed within a Pop-up Window

Recently, I developed a custom Google map where points are plotted and an HTML popup window appears when the image is clicked. Now, my goal is to open a file with JavaScript functions inside a lightbox/fancybox when a user clicks on an image. Below is th ...

Creating a Star Rating System Using HTML and CSS

Looking for help with implementing a Star rating Feedback on articles in Visualforce page. Came across some code that seems to fit the bill but facing issues with getting it to work when placed in a file and executed, particularly in Firefox. Any assistanc ...

Transmit information using $broadcast when a button is clicked, and retrieve that information using $scope.$on

I am trying to create a function that will broadcast data from the server upon button click, and then navigate to a new route using $state.go('new-route'). In the controller of this new state, I want to retrieve the transmitted data. However, whe ...

Tips on maintaining the parent's scope in CoffeeScript while making an AJAX call

I need to iterate through an object in CoffeeScript and make an AJAX call for each item in the object using jQuery. However, I'm facing an issue with losing the reference to the initial context in the callback function of the AJAX call. The context al ...

Angular Transclude - ng-repeat fails to iterate over elements

Recently, I've been experimenting with Angular directives and encountered a peculiar issue... Check out the code snippet below: <!DOCTYPE html> <html> <head> <title>Directive test</title> <script type="text/ja ...

Learn the steps for filling the color area between two points in HighCharts

Is it possible to have a color fill between two points on an area chart when clicked? You can view the current chart here. $(function () { $('#container').highcharts({ chart: { type: & ...

Troubleshooting the Gutter Problem in jQuery Isotope and Masonry

Currently, I am utilizing the Isotope jQuery plugin. While it is a fantastic tool, I am encountering a minor issue with aligning items in masonry mode. The width of my container is 960px, and I aim to have 4 items perfectly aligned as if they were adhering ...

Saving the Chosen Option from Button Group into react-hook-form State

Struggling to save the chosen value from MUI Button Group into react-hook-form's state, but encountering challenges with the update not happening correctly. view codesandbox example Below is a simplified version of my code: import { ButtonGroup, But ...

Utilize Electron to extract and render content from a local file into HTML code

I am struggling to find a solution for automatically reading and parsing a local csv file in an electron application. When I use 'fs' to open the file, I can't figure out how to pass the contents into the HTML window. One option is to use a ...

Choosing the appropriate data type for form data on the server

Seeking assistance on uploading an audio file to my server using the following method: var fd = new FormData(); fd.append('fname', 'test.wav'); fd.append('data', soundBlob); $.ajax({ type: 'POST', url: &apos ...

Stellar.js is malfunctioning

I've been attempting to implement a parallax effect using Stellar.js with two image tag elements, but I'm encountering issues. Despite trying various configurations, including following the Stellar.js creator's tutorial scripts closely, noth ...

Troubleshooting async/await issues in certain IDEs

I've been experimenting with aysnc and await in my project. While it worked perfectly in FiddleJS, I encountered an error when trying to implement it in my IDE (PHPSTORM 2017): async function test(url){ ^^^^^^^^ SyntaxError: Unexpected token f ...

What is the best way to transfer functions connected to an Object over to Object.prototype?

Imagine having this: var exampleObject = {age: 25, name: 'John'}; If you do this: Object.keys(exampleObject); // it will return ['age', 'name'] Now, what if you want to add this functionality to the object prototype? You c ...

Cross-Origin Resource Sharing (CORS) verification for WebSocket connections

I am currently utilizing expressjs and have implemented cors validation to allow all origins. const options = { origin: ['*'], credentials: true, exposedHeaders: false, preflightContinue: false, optionsSuccessStatus: 204, methods: [&a ...

Struggling to make fadeIn() function properly in conjunction with addClass

I've been struggling with this issue for quite some time now and I just can't seem to make it work. The JavaScript I'm working on involves using addClass and removeClass to display and hide a submenu element. While the addclass and removeCla ...

Pull information from database based on selection made in combo box

I am attempting to populate a text box with values from a database based on the selection in a combo box. I have written the code below but it doesn't seem to be working correctly. The issue is that the value selected in the combo box is not being pas ...

Click the button to send the form without including any hidden HTML element array value

My main goal is to create a dynamic dropdown menu for users when they click a button. Each click triggers a new dropdown to appear. To achieve this, I have been cloning a hidden div each time the button is clicked. Here's an example of how I am accom ...