Modify components in a directive template depending on the information in the scope

In my project, I am facing an issue with a directive nested within an ng-repeat. The ng-repeat item is passed to the directive and I am trying to generate a directive template or templateUrl with dynamic elements based on a key/value in the item. Specifically, I want to make a button red if the item number is greater than 50, otherwise blue.

I suspect that I might not be using the right approach to solve this problem. My aim is to modify Bootstrap tags based on certain conditions. For example, I would like to apply the logic:

if item.number > 50: 
  class="btn btn-danger"
else:
  class="btn btn-success"

If possible, I prefer using templateUrl as I need the button to trigger a bootstrap modal which might be difficult to incorporate in the basic template option. Passing individual scope variables to the template seems like a cleaner solution.

You can check out this JSFiddle link for more context on the problem.

Here is the HTML snippet:

<div ng-controller="TableCtrl">
  <table>
    <thead>
      <tr>
        <th>#</th>
        <th>Button</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="item in buttons">
        <td>{{item.id}}</td>
        <td new-button item='item'></td>
      </tr>
    </tbody>
  </table>
</div>

And here is the corresponding JavaScript code:

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

function TableCtrl($scope) {
  $scope.buttons = {
    button1: {
      id: 1,
      number: '10',
    },
    button2: {
      id: 2,
      munber: '85',
    }
  };
};

myApp.directive('newButton', function() {
  return {
    restrict: 'A',
    replace: true,
    scope: {
      item: '=',
    },
    link: function(elem, attrs, scope) {
        // This is most likely not the right location for this
        /*if (item.number > 50) {
        button.color = red
      }, else {
        button.color = blue
      }; */
    },
    template: '<td><button type="button">{{button.color}}</button></td>'
  }
});

Answer №1

If you want to style a button based on a condition, consider using the ng-class directive like so:

<button ng-class="{
  'btn-danger': item.number > 50,
  'btn-success': item.number <= 50
}"></button>

For more information, check out the documentation at https://docs.angularjs.org/api/ng/directive/ngClass

Answer №2

If you find yourself in need of a personalized directive, one option is to implement it in the following manner:

link: function(scope,elem,attrs) {
        var item=scope.item;
        if (item.number > 50) {
        elem.addClass("btn-danger");
      } else {
        elem.addClass("btn-success");
      }
    }

However, I believe that the ngClass directive would be more suitable for your specific requirements, as demonstrated below:

<button type="button" item="item" class="btn" ng-class="item.number > 50?'btn-danger':'btn-success'"></button>

Answer №3

Upon reviewing your sample code, I have identified a few key points:

  1. There is a typo in the 'munber' property of button 2.
  2. The link function lacks dependency injection, so the argument order is significant. Scope should be prioritized first.
  3. Your commented-out section of code is almost functional, but you must reference the variables as scope properties - 'item' should be on scope, and the button object you create needs to be scoped to be addressed as 'button' in your view template.

This implementation works (although using ng-class instead of class with moustache syntax, as suggested by others, would be more optimal):

HTML

<div ng-controller="TableCtrl">
  <table>
    <thead>
      <tr>
        <th>#</th>
        <th>Button</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="item in buttons">
        <td>{{item.id}}</td>
        <td new-button item='item'></td>
      </tr>
    </tbody>
  </table>
</div>

JS

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

function TableCtrl($scope) {
  $scope.buttons = {
    button1: {
      id: 1,
      number: '10',
    },
    button2: {
      id: 2,
      number: '85',
    }
  };
};

myApp.directive('newButton', function() {
  return {
    restrict: 'A',
    replace: true,
    scope: {
      item: '=',
    },
    link: function(scope, elem, attrs) {
        scope.button = {};
        if (scope.item.number > 50) {
        scope.button.class = 'btn btn-danger';
      } else {
        scope.button.class = 'btn btn-success';
      };
    },
    template: '<td><button type="button" class="{{button.class}}">Press Me?</button></td>'
  }
});

CSS

.btn-danger {
  background-color: red;
}
.btn-success {
  background-color: green;
}

Modified JSFiddle

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 Typescript Select is displaying an incorrect value

Here's the code snippet I've been working with: <select #C (change)="changeSelect(zone.id, C.value)"> <option *ngFor="let town of townsLocal" [attr.value]="town.data" [attr.selected]="town.data === zone.town && 'selected& ...

What could be the issue with my JSON file?

I am currently utilizing the jQuery function $.getJson. It is successfully sending the desired data, and the PHP script generating the JSON is functioning properly. However, I am encountering an issue at this stage. Within my $.getJSON code, my intention ...

Utilizing HTML documents instead of images in Owl Carousel 2

I am currently utilizing owl carousel 2 to construct a basic sliding carousel. However, I am only using images at the moment and would like to incorporate HTML files instead. These HTML files contain multiple divs where images can be inserted, and instead ...

Quickly switch between pages as they load

In Chrome, I'm experiencing a white flash between page loads that is causing transitions to appear choppy. I've taken various steps to optimize the site, such as using image sprites, reducing image sizes, minifying CSS, ensuring correct CSS loadi ...

Choosing KineticJS path based on its identification number

I've been working on creating an interactive map using some prebuilt templates. Each country in the map highlights when the mouse hovers over it. My question is, how can I make another country, like Brazil, highlight when any country is hovered over? ...

Using Node.js with the express framework for requiring and posting data

main.js: var mainApp = express(); require('./new_file.js')(mainApp); new_file.js: mainApp.post('/example', function(req, res) { console.log(true); }); Error message: mainApp is not defined. Looking for a solution to access exp ...

Implement a click event to trigger a search functionality within Bootstrap

I have implemented the following code to add search options in the navigation bar. It is displaying correctly, but I am not getting the click action that I require. For example, I want to trigger an action from JavaScript when the user clicks on the enter ...

Tips for setting default values for named parameters in JavaScript

In my TypeScript method, I am using named parameters like this public foo({x, y, z , m , n} : {x:string, y: number, z: number, m?:string, n?:number}) { } The parameters m and n will be provided from another object like const defaults = { m : 'M&apo ...

Configuring JsFiddle with Vue and integrating vue-tables-2 - The variable "t" is not defined

Seeking assistance for implementing the vue-tables-2 package and encountering a persistent issue. Despite my efforts to set up a jsfiddle, I keep encountering an error stating "t is undefined" even with a simple implementation. Has anyone faced this specif ...

Having problems with route navigation in Angular/Rails when using multiple layouts

Currently, I am in the process of building an AngularJS application that connects to a RoR backend. However, I have encountered an issue when working with multiple layouts. The application is designed to display one layout for unauthenticated users and swi ...

Display a series of elements in rows using styled-components

Here is a simple array that I need help rendering into a grid structure. Currently, the array is displayed like this: HAMDDN I want each element to be on a new row like so: HA MD DN Any suggestions on how to achieve this? Below is the full code. I am ...

having trouble parsing JSON data

Recently, I decided to experiment with JSON and utilized json_encode to generate a JSON object structured as shown below: [{ "timestamp": "12\/16\/2013 0:00", "curr_property": "7211", "curr_property_cost": "123", "day_pro ...

What are the most optimal configurations for tsconfig.json in conjunction with node.js modules?

Presently, I have 2 files located in "./src": index.ts and setConfig.ts. Both of these files import 'fs' and 'path' as follows: const fs = require('fs'); const path = require('path'); ...and this is causing TypeScr ...

MUI version 5 - Checkboxes are receiving a variety of unique classes

After recently upgrading from Mui v4 to v5, I've noticed a strange behavior with checkboxes. Upon inspecting the DOM differences between the two versions, it appears that some additional classes are now being applied in v5 and the extra span with the ...

Having trouble with Silverlight running JavaScript?

When I try to call a JavaScript function from a SL component using the HtmlPage.Window.Invoke api, it works fine if the function is defined in the page (html). For example: HtmlPage.Window.Invoke("publishValue", topic, jsonObject); However, if I place th ...

Submitting a form within AJAX-powered tabs (using the Twitter Bootstrap framework)

I have encountered an issue while trying to submit a form that is located within tabs. The content of these tabs is generated through AJAX. My problem arises when I submit the form - the page refreshes and loads the "default" tab, causing the PHP function ...

Change the value of a single element in an array using a component in ReactJS

I'm attempting to pass an array value to a specific index in one component and then assign a desired value from the child component. I need it to work this way because I'm developing a survey app where the number of questions can vary. This is j ...

Every single data attribute is unique for each element

Hello! I'm currently working on creating a sorting system for pictures, documents, and videos. Each div contains data-extension attributes, so my plan is to filter out all attributes that are jpg, gif, or png and make them visible while hiding the oth ...

Is there a way to trigger a Modal to open upon clicking a custom-designed button in MaterialUI?

In my React and Material-UI project, I am attempting to trigger a Modal to open using a custom button. The button also performs other functions, which is why it's important for me to combine the "Modal Opening" action with these additional functionali ...

Store the running of a JavaScript file in memory

It seems highly unlikely that achieving the following is possible without expert confirmation: On page number 1, user and application data is requested as soon as the page loads. Page number 2 utilizes the same script, so requesting the same information w ...