Angular ngStyle Variable Style - angularjs

I am trying to give my div dynamic style - I want the css to come from the controller , where the css object the controller returns isn't hard-coded but changes dynamically(I need a 'top' field which is a variable). I am using ng-style to try to achieve this :
-html-
<div id="preview" ng-style="setTopPosition()">
-controller-
$scope.setTopPosition = function() {
console.log("top position: " + $scope.topPosition);
var retObj = { top : $scope.topPosition , background: "green" };
console.log(retObj);
return retObj
};
Now I know that the values I'm expecting ($scope.topPosition etc) are there(they show in console log) , and I know the controller is running it's code since the div's background turns green . However , the top position part is not working . Can't ng-style use objects with variable fields ? Also , does this need to be in a custom directive instead ?

Remove braces from ng-style="setTopPosition() if you want to use it as variable.
It should be ng-style="setTopPosition
in controller, as example:
$scope.setTopPosition= {
top : $scope.topPosition+'px',
background : "green",
"width": 0 + '%',
"height": 5 + 'px'
};
on any change you just set new values to $scope.setTopPosition= {/* ... */}

In case anyone else comes across this question like I did, the problem for me came after upgrading from Angular 1.2.x to Angular 1.3.x.
After upgrading, it actually failed when I manually added 'px':
<span ng-style="{top: spanTop + 'px'}">I (don't) have top!</span>
and it started working when I removed the 'px':
<span ng-style="{top: spanTop}">I have top!</span>

Unless you are using jQuery with angular you must provide the px part of the value. jQlite doesn't support advanced CSS stuff like jQuery does so you should do this.
top : $scope.topPosition + 'px'
Note: The reason I say that is because the styles are applied normally in the ng-style directive like this: element.css(styles);

Related

How to use ng-src when there are more conditions to check?

I have 10 icons where each one for different types of alerts. I'm getting the type value from a service. I need to change the icon and style of text based on the type I'm getting from service. I'm using ng-src for changing the images.
<div ng-src="{{type=='0' : 'img1.png' : (type=='1' : 'img2.png' : ())}}"></div>
<div ng-class="{{class1: type=='1'}}">Some text</div>
Is there a better way to do this?
You can just set the icon img source in controller. Or even set the img source like:
$scope.iconSrc = "img" + type + ".png";
And use in template. Same login for class.

Kendo UI grid with angular - curly brackets not binding value in column template

I just started using kendo-ui grid and have created my columns and everything works with data coming back. I tried adding in a template value to my column definitions and the kendo docs say that I should be able to use {{dataItem.something}} to access the value in a template. This does NOT work. However doing <span ng-bind='dataItem.something'></span> works fine. Why is this, and how can I get the curly braces binding working? Thanks.
Here is a snippet of pseudo code for what I'm doing:
in my html and controller ( I am omitting all the other options like datasources etc..):
this.gridOptions = {
columns: [
{
field: 'valueOne',
template: "<span ng-bind='dataItem.valueOne'></span>" // THIS WORKS
},
{
field: 'valueTwo',
template: "{{dataItem.valueTwo}}" // THIS DOES NOT WORKS
}
]
};
<div ng-controller="gridController as vm">
<div kendo-grid k-options="vm.gridOptions"></div>
</div>
What I'm attempting is right from the kendo documentation and demos:
http://docs.telerik.com/kendo-ui/AngularJS/the-grid-widget#template‌​s
http://dojo.telerik.com/ikEKIr
TL;DR;
By removing kendo-angular.js the binding is working as expected.
kendo-angular.js library was still being included in our build and was conflicting with kendo.all.js
More:
The kendo-angular.js library was deprecated and support was moved to kendo professional. The angular functionality was moved into kendo.all.js. The docs are very specific about including libraries in a specific order. The include order must be JQuery, Angular, then Kendo. I checked this and made sure to try the latest versions of all scripts, also tried using the specific versions used in the demos. However after digging a bit further into our scripts it turns out that our build scripts were still including kendo-angular.js farther down the list. Removing this fixed my issue.
You cannot use angular templates after app was initialized, when you inserting new HTML angular will ignore it.
Kendo have own templating tags for it:
There are three ways to use the hash syntax:
Render values as HTML: #= #.
Use HTML encoding to display values: #: #.
Execute arbitrary JavaScript code: # if (true) { # ... non-script content here ... # } #.
Also you can use functions as templates:
template:
function (e) {
if (e.type !== 1)
return "";
return '<input type="checkbox"' + (e.canExecute ? 'checked="checked"' : '') + 'disabled="disabled" />';
}
You also can check out docs for more info

Using angular to change class settings

There is a lot of information on how to use ng-class and ng-style on elements. But I was wondering if there is a way to use angular to change the "settings" of a class.
So for example, say that you had a css class that looked as follows:
.testclass {
color: red;
background-color: blue;
}
I want to use angular to change the color:red to color:black, without attaching angular to the HTML DOM object, but via the class instead.
OK, this isn't a very useful example. What I was really planning to use it for was to hide part of ck-editor (class cle_top) and I want to set the whole class to hidden when someone clicks a button (and visible if the click it again).
======== To make it clearer, this is the bit of HTML I want to hide =======
<span id="cke_1_top" class="cke_top cke_reset_all" role="presentation" style="height: auto; -webkit-user-select: none;"><span id="cke_8" class="cke_voice_label">
Editor toolbars</span><span id="cke_1_toolbox" class="cke_toolbox" role="group" aria-labelledby="cke_8" onmousedown="return false;">
<span id="cke_11" class="cke_toolbar" aria-labelledby="cke_11_label" role="toolbar"><span id="cke_11_label" class="cke_voice_label">
But I need to do it without being able to add angular hooks in the HTML code (like adding ng-class to the span, which would have been a simple solution)
Attached is a JSfiddle that shows my problem, and as you can see, the toolbar button does nothing.
http://jsfiddle.net/vrghost/uqvo3ceh/
Which kind of works now, it adds the class invisible to the span, however, it does not hide the span that it is looking at.
Use the same process on a test text and it works...
Don't know of anything that will edit the class itself, but that probably isn't want you want to do. Other options are:
1) Create a second class, that comes after the first one in your CSS file that adds / changes the properties you want. Ex:
.testclass {
color: red;
background-color: blue;
}
.newclass {
color: green; // change property in first CSS class
display: none; // or hide
}
Then apply the second class conditionally:
<div class="text-class" ng-class="{newclass: hideScopeFlag}">blah</div>
2) Simply use ng-if, ng-hide, or ng-show if all you are doing is hiding something. Ex:
<div class="text-class" ng-hide="hideScopeFlag">blah</div>
or
<div class="text-class" ng-show="!hideScopeFlag">blah</div>
Why not simply toggle the class off/on for that element when the user clicks the button? (Edit: You said you want to "set the whole class to hidden" - I am assuming you mean to remove the class?)
To answer your question though, you can do this with JavaScript using document.styleSheets.
See this Stack Overflow question and the blog post it references. It mentions that there may be some browser compatibility issues. I have not investigated this.
EDIT: This implementation of 'ng-toggle' will allow you to hide or show an element with a single button.
The simplest solution without messing with the stylesheets is to add a new rule like
.visibleOff .testclass {
color: black;
}
and then you just need to toggle the "visibleOff" class on a parent element (the wrapper or the body element) of the editor.
To hide certain elements in the DOM you can also use a $scope variable that acts as a boolean. You can set it to false by default and on button click toggle it to true and back.
$scope.hidden = false;
$scope.toggleHide = function(){
$scope.hidden = !$scope.hidden;
}
In your dom you can then wrap your element with an ng-hide="hidden" attribute like so:
<div ng-hide="hidden">...</div>
<button ng-click="toggleHide()">togglehide</button>
A plunker example can be found here: http://plnkr.co/edit/?p=preview
If anyone wanted to know how to do this, potentially this could be useful for other things as well.
Created a function that uses document.querySelector to find the element, then just do a toggle to turn on or of, and that, as they say, is it folks.
$scope.toolBarVisible = function(){
console.log("Changing visibility");
var element = document.querySelector( '.cke_top' );
console.log("Just to do some debugging we check " + element);
var myEl = angular.element( element );
myEl.toggle();
element = document.querySelector( '.cke_bottom' );
myEl = angular.element( element );
myEl.toggle();
var myEl2 = angular.element( document.querySelector( '.test' ) );
myEl2.toggleClass("invisible")
}
And for those that are looking closely, yes, it hides the bottom as well, and all without changing ckeditor or the code.
Hope someone finds it helpful.

Bootstrap Progress bar not showing

Okay,
I'm using a small programming test to play around with Angular and Sinatra, and I'm done logic wise, but I wanted to add a small progress bar under the play field to show the moves made.
my haml template looks like this:
.progress.progress-striped.active
.progress-bar{role: "progressbar", :"aria-valuenow" => "{{moves}}", :"aria-valuemin" => 0, :"aria-valuemax" => 9}
%span.sr-only
{{moves}} moves out of 9
I've added the Bootstrap CSS from the CDN to my project, but the bar is not working as I want to.
I only see part of it:
Tried to play around with the classes, but it's not making any difference. I've checked whether I am using the correct classes, and this is also the case. I can also the see the aria- values being properly updated on every click, so the binding works as well.
source code: https://github.com/NekoNova/tictactoe
Can someone give me a pointer as to what I am missing?
Just an alternative usage if you want to use angular-ui bootstrap you can use this library for smooth and easy usage:
%script{ type: "text/javascript", src: "//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.1.min.js" }
Add the module "ui.bootstrap" to your application:
var TicTacToeApp = angular.module('TicTacToeApp', ['ui.bootstrap']);
Here is the haml expression:
%progressbar{ :max => "max", value: "dynamic"}
%span{ style: "color: white;white-space: nowrap;"}
{{dynamic}} / {{max}}
And for some demostration here is the variables which need to put in your controller:
$scope.max = 100;
$scope.dynamic = 70;

Set background image in css style angularjs

I want to set an image dynamically having the path of the image setted in a scope. The problem is that this is seen as a text, the value of selectedEvent.eventBannerImage is shown correctly, in my case the final url looks something like this:
background-image: url('/mydomain/images/banners\444b6e91-30fe-478b-a3d3-7984f0d35e69__1253402730_2873_full-269x300.jpg'), but it doesn't appear like a link as I need but just as a text. The image isn't shown.
<div style="background-image:
url('${pageContext.request.contextPath}/images/{{selectedEvent.eventBannerImage}}')">
please see here: http://jsbin.com/zehawu/1/edit
ng-style="{'background-image':
'url({{pageContext.request.contextPath}}/images/{{selectedEvent.eventBannerImage}})'}"
You will need to use a directive for the binding -- probably ng-style. Unfortunately, ng-style takes an expression, not a string, so you can't use concatenation inside of it.
<div ng-style="ctrl.bgImage">
// In the controller:
this.bgImage = {"background-image":
"url(" + this.pageContext.request.contextPath
+ "/images/" + this.selectedEvent.eventBannerImage + ")"
};

Resources