Bind Angularjs Variables into CSS Syntax

Bind AngularJS variables into CSS syntax

As explained here angular doesn't run on content inside style tags. There's a workaround plunkr in that post but as a more flexible approach I'd just create a directive that grabs the contents, parses them and replaces:

Updated answer

app.directive('parseStyle', function($interpolate) {
return function(scope, elem) {
var exp = $interpolate(elem.html()),
watchFunc = function () { return exp(scope); };

scope.$watch(watchFunc, function (html) {
elem.html(html);
});
};
});

Usage:

<style parse-style>.css_class {color: {{ angular_variable }};}</style>

http://jsfiddle.net/VUeGG/31/


Original answer

app.directive('parseStyle', function()
{
return function(scope, elem)
{
elem.html(scope.$eval('\'' + elem.html() + '\''));
};
});

then:

<style parse-style>.css_class {color: ' + angular_variable + ';}</style>

Not sure about the browser support for this though.

http://jsfiddle.net/VUeGG/4/

Angularjs Bind variables into external css file

I'm afraid at the moment that is not possible but last commit for angularjs added support for expresssions in style tags.

So you can do things like that:

In your controller:

$Scope.mystyles = {
.myclass: {
display: block
}
};

In your html:

<style>{{mystyles}}</style>

angularjs changelog

Take into account that it won't work in IE8 though, since it's been deprecated from 1.3.x.

Generate dynamic css based on variables angular

Direct approach available in angular is using ngstyle as follows

<div [ngStyle]="{'color': style.colorVal ? style.colorVal : '#000', 'font-size' : style.fontSize ? style.fontSize : '16px' }"></div>

After going through different methods and approached to add dynamic css to all pages on angular app I ended up with following solutions.

Requirement : generate dynamic css based on values returned from and API to change design and styling.

Solution :

  1. create a new component and create a service to load dynamic css variables from API.
  2. Add style tag in template file and use variable values for properties.
  3. Load this template on all pages or on main template.
  4. On app build style will be moved to head tag.

Code sample

import { CssService} from './Css.service';

@Component({
selector: 'DynamicCss',
templateUrl: './DynamicCss.component.html',
styleUrls: ['./DynamicCss.component.scss']
})
export class ServiceProviderComponent implements OnInit {
cssVariables: any;
constructor(private cssService:CssService){
/* call the service/api to get the css variable values in cssVariables */

}
}

Now apply css using jquery or javascript to append css with help of function like following

appendCss(customData)
{
let text = '.custom-form-1 {
background-image: url("`+customData.background_image+`");
}';
$(document).ready(function(){
$("style").append(text);
});
}

and call this function after loading custom data from service or other variable like I did it ngOnInit

ngOnInit(){
this.appendCss(this.customizeFormData);
}

Its using jquery but can be done with javascript/typescript as well if you dont want to use jquery in your angular app

Other useful resource https://github.com/angular/angular/issues/9343#issuecomment-312035896

Using angularjs template {{ }} inside css

You can just use the style attribute as following:

<div ng-app="test" ng-controller="testCtrl">
<div id="container" style="background: url({{backgroundUrl}})">
<div class="shape" ng-draggable='dragOptions' ></div>
</div>
</div>

and set the value in your controller as following:

angular.module('test').controller('testCtrl', function($scope) { 
$scope.backgroundUrl = 'http://i.stack.imgur.com/GgZvy.jpg';
})

Check the fiddle link here https://jsfiddle.net/rba7zqzn/5/

Dynamic Inline CSS using AngularJS

Check the following example:



var COLOR_CTRL = function($scope, $sce) {

$scope.changeColor = function(color) {

$scope.style = $sce.trustAsHtml('a, p {color: ' + color + '}');

};

$scope.changeColor('#000');

};

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

app.controller('ColorCtrl', ['$scope', '$sce', COLOR_CTRL]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>

<div ng-controller="ColorCtrl" ng-app="app">

<a href="#">anchor</a>

<p>paragraph</p>

<div>

<button ng-click="changeColor('#f00')">red</button>

<button ng-click="changeColor('#0f0')">green</button>

<button ng-click="changeColor('#00f')">blue</button>

</div>

<style data-ng-bind-html="style"></style>

</div>

Change css variables dynamically in angular

You can update them using

 document.documentElement.style.setProperty('--theme-color-1', '#fff');

If u want to update many values, then create a object

 this.styles = [
{ name: 'primary-dark-5', value: "#111" },
{ name: 'primary-dark-7_5', value: "#fff" },
];

this.styles.forEach(data => {
document.documentElement.style.setProperty(`--${data.name}`, data.value);
});

The main thing here is document.documentElement.style.setProperty. This line allows you to access the root element (HTML tag) and assigns/overrides the style values.

Note that the names of the variables should match at both places(css and js files)


if you don't want to use document API, then you can use inline styles on HTML tag directly

    const styleObject = {};

this.styles.forEach(data => {
styleObject[`--${data.name}`] = data.value;
});

Then In your template file using ngStyle (https://angular.io/api/common/NgStyle)

Set a collection of style values using an expression that returns
key-value pairs.

<some-element [ngStyle]="objExp">...</some-element>
<html [ngStyle]="styleObject" >...</html>  //not sure about quotes syntax

Above methods do the same thing, "Update root element values" but in a different way.

When you used :root, the styles automatically got attached to HTML tag

How do I conditionally apply CSS styles in AngularJS?

Angular provides a number of built-in directives for manipulating CSS styling conditionally/dynamically:

  • ng-class - use when the set of CSS styles is static/known ahead of time
  • ng-style - use when you can't define a CSS class because the style values may change dynamically. Think programmable control of the style values.
  • ng-show and ng-hide - use if you only need to show or hide something (modifies CSS)
  • ng-if - new in version 1.1.5, use instead of the more verbose ng-switch if you only need to check for a single condition (modifies DOM)
  • ng-switch - use instead of using several mutually exclusive ng-shows (modifies DOM)
  • ng-disabled and ng-readonly - use to restrict form element behavior
  • ng-animate - new in version 1.1.4, use to add CSS3 transitions/animations

The normal "Angular way" involves tying a model/scope property to a UI element that will accept user input/manipulation (i.e., use ng-model), and then associating that model property to one of the built-in directives mentioned above.

When the user changes the UI, Angular will automatically update the associated elements on the page.


Q1 sounds like a good case for ng-class -- the CSS styling can be captured in a class.

ng-class accepts an "expression" that must evaluate to one of the following:

  1. a string of space-delimited class names
  2. an array of class names
  3. a map/object of class names to boolean values

Assuming your items are displayed using ng-repeat over some array model, and that when the checkbox for an item is checked you want to apply the pending-delete class:

<div ng-repeat="item in items" ng-class="{'pending-delete': item.checked}">
... HTML to display the item ...
<input type="checkbox" ng-model="item.checked">
</div>

Above, we used ng-class expression type #3 - a map/object of class names to boolean values.


Q2 sounds like a good case for ng-style -- the CSS styling is dynamic, so we can't define a class for this.

ng-style accepts an "expression" that must evaluate to:

  1. an map/object of CSS style names to CSS values

For a contrived example, suppose the user can type in a color name into a texbox for the background color (a jQuery color picker would be much nicer):

<div class="main-body" ng-style="{color: myColor}">
...
<input type="text" ng-model="myColor" placeholder="enter a color name">


Fiddle for both of the above.

The fiddle also contains an example of ng-show and ng-hide. If a checkbox is checked, in addition to the background-color turning pink, some text is shown. If 'red' is entered in the textbox, a div becomes hidden.

AngularJS pass variable argument function calls in elements generated with ng-repeat

Edit:
Ok, not sure why you need this but I got it to work:
https://plnkr.co/edit/uR9s5vUJxQoviTiUD2vj?p=preview

And the same but using a Directive:
https://plnkr.co/edit/Onh2WonmarpUscnFFLGK?p=preview

End of Edit

You should pass a variable to "my-options" (let's call it 'dropDownOptions'):

<my-bootstrap-drop-down 
my-label="Some label"
my-options="dropDownOptions" >
</my-bootstrap-drop-down>

And the dropDownOptions array should contain the data you need in the directive, but only the data, not a function: [{"label": "Option 1", "params": {"p1": 1, "p2": 25}}, ...]

Now inside your directive, you have access to the data and can work on the action/function part. Example:

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

testApp.controller('mainCtrl', ['$scope',

function ($scope) {

$scope.test = "Hi";

$scope.dropDownOptions = [{"name": "yes", "value": 2}, {"name": "no", "value": 25}];

}]);

testApp.directive('myBootstrapDropDown', function () {

return {

restrict: 'E',

scope: {

myLabel: '@',

myOptions: '='

},

controller: function ($scope) {

$scope.myMethod = function (val) {

alert("There was a change, new value: " + val);

};

},

template: '<label>{{myLabel}}</label> <select name="myLabel" ng-model="myValue" ng-options="opt.value as opt.name for opt in myOptions" ng-change="myMethod(myValue)"><option value=""> </option></select>'

};

});
<!DOCTYPE html>

<html lang="en" ng-app="testApp">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<meta charset="utf-8">

<title>Sample</title>

<style>

.starter-template {

padding: 10px 15px;

text-align: center;

}

a {

font-size: 11px;

cursor: pointer;

}

</style>

</head>

<body>

<div ng-controller="mainCtrl">

<div class="container">

<div class="starter-template">

<h1>Example</h1>

<p class="lead">{{test}}</p>

<my-bootstrap-drop-down

my-label="Some label"

my-options="dropDownOptions" >

</my-bootstrap-drop-down>

</div>

</div>

</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<script src="app.js"></script>

</body>

</html>


Related Topics



Leave a reply



Submit