class not getting applied in ng-repeat - angularjs

Folks,
I am looking through a array in angular. For each element in the array there is a width attribute which dictates what the width of this element should be on screen. However, this does not get renedred for some reason.
The array is as below:
$scope.header = [
{'column':'name', 'width':'300'},
{'column':'city', 'width':'300'},
{'column':'address', 'width':'300'},
{'column':'age', 'width':'300'}
];
The view is as below
<div ng-repeat="element in header" >
<span ng-bind="element.column" style="display:inline-block;width:{{element.width}}" >
</span>
</div>
Please advice

you should try ng-style
ng-style="{width: element.width + 'px'}"

C. S. is right about needing {{element.width}}px. Here's a fiddle to demonstrate. http://jsfiddle.net/nordyke/T7cW7/

All you need to do is add px after your {{expression}}, here is the working fiddle
<span ng-bind="element.column" style="display:inline-block;width:{{element.width}}px" >
or even this:
<span ng-bind="element.column" style="display:inline-block;width:{{element.width+'px'}}" >

Related

Changing Element Attributes Based on a Condition

Is there a way to determine which attribute to render on an element? For example, say I wanted to style a div to have a green background if my count variable is greater than 5, but give it a ui-view directive otherwise?
Let's take an unrealistic example written in pseudocode
<div ng-if="count > 5 ? {style='background: green'} : {ui-view='home'}">
</div>
Is this plausible? I may be approaching it the wrong way but I wanted to know if this could or should be done (I'm thinking custom directives could help but I wanted to keep this as lightweight as possible)
Any help or discussion is appreciated!
You can simply do:
<div ng-if="myCondition"></div>
<div ng-if="!myCondition" ui-view></div>
In order to avoid code duplication I suggest to use ng-include:
<ng-include src="template"></ng-include>
Yes it is, ng-class is made for that
<div ng-class="{{ 'green' : (count > 5) ; 'red' : (count != 5) }}">
</div>
// where green and red is class name not style
You can also use a variable for the class name
<div class="base-class" ng-class="myVar">Sample Text</div>
or ng-style
http://plnkr.co/edit/pCplLBymY1nmX7Bmb0uO?p=preview
<span ng-style=" count > 5 ? { 'background-color':'red' } : { 'background-color':'green' }" >Sample Text</span>

Angular if condition from value of ng-repeat

I'm rendering data in a table using Angular and ng-repeat. What I would like to do is add an if condition to say if the value contained in ng-repeat is a certain word, set the background colour of that row to red. I think it might look something like this, but I'm not sure how to do this in Angular.
if( {{field.value}} == THING){
var backgroundColour = red;
}
I was thinking of using ng-filter, although I dont wan't to actually filter the data, just set a variable based on a value.
Any ideas?
You could add an ng-class in the html to achieve this.
<div ng-repeat"field in fields" ng-class="{'with-background': field.value == THING}">
{{field.value}}
</div>
And then add with-background to css
.with-background {
background-color: red;
}
If THING is a variable pointing to some other value, you don't have to use quotes and if it's meant to be a string, use it as 'THING'
Here's the official documentation of ngClass: https://docs.angularjs.org/api/ng/directive/ngClass
You cann also use ng-style for this
<div ng-style="field.value == THING?{'background-color':'red'}:{}">
Hello Plunker!
</div>
plunker
You could do something like this below:
<div ng-repeat="field in collections"
ng-if="field.value && field.value =='THING'">
{{backgroundcolor}}
</div>
Or you could you use ng-class directive
<div id="wrap" ng-class="{true: 'yourClassName'}[field.value]">
You can use ng-class directive
<tr ng-class="{'color-red': item.value > 0}" ng-repeat="item in vm.items">
<td>{{ item.value }}>/td>
</tr>

angularjs how set right scope for function?

have this ng-repeat
<li class="tmmenu-admin-tabs-builder-panel-portlet" ng-repeat="question in questions">
<div>
<span class="tmmenu-admin-tabs-builder-panel-portlet-toggler" ng-click="tatbppTogler()">{{{tatbppt}}}</span>
<span class="tmmenu-admin-tabs-builder-panel-portlet-number">{{question.id}}</span>
{{question.text}}
</div>
<div class="tmmenu-admin-tabs-builder-panel-portlet-options" ng-show="showTatbppo">
...
</div>
</li>
I want, for click in "tmmenu-admin-tabs-builder-panel-portlet-toggler" change visibility "tmmenu-admin-tabs-builder-panel-portlet-options" and change text in "tmmenu-admin-tabs-builder-panel-portlet-toggler".
And i write this code for get result:
$scope.tatbppTogler = function(){
$scope.showTatbppo = !$scope.showTatbppo;
if($scope.showTatbppo){
$scope.tatbppt = "-";
}else{
$scope.tatbppt = "+";
}
}
It's works, but changed dom in all "Li", how changed only current (where user click) "li"?
You can do it like this:
<li class=portlet" ng-repeat="question in questions">
<div>
<span class="toggler" ng-click="showTatbppo=!showTatbppo">{{showTatbppo ? "+" : "-" }}</span>
<span class="number">{{question.id}}</span>
{{question.text}}
</div>
<div class="options" ng-show="showTatbppo">
...
</div>
</li>
Working fiddle, with this concept:
http://jsfiddle.net/x1nguaxj/
btw. You have very-very-very long css class names :)
1 way
you can pass this in ng-click="tatbppTogler(this)" and then in function manipulate with this
2 way
you can create custom directive and apply it to your li element and then on this directive bind click to element and listen , and on click function will be triggered your listener and you will have access on this element
You can create an attribute id for each question and then change based on the id of the question you clicked
I would suggest you'd take a look at $index. From the angularjs docs:
iterator offset of the repeated element (0..length-1)
Using this, you can clearly determine the certain div that was clicked on.

AngularJS - ng-bind-html-unsafe inside a directive not working

I am having the next problem. As you can see in my jsFiddle I am trying to use ng-bind-html-unsafe inside a template in my directive, and the attribute's value that I'm passing item{{itemColumn.field}} depends because is inside an ng-repeat. The thing is that I am using the ng-bind-html-unsafe in the columns that the attribute highlight is true, because the idea is to filter data (using the text input) and highlight the selection introduced by the user in the input. And as you can see, there is no value in those columns (because it seems that the binding is not working for some reason).
I have read about possible solutions and it one guy said that it can be fixed using $compile (which I'm actually using), so I have some time stuck in this with no idea on how to solve it.
Someone has faced something like this before? and can give me some ideas on how to solve the problem?
EDIT:
As Joachim suggests, I will provide more relevant code. In my template I have this
<td ng-repeat=\"itemColumn in gridOptions.gridColumnDefs \"
ng-show=\"itemColumn.visible | elementIsDefined : itemColumn.visible : true\" >
<div ng-switch on=\"itemColumn.highlight\"> " +
<span ng-switch-when=\"true\">
<div ng-bind-html-unsafe=\"item.{{itemColumn.field}} | highlight: {{gridOptions.searchInput}}\" ></div>
</span>
<span ng-switch-when=\"false\">{{item[itemColumn.field]}}</span>
</div>
</td>
I think my problem is related to the fact that I am trying to use a binding {{ }} inside the ng-bind-html-unsafe directive (Which i need). When the page renders, I got my div with the attributes as stated in the template, but the ng-bind-html-unsafe does not renders any HTML.
Just in case you need it, i found a way to make my issue disappear. In the link function inside my directive, I added the next functions:
scope.getValueToBind = function (item, subItem) {
return item[subItem];
};
scope.getFieldToFilter = function () {
var inputValue = scope.gridOptions.searchInput;
var returnValue = $("input[ng-model='" + inputValue + "']").val();
return returnValue;
};
And in my template I call this new functions instead of having a direct binding in the ng-bind-html-unsafe (which does not work at all with internal bindings). The functions return the values that I needed (as If i had a binding)
<td ng-repeat=\"itemColumn in gridOptions.gridColumnDefs \"
ng-show=\"itemColumn.visible | elementIsDefined : itemColumn.visible : true\" >
<div ng-switch on=\"itemColumn.highlight\">
<span ng-switch-when=\"true\"><div ng-bind-html-unsafe=\"getValueToBind(item,itemColumn.field) | highlight: getFieldToFilter()\" ></div>
</span>
<span ng-switch-when=\"false\">{{item[itemColumn.field]}}</span>
</div>
</td>
Here you can find the complete jsFiddle. If you type any letter/word that is inside the table, it will be highlighted.

Different class for the last element in ng-repeat

I am creating a list using ng-repeat something like this
<div ng-repeat="file in files">
{{file.name}}
</div>
But for the last element alone I would like to have a class (<div class="last">test</div>) included to it. how can i achieve this using ng-repeat?
You can use $last variable within ng-repeat directive. Take a look at doc.
You can do it like this:
<div ng-repeat="file in files" ng-class="computeCssClass($last)">
{{file.name}}
</div>
Where computeCssClass is function of controller which takes sole argument and returns 'last' or null.
Or
<div ng-repeat="file in files" ng-class="{'last':$last}">
{{file.name}}
</div>
It's easier and cleaner to do it with CSS.
HTML:
<div ng-repeat="file in files" class="file">
{{ file.name }}
</div>
CSS:
.file:last-of-type {
color: #800;
}
The :last-of-type selector is currently supported by 98% of browsers
To elaborate on Paul's answer, this is the controller logic that coincides with the template code.
// HTML
<div class="row" ng-repeat="thing in things">
<div class="well" ng-class="isLast($last)">
<p>Data-driven {{thing.name}}</p>
</div>
</div>
// CSS
.last { /* Desired Styles */}
// Controller
$scope.isLast = function(check) {
var cssClass = check ? 'last' : null;
return cssClass;
};
Its also worth noting that you really should avoid this solution if possible. By nature CSS can handle this, making a JS-based solution is unnecessary and non-performant. Unfortunately if you need to support IE8> this solution won't work for you (see MDN support docs).
CSS-Only Solution
// Using the above example syntax
.row:last-of-type { /* Desired Style */ }
<div ng-repeat="file in files" ng-class="!$last ? 'class-for-last' : 'other'">
{{file.name}}
</div>
That works for me! Good luck!
You could use limitTo filter with -1 for find the last element
Example :
<div ng-repeat="friend in friends | limitTo: -1">
{{friend.name}}
</div>
The answer given by Fabian Perez worked for me, with a little change
Edited html is here:
<div ng-repeat="file in files" ng-class="!$last ? 'other' : 'class-for-last'">
{{file.name}}
</div>

Resources