How can buttons be replicated in an angular-friendly manner?

I need to implement a follow button functionality for a specific user that should toggle its text between "Follow" and "Followed" when clicked. The follow button may appear in various modules across the page, and when clicked, it should update in all instances. The challenge is that these buttons exist within different scopes. How can I ensure that all cloned buttons are in sync using Angular?

My current workaround involves using a universal jQuery selector to update all the buttons upon click.

Answer №1

It’s recommended to keep the state in a service for easier access.

For instance:

app.factory('SharedService', function() {
  this.dataState = null;

  this.setDataState = function(value) {
    this.dataState = value;
  }

  this.getDataState = function() {
    return this.dataState;
  }

  return this;
});

For more information, refer to the AngularJS Docs on services

Alternatively, you can watch this Egghead.io video

Answer №2

To achieve this functionality, you can utilize the $rootScope.$broadcast method. When any button is clicked, you can trigger an event using $rootScope.$broadcast and then monitor it using $scope.$on to toggle the button status. Additionally, you have the option to update the state within the service as well, allowing you to retrieve the current value later if necessary.

Check out the example below:

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

app.controller('ctrl1', function($scope) {
  $scope.label1 = "First Button";
});

app.controller('ctrl2', function($scope) {
  $scope.label2 = "Second Button";
});

app.controller('ctrl3', function($scope) {
  $scope.label3 = "Third Button";
});

// Updating state in the service as well.
app.service('fButtons', function($rootScope) {
  var buttonState = false;
  this.getCurrentState = function() {
    return buttonState;
  };

  this.updateCurrentState = function() {
    buttonState = !buttonState;
  };
});

app.directive('followButton', function($rootScope, $timeout, fButtons) {

  return {
    restrict: 'E',
    scope: {
      label: '='
    },
    template: '<button ng-click="buttonClick()" ng-class="{red: active}">{{label}}</button>',
    controller: function($scope) {
      $scope.$on('button.toggled', function() {
        $scope.active = !$scope.active;
      });

      $scope.buttonClick = function() {
        fButtons.updateCurrentState();
        $rootScope.$broadcast('button.toggled');
        console.log(fButtons.getCurrentState());
      }
    }
  };

});
.red {
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">

  <div ng-controller="ctrl1">
    <follow-button label="label1"></follow-button>
  </div>
  <hr/>
  <div ng-controller="ctrl2">
    <follow-button label="label2"></follow-button>
  </div>
  <hr/>
  <div ng-controller="ctrl3">
    <follow-button label="label3"></follow-button>
  </div>
</div>

Remember to check the console for service state updates.

$broadcast documentation

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

Issues with $.post function causing HTML to be displayed instead of the intended value

I have a question about sending the value of an HTML element to the server using POST. When I alert the result, I expect to only see the value but I am also getting the HTML content of the PHP file included in my code. Why is this happening? function post ...

What is the best way to implement a 'box-shadow-right' that stops at the border?

How can I achieve a seamless shadow effect at the border-right of a small div that matches the shadow of a larger div, without cutting off at the border-bottom of the small div or the border-top of the large div? I am unable to use Z-index due to the compl ...

What is the best way to achieve consistent width in a material-ui card component?

How can I ensure that all these cards have the same width? https://i.stack.imgur.com/Ns3zw.png I'm experiencing an issue with achieving uniform card widths when using flexbox in material-ui. How can I resolve this? Is it necessary to utilize Grid fo ...

Styling text and images with Bootstrap

Currently, I'm utilizing bootstrap to structure a row with 2 div elements. The first div contains an image while the second div holds text content. The challenge I am facing is aligning the text to the edge of the image. However, since the image does ...

Using the html5 file reader API in JavaScript to retrieve a file as a binary string and then sending it through an ajax request

I'm attempting to obtain the binary string of files, but I seem to be unable to do so. Why does readAsDataUrl work while readAsBinaryString doesn't? I have posted my code on jsbin and any help would be greatly appreciated. Thank you. Check out ...

Changing the Button Background in Richfaces

I am attempting to modify the background-image of a h:commandButton element located within a RichFaces:panel. To achieve this, I created a CSS file with the following styling rule: .sButton { background-image:url('../imgs/btnTexture2.jpg') ...

What is the best way to position three DIVs next to each other within another DIV while aligning the last DIV to the right?

I need help formatting a simple list item with three DIVs. The first DIV should be left justified, the second should be able to grow as needed, and the third should be right justified. I currently have them stacked side by side, but can't get the last ...

Vue Error: "the main template must have one and only one root element"

Exploring My Component Setup components exposed: <template> <!--<post-form/>--> <div class="wrapper"> <b-table :data="posts"> <template slot-scope="props"> <b-table-column fie ...

The implementation of an onclick event in a freshly created HTML element is functioning solely on the final element

One issue I encountered was that when I generated page number buttons at the bottom of a page, the onclick event only worked with the last button created. Below is an example of how the page buttons were displayed: https://i.stack.imgur.com/wHwI0.png ...

Displaying an image in AngularJS using Express: A step-by-step guide

Greetings! I am currently utilizing the angular-fullstack generator to build my web application. For uploading images, I opted for ng-file-upload. //server/picture.contoller.js exports.upload = function (req, res) { //Create Picture on db ...

What is causing the colorful background to not fully cover my page when I make the window smaller?

I'm currently designing a webpage that features a dynamic gradient background. Within this webpage are two columns - one displaying an image of a phone, and the other containing text. In full screen mode, everything looks perfect. The gradient stretch ...

stopPropagation() halts the propagation in the opposite direction

I encountered an issue while attempting to create a non-clickable div. While it does stop propagation, it doesn't prevent what should be stopped and allows things that shouldn't be clickable. js //screen has set stopPropagation $("#smokeScree ...

What is the best way to create a background image that remains hidden behind content as you scroll through a webpage?

I am looking to recreate the effect seen on the background image of this website , where the image gets covered by content as you scroll down. ...

Discover the magic of DevTools: Easily view real-time SCSS updates without the hassle of constantly saving your changes

The question at hand fails to provide a complete picture of the situation. While I am familiar with Workspaces and SASS source-maps, I can already track the line in the scss file where the specific rule is located that I wish to modify, thanks to the Style ...

Apache causes HTML download tag to malfunction

I have an HTML file that includes the following code: <a href="/Library/WebServer/Documents/file.zip" download="file.zip"> Download here </a> When I test this HTML page on Chrome, it successfully allows me to download the file. However, when ...

Retrieve files from a Webservice and transfer them to Azure Blob Storage using Node.js and Express framework

In order to provide users with their own separate workspace, I am working on retrieving files from a vendor's Web service and storing them in unique blob containers. This way, users can edit the files without interfering with each other's work. I ...

Utilize CSS to showcase the full-size version of a clicked thumbnail

I am working on a web page that features three thumbnails displayed on the side. When one of these thumbnails is clicked, the full-size image should appear in the center of the page with accompanying text below it. Additionally, I have already implemented ...

Modifying an Object within a for-in loop

Hi there, I'm facing a challenge with updating an object that has child properties in my Angular application. Here is the initial object: $scope.osbStep = { test0Nav : { current : false, comp ...

Steps for choosing the nth HTML row with jQuery

I'm facing a situation where I need to be able to select the nth row of an HTML table based solely on the id of the selected row. You can see exactly what I mean by checking out this JSFiddle Demo <table class="mytable1"> <tr><td i ...

Displaying JSON array data across three different pages using AngularJS and Ionic framework

I have an array of categories with multiple products. I want to display these categories on a category page. When a category is clicked, it should redirect to the product page and show the relevant products. Similarly, when a product is clicked, it shou ...