0

I have an Object like this

var obj = [
            {
              'id':1,
              'color':'#ff0000',
              'name':'final'
            },
            {
              'id':2,
              'color':'#ffff99',
              'name':'start'
            }
          ];

By using this I am rendering radio button group:

<div class="btn-group" ng-repeat="item in obj">
 <button type="radio" class="btn-group btn-xs btn-group-xs">{{item.name}}</button>
</div>

Here My Question are:

1.How can I apply background-color property on ng-click to button what is present in obj.

2. change the color of button text to contrast/opposite color. (That means if button background color is Black want to change text color to white) .

Here I have tried with ng-class And ng-style but Some where I did wrong.I don't know where it is.

Can any one help me. Thanks

domokun
  • 3,013
  • 3
  • 29
  • 55
chandu
  • 2,276
  • 3
  • 20
  • 35
  • I just answered a question very much like yours. Take a look: http://stackoverflow.com/questions/24403038/angularjs-cant-add-class-to-id – Jonathan Wilson Jun 25 '14 at 08:09
  • @Jonathan Willson. Great Answer but In your class you are using only one color. but in my case I don't know the color. the value of color comes from server. I have already tried with single color – chandu Jun 25 '14 at 08:13
  • Ok, gotcha. Working on an answer – Jonathan Wilson Jun 25 '14 at 08:17

4 Answers4

0

You could try something like this: add a style property to the elements inside the array:

function MyCtrl($scope) {
  $scope.obj = [
      {
          'id':1,
          'color':'#ff0000',
          'name':'final',
          'style' : {
              'background-color' : ''
          }
      },
      {
          'id':2,
          'color':'#ffff99',
          'name':'start',
          'style' : {
              'background-color' : ''
          }
      }
  ];
}

then, in your view, you can do:

<div ng-app="">
    <div ng-controller="MyCtrl">
        <div class="btn-group" ng-repeat="item in obj">
            <button data-ng-click="item.style = {'background' : item.color}" data-ng-style="item.style" type="radio" class="btn-group btn-xs btn-group-xs">{{item.name}
            </button>
        </div>
    </div>
</div> 

This is a JSFiddle I created. I hope it helps.

EDIT: in Javascript you can add properties to an abject at runtime with a simple loop like this:

for(var i=0; i<$scope.obj.length; i++){
    $scope.obj[i].style = {
        'background-color' : ''
    }
}

You don't have to modify the way you retrieve data from the server (or the format of the data retrieved). Doing this loop you modify only the javascript object you work with. It is a common practice.

superpuccio
  • 11,674
  • 8
  • 65
  • 93
0

Take this function that inverts hex colors

(source: Automatically change text color to assure readability)

and attach it to your $scope so that it's available in the view:

$scope.invertColor = function (hexTripletColor) {
    var color = hexTripletColor;
    color = color.substring(1);           // remove #
    color = parseInt(color, 16);          // convert to integer
    color = 0xFFFFFF ^ color;             // invert three bytes
    color = color.toString(16);           // convert to hex
    color = ("000000" + color).slice(-6); // pad with leading zeros
    color = "#" + color;                  // prepend #
    return color;
}

Then you use ng-style to set the background and color of each item:

ng-style="{background:item.color, 'color':invertColor(item.color)}"

See the working example here: http://jsfiddle.net/wilsonjonash/eAFVk/2/

Community
  • 1
  • 1
Jonathan Wilson
  • 4,138
  • 1
  • 24
  • 36
0

I'm use a bit of Jonathan solution to make everything works please see here: jsfiddle

<div ng-app="app">
    <div ng-controller="myCtrl">
        <div class="btn-group" ng-repeat="item in obj">
            <button type="radio" class="btn-group btn-xs btn-group-xs" ng-style="getMyStyle(item)" ng-click="UpdateColor(item)">{{item.name}} {{item.color}}</button>
        </div>
    </div>
</div>

and JS:

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

app.controller('myCtrl', function ($scope) {


    $scope.invertColor = function (hexTripletColor) {
        var color = hexTripletColor;
        color = color.substring(1); // remove #
        color = parseInt(color, 16); // convert to integer
        color = 0xFFFFFF ^ color; // invert three bytes
        color = color.toString(16); // convert to hex
        color = ("000000" + color).slice(-6); // pad with leading zeros
        color = "#" + color; // prepend #
        return color;
    }

    $scope.obj = [{
        'id': 1,
            'color': '#ff0000',
            'name': 'final'
    }, {
        'id': 2,
            'color': '#ffff99',
            'name': 'start'
    }];

    $scope.UpdateColor = function (item) {

        item.color = $scope.invertColor(item.color);

    };

    $scope.getMyStyle = function (item) {
        var myStyle = {
            'background-color': item.color,
            color: $scope.invertColor(item.color)
        }
        return myStyle;
    }


});
sylwester
  • 16,498
  • 1
  • 25
  • 33
0

In terms of displaying opposite colours, from my experience the best readability you can achieve with white/black text over any background colour. I've put some time to study this and that's what I came up with

$scope.RGB = function(colour) {
    if (colour.charAt(0) == "#") {
      colour = colour.substr(1, 6)
    }
    colour = colour.replace(/ /g, "");
    colour = colour.toLowerCase();
    var colour_defs = [{
      re: /^(\w{2})(\w{2})(\w{2})$/,
      process: function(bits) {
        return [parseInt(bits[1], 16), parseInt(bits[2], 16), parseInt(bits[3], 16)]
      }
    }, {
      re: /^(\w{1})(\w{1})(\w{1})$/,
      process: function(bits) {
        return [parseInt(bits[1] + bits[1], 16), parseInt(bits[2] + bits[2], 16), parseInt(bits[3] + bits[3], 16)]
      }
    }];
    for (var i = 0; i < colour_defs.length; i++) {
      var re = colour_defs[i].re;
      var processor = colour_defs[i].process;
      var bits = re.exec(colour);
      if (bits) {
        var channels = processor(bits);
        this.r = channels[0];
        this.g = channels[1];
        this.b = channels[2]
      }
    }
    this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);
    this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);
    this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b)
  }

then

myCol = $scope.RGB('#backgroundColour');
brightness = Math.sqrt(myCol.r * myCol.r * 0.299 + myCol.g * myCol.g * 0.587 + myCol.b * myCol.b * 0.114);
$scope.fontcolour = brightness < 130 ? "#FFFFFF" : "#000000";

any attempts of reversing colours are IMHO bad and often unreadable

here is a demo of inverse which I extended by my blackand white

http://jsfiddle.net/maurycyg/f9Re3/83/

maurycy
  • 8,455
  • 1
  • 27
  • 44